You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maven exec:exec启动的JVM进程在Maven终止后未停止的问题排查

问题与解决方案

问题描述

在Azure DevOps(ADOS)流水线中使用Maven的exec插件构建并执行一个高内存消耗的Java程序,采用exec:exec方式启动独立JVM并设置-Xmx12g参数,运行正常,pom.xml配置如下:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>          
            <goals>
                <goal>exec</goal>
            </goals>
        </execution>
    </executions>        
    <configuration>
        <executable>java</executable>
        <arguments>
            <argument>-Xmx12g</argument>
            <argument>-classpath</argument>                        
            <classpath/>
            <argument>my.class</argument>
            <argument>some CLI argument</argument>                   
        </arguments>
    </configuration>               
</plugin>

遇到的具体问题:

  • 通过PowerShell脚本启动Maven构建运行正常,但在Shell中用Ctrl+C终止Maven后,exec:exec启动的用户程序JVM并未停止,成为独立进程;
  • 但在ADOS流水线中执行时,终止操作能正常停止用户程序;
  • 尝试调整exec插件的异步选项无效,希望找到无需PID脚本的最优解决方案,同时理解背后的机制。

核心解答

1. 为何用户程序不会随Maven终止而停止?

exec:exec的本质是启动一个完全独立的子进程,而非Maven进程的子线程。在Windows PowerShell环境下:

  • 当按下Ctrl+C时,中断信号只会传递给前台的Maven进程;
  • 独立启动的Java进程不属于Maven的进程组(或会话组),因此不会收到中断信号,会继续在后台运行。
    而exec:java目标是在Maven的JVM中运行程序,终止Maven时会直接停止程序,但它无法设置独立的JVM参数(比如单独的-Xmx),这也是选择exec:exec的核心原因。

2. ADOS采用了什么机制实现终止?

ADOS流水线在终止任务时,并非只终止顶层的Maven进程:

  • ADOS会将整个任务的进程组作为目标,发送终止信号(Windows下为TerminateProcessTree,类Unix环境下为SIGTERM/SIGKILL);
  • 所有由Maven启动的子进程(包括exec:exec启动的Java进程)都会被纳入同一个进程组,因此在流水线终止时会被一并停止,不会出现遗留进程。

3. 无需PID脚本的最优方案

可以通过以下两种方式解决本地PowerShell中的问题:

方式一:使用PowerShell进程组管理

在启动Maven时,将其纳入新进程组,确保Ctrl+C能终止整个进程组:

Start-Process mvn -ArgumentList "exec:exec" -NoNewWindow -PassThru | Wait-Process

Wait-Process会让PowerShell等待Maven进程结束,同时按下Ctrl+C时,信号会传递给整个进程组,连带终止Java子进程。

方式二:修改exec插件配置,启用killAfterExit

在exec插件的configuration中添加killAfterExit参数,让Maven在退出时主动终止子进程:

<configuration>
    <executable>java</executable>
    <arguments>
        <argument>-Xmx12g</argument>
        <argument>-classpath</argument>                        
        <classpath/>
        <argument>my.class</argument>
        <argument>some CLI argument</argument>                   
    </arguments>
    <!-- 添加该配置,Maven退出时主动杀死子进程 -->
    <killAfterExit>true</killAfterExit>
</configuration>

该参数会让Maven在自身退出时(无论正常退出还是被中断),主动杀死由exec:exec启动的子进程。此参数在exec-maven-plugin 3.0.0及以上版本可用,你的3.1.0版本完全支持。

内容的提问来源于stack exchange,提问作者BennyBarns

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:10:21