优雅地停止由 maven-antrun-plugin 启动的 java 进程
Gracefully stopping a java process started by maven-antrun-plugin
这个问题是昨天对这个问题的回答的结果
因此,正如上述问题所回答的那样,我现在有一个 maven-antrun-plugin,它分叉一个子进程并使用这样的配置运行我的 java 应用服务器 -
<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>
以上配置顺利启动了我的应用服务器作为后台进程。
现在我的问题是,是否有一种简单的方法可以找到此进程,并在我通过构建启动它后根据需要停止它。
您可以使用捆绑在 JDK 中的 jps
实用程序来获取 运行 Java 可执行文件的进程 ID:
The jps
tool lists the instrumented HotSpot Java Virtual Machines (JVMs) on the target system. The tool is limited to reporting information on JVMs for which it has the access permissions.
然后,当我们检索到进程 ID 后,我们可以在 Windows 或 kill
或 Unix 系统上使用 taskkill
杀死它。
这将是 maven-antrun-plugin
的示例配置。它声明 jps
可执行文件并将其调用结果重定向到 属性 process.pid
和 <redirector>
attribute. The result is filtered with <outputfilterchain>
so that only the lines corresponding to the executable AppServer
are kept. jps
output is in the form [PID] [NAME]
so the name is then removed with <replacestring>
;这样,我们只保留 PID。最后根据OS.
有两个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>
既然你提到了 "gracefully",我在 Unix 上使用了 -15
选项并且没有包括 Windows 的 /F
选项。如果想强制退出,可以在Unix系统上使用kill -9
,在Windows上加上/F
选项。
尝试过各种选择后,我发现 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>
这个问题是昨天对这个问题的回答的结果
因此,正如上述问题所回答的那样,我现在有一个 maven-antrun-plugin,它分叉一个子进程并使用这样的配置运行我的 java 应用服务器 -
<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>
以上配置顺利启动了我的应用服务器作为后台进程。
现在我的问题是,是否有一种简单的方法可以找到此进程,并在我通过构建启动它后根据需要停止它。
您可以使用捆绑在 JDK 中的 jps
实用程序来获取 运行 Java 可执行文件的进程 ID:
The
jps
tool lists the instrumented HotSpot Java Virtual Machines (JVMs) on the target system. The tool is limited to reporting information on JVMs for which it has the access permissions.
然后,当我们检索到进程 ID 后,我们可以在 Windows 或 kill
或 Unix 系统上使用 taskkill
杀死它。
这将是 maven-antrun-plugin
的示例配置。它声明 jps
可执行文件并将其调用结果重定向到 属性 process.pid
和 <redirector>
attribute. The result is filtered with <outputfilterchain>
so that only the lines corresponding to the executable AppServer
are kept. jps
output is in the form [PID] [NAME]
so the name is then removed with <replacestring>
;这样,我们只保留 PID。最后根据OS.
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>
既然你提到了 "gracefully",我在 Unix 上使用了 -15
选项并且没有包括 Windows 的 /F
选项。如果想强制退出,可以在Unix系统上使用kill -9
,在Windows上加上/F
选项。
尝试过各种选择后,我发现 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>