使用exec-maven-plugin运行守护进程,避免出现"IllegalThreadStateException"异常。

41

我想运行一个守护线程,并在maven包装阶段启动。以下是我的pom.xml配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>java</goal>
                    </goals>
                </execution>                                
            </executions>
            <configuration>
                 <mainClass>com.test.Startup</mainClass>
                 <cleanupDaemonThreads>true</cleanupDaemonThreads>
            </configuration>
       </plugin>
  </plugins>
</build>

以下是Startup类的内容:

public class Startup {

    public static class Testing extends Thread {
        @Override
        public void run() {
            while(true) {
                System.out.println("testing..");
            }
        }
    }

    public static void main(String[] list) throws Exception {
        Testing t = new Testing();
        t.setDaemon(true);
        t.start();
    }
}

当线程正在运行时,编译停止了。经过一段时间(可能是超时或其他原因),线程停止,编译继续进行。有没有任何方法可以让这个线程在后台启动并使编译自动继续呢?

Maven 的一些输出:

[WARNING] thread Thread[Thread-1,5,com.test.Startup] was interrupted but is still alive after waiting at least 15000msecs
[WARNING] thread Thread[Thread-1,5,com.test.Startup] will linger despite being asked to die via interruption
[WARNING] NOTE: 1 thread(s) did not finish despite being asked to  via interruption. This is not a problem with exec:java, it is a problem with the running code. Although not serious, it should be remedied.
[WARNING] Couldn't destroy threadgroup org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup[name=com.test.Startup,maxpri=10]
java.lang.IllegalThreadStateException
    at java.lang.ThreadGroup.destroy(ThreadGroup.java:754)
    at org.codehaus.mojo.exec.ExecJavaMojo.execute(ExecJavaMojo.java:334)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)

我计划创建一个套接字监听器到这个线程,并让它在后台持续运行,直到Maven关闭JVM,但目前似乎套接字只会在编译期间保持一段时间。

11
乍一看,似乎“cleanupDaemonThreads”选项是导致这种行为的原因。你尝试将其设置为false了吗?(原文已翻译,不含解释或其他内容) - Andrew Logvinov
哦,看起来很顺利。现在只需要进行实际的实现... :) 谢谢! - drodil
1
我曾经遇到过与ExecJavaMojo类似的问题,通过目标在Team City中执行。 "exec:java -Dexec.mainClass="com.test.Startup" 因为POM文件中没有覆盖,所以默认插件被调用。你的建议解决了这个问题 "exec:java -Dexec.mainClass="com.test.Startup" -Dexec.cleanupDaemonThreads=false"。 - Yoztastic
2个回答

74

发布在问题评论区讨论过的解决方案。

这个解决方案对我起作用了!感谢Andrew Logvinov

cleanupDaemonThreads = false

在配置标签中加入类似以下代码:

<configuration> <mainClass>com.test.Startup</mainClass> <cleanupDaemonThreads>false</cleanupDaemonThreads> </configuration>


23
我曾经遇到过与“exec:java -Dexec.mainClass="com.test.Startup" -Dexec.cleanupDaemonThreads=false”类似的问题。 - Yoztastic
谢谢您先生!我已经为此苦苦挣扎了一段时间。 - Krik

4

您也可以使用命令行参数传递 cleanupDaemonThreads:

#!/bin/bash

PARAMS="$*"

export MAVEN_OPTS=-Dfile.encoding=utf-8

mvn exec:java \ 
     -Dexec.cleanupDaemonThreads=false \ 
     -Dexec.mainClass="org.mu.App" -Dexec.args="$PARAMS"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接