优雅地停止maven-antrun-plugin启动的java进程

时间:2016-02-17 10:03:58

标签: java maven kill-process maven-antrun-plugin

这个问题是昨天回答这个问题的结果

run a java application and a web application in a single maven build within a reactor project

正如上面的问题所解释的那样,我现在有了一个maven-antrun-plugin,它使用这样的配置分叉子进程并运行我的java appserver -

<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
  <phase> verify </phase>
  <configuration>
    <target>
      <property name="runtime_classpath" refid="maven.runtime.classpath" />
      <exec executable="java" spawn="true">
        <arg value="-classpath"/>
        <arg value="${runtime_classpath}"/>
        <arg value="somepackage.AppServer"/>
      </exec>  
    </target>
  </configuration>
  <goals>
    <goal>run</goal>
  </goals>
</execution>
</executions>
</plugin>

以上配置可以顺利启动我的appserver作为后台进程。

现在我的问题是,如果有一个简单的方法我可以找到这个过程并在我通过构建开始之后需要时停止它。

2 个答案:

答案 0 :(得分:3)

您可以使用JDK中捆绑的jps实用程序来获取正在运行的Java可执行文件的进程ID:

  

jps工具列出了目标系统上的已检测HotSpot Java虚拟机(JVM)。该工具仅限于报告具有访问权限的JVM的信息。

然后,当我们检索到进程ID时,我们可以在Windows或kill或Unix系统上使用taskkill将其终止。

这是maven-antrun-plugin的示例配置。它声明了jps可执行文件,并使用<redirector>属性在属性process.pid中重定向其调用结果。结果使用<outputfilterchain>进行过滤,以便仅保留与可执行文件AppServer对应的行。 jps输出的格式为[PID] [NAME],因此名称随<replacestring>移除;这样,我们只保留PID。最后,根据操作系统,有两个exec配置。

<configuration>
    <target>
        <property name="runtime_classpath" refid="maven.runtime.classpath" />
        <exec executable="java" spawn="true">
            <arg value="-classpath" />
            <arg value="${runtime_classpath}" />
            <arg value="somepackage.AppServer" />
        </exec>
        <exec executable="${JAVA_HOME}/bin/jps">
            <arg value="-l" />
            <redirector outputproperty="process.pid">
                <outputfilterchain>
                    <linecontains>
                        <contains value="somepackage.AppServer" />
                    </linecontains>
                    <replacestring from=" somepackage.AppServer" />
                </outputfilterchain>
            </redirector>
        </exec>
        <exec executable="taskkill" osfamily="winnt">
            <arg value="/PID" />
            <arg value="${process.pid}" />
        </exec>
        <exec executable="kill" osfamily="unix">
            <arg value="-15" />
            <arg value="${process.pid}" />
        </exec>
    </target>
</configuration>

由于您提到“优雅”,我在Unix上使用了-15选项,并且没有包含Windows的/F选项。如果要强制退出,可以在Unix系统上使用kill -9并在Windows上添加/F选项。

答案 1 :(得分:1)

尝试了各种选项之后,我发现process-exec-maven-plugin是最好的。我意识到OP专门询问maven-antrun-plugin,但这是因为收到了一般性问题的答案。

https://github.com/bazaarvoice/maven-process-plugin

使用它来启动nodeJs服务器的示例,该服务器用作集成测试的一部分:

<plugin>
    <groupId>com.bazaarvoice.maven.plugins</groupId>
    <artifactId>process-exec-maven-plugin</artifactId>
    <version>${process-exec-maven-plugin.version}</version>
    <executions>
        <!-- Start process -->
        <execution>
            <id>node-server</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>start</goal>
            </goals>
            <configuration>
                <name>node-server</name>
                <workingDir>../../test-server-dir</workingDir>
                <waitForInterrupt>false</waitForInterrupt>
                <healthcheckUrl>http://localhost:3000/</healthcheckUrl>
                <arguments>
                    <argument>node</argument>
                    <argument>./app.js</argument>
                </arguments>
            </configuration>
        </execution>
        <!--Stop all processes in reverse order-->
        <execution>
            <id>stop-all</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>stop-all</goal>
            </goals>
        </execution>
    </executions>
</plugin>