使用 exec-maven-plugin 运行守护程序,避免 `IllegalThreadStateException`
Posted
技术标签:
【中文标题】使用 exec-maven-plugin 运行守护程序,避免 `IllegalThreadStateException`【英文标题】:Running daemon with exec-maven-plugin avoiding `IllegalThreadStateException` 【发布时间】:2012-11-08 10:05:55 【问题描述】:我想运行一个应该在 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,但目前看来套接字只会在编译期间打开一段时间。
【问题讨论】:
嗯,乍一看,cleanupDaemonThreads
选项似乎是造成这种行为的原因。您是否尝试将其设置为 false?
哦,看起来效果很好。现在只是做实际的实现.... :) 谢谢!
我在使用 ExecJavaMojo 时遇到了类似的问题,通过目标在团队城市中执行。 "exec:java -Dexec.mainClass="com.test.Startup" 默认插件被调用,因为 pom 文件中没有覆盖。你的建议成功了 "exec:java -Dexec.mainClass="com.test。启动"-Dexec.cleanupDaemonThreads=false"
【参考方案1】:
发布问题的 cmets 部分中讨论的答案。 这个解决方案对我有用!谢谢Andrew Logvinov
cleanupDaemonThreads = false
配置标签里有这样的东西
<configuration>
<mainClass>com.test.Startup</mainClass>
<cleanupDaemonThreads>false</cleanupDaemonThreads>
</configuration>
【讨论】:
我遇到了与 exec:java -Dexec.mainClass="com.test.Startup" -Dexec.cleanupDaemonThreads=false 类似的问题 谢谢您,先生!已经为此苦苦挣扎了一段时间。【参考方案2】:您也可以使用命令行参数传递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"
【讨论】:
以上是关于使用 exec-maven-plugin 运行守护程序,避免 `IllegalThreadStateException`的主要内容,如果未能解决你的问题,请参考以下文章
exec-maven-plugin 说不能运行指定的程序,即使它在 PATH 上
在多模块 Maven 项目中运行 exec-maven-plugin 时出现问题
在 Linux 上运行时 exec-maven-plugin 未找到类异常
exec-maven-plugin 生成的进程会阻塞 maven 进程
Maven 不会运行我的项目:无法执行目标 org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
在 Maven 中从测试范围运行 main:“目标 org.codehaus.mojo:exec-maven-plugin:1.6.0:java 的参数 'mainClass' 丢失或无效”