使用 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' 丢失或无效”