Maven Exec 插件
最后修改时间:2025 年 6 月 11 日
Maven Exec 插件允许您从 Maven 运行 Java 程序和系统命令。它非常适合开发,可以在不构建 JAR 文件的情况下快速执行。
该插件支持两个目标:exec:java
用于运行 Java 类,exec:exec
用于执行系统命令或脚本。本教程将通过实际示例涵盖插件的配置和使用。
基本配置
要使用 Maven Exec 插件,请将其添加到 pom.xml
的 build
部分。以下是在 package 阶段运行 Java 主类的示例配置。
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>exec-example</artifactId> <version>1.0.0</version> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>run-app</id> <phase>package</phase> <goals> <goal>java</goal> </goals> </execution> </executions> <configuration> <mainClass>com.example.MainApp</mainClass> <cleanupDaemonThreads>false</cleanupDaemonThreads> </configuration> </plugin> </plugins> </build> </project>
<mainClass>com.example.MainApp</mainClass>
这指定了要执行的主方法的 Java 类的完全限定名称。cleanupDaemonThreads
选项确保在关闭期间正确处理线程。
运行应用程序
您可以使用 exec:java
目标运行应用程序,如果未在 POM 中配置,则可以通过系统属性指定主类。
mvn exec:java -Dexec.mainClass="com.example.MainApp"
如果插件已在 pom.xml
中配置并绑定到 package 阶段,只需运行
mvn package
这将编译代码并执行已配置的主类。以下是一个演示的示例 Java 应用程序。
package com.example; public class MainApp { public static void main(String[] args) { System.out.println("Hello from Maven Exec Plugin!"); for (String arg : args) { System.out.println("Argument: " + arg); } String prop = System.getProperty("app.name", "Unknown"); System.out.println("App Name: " + prop); } }
运行 mvn package
或 mvn exec:java
将执行此类,打印问候语以及任何传递的参数或系统属性。
传递参数
您可以通过命令行或在 pom.xml
中进行配置,将命令行参数传递给您的 Java 应用程序。
mvn exec:java -Dexec.mainClass="com.example.MainApp" -Dexec.args="arg1 arg2 arg3"
这将“arg1”、“arg2”和“arg3”传递给 main 方法。或者,在 pom.xml
中配置参数
<configuration> <mainClass>com.example.MainApp</mainClass> <arguments> <argument>input.txt</argument> <argument>output.txt</argument> </arguments> </configuration>
这些参数会传递给 main 方法的 String[] args
参数,这对于文件名、标志或其他运行时输入很有用。
系统属性
可以传递系统属性来定制 JVM 或应用程序的行为。这可以通过命令行或在 pom.xml
中完成。
mvn exec:java -Dexec.mainClass="com.example.MainApp" \ -Dapp.name="MyApp" -Denv=dev
或者,在 pom.xml
中配置系统属性
<configuration> <mainClass>com.example.MainApp</mainClass> <systemProperties> <property> <key>app.name</key> <value>MyApp</value> </property> <property> <key>env</key> <value>dev</value> </property> </systemProperties> </configuration>
这些属性可以通过 System.getProperty
在您的 Java 代码中访问,如上面 MainApp
示例所示。
类路径配置
Exec 插件允许您自定义运行应用程序时使用的类路径,从而控制包含哪些依赖项。
<configuration> <mainClass>com.example.MainApp</mainClass> <classpathScope>runtime</classpathScope> <includePluginDependencies>false</includePluginDependencies> <includeProjectDependencies>true</includeProjectDependencies> <additionalClasspathElements> <additionalClasspathElement>${project.basedir}/lib/extra.jar</additionalClasspathElement> </additionalClasspathElements> </configuration>
<classpathScope>runtime</classpathScope>
定义要包含的依赖项范围(例如,compile、runtime、test)。includePluginDependencies
控制是否包含插件依赖项,而 additionalClasspathElements
添加自定义 JAR。
执行外部程序
exec:exec
目标运行系统命令或脚本,例如 Python 脚本、shell 命令或其他可执行文件。
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>run-script</id> <phase>generate-resources</phase> <goals> <goal>exec</goal> </goals> </execution> </executions> <configuration> <executable>python3</executable> <arguments> <argument>${project.basedir}/scripts/process.py</argument> <argument>--input</argument> <argument>data.txt</argument> </arguments> </configuration> </plugin>
此示例在 generate-resources
阶段运行 Python 脚本。executable
必须在系统 PATH 中可用。
多重执行
您可以配置多个执行,以便在不同的 Maven 阶段运行不同的程序或类,例如运行一个主类和一个实用工具。
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>run-main</id> <phase>package</phase> <goals> <goal>java</goal> </goals> <configuration> <mainClass>com.example.MainApp</mainClass> <arguments> <argument>start</argument> </arguments> </configuration> </execution> <execution> <id>run-tool</id> <phase>verify</phase> <goals> <goal>java</goal> </goals> <configuration> <mainClass>com.example.DataValidator</mainClass> <arguments> <argument>check</argument> </arguments> </configuration> </execution> <execution> <id>run-script</id> <phase>process-resources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>bash</executable> <arguments> <argument>${project.basedir}/scripts/cleanup.sh</argument> </arguments> </configuration> </execution> </executions> </plugin>
此配置在不同阶段运行了一个 Java 主类、一个验证工具和一个 shell 脚本,展示了该插件的灵活性。
package com.example; public class DataValidator { public static void main(String[] args) { System.out.println("Running DataValidator with args: " + String.join(", ", args)); // Simulate validation logic boolean valid = "check".equals(args.length > 0 ? args[0] : ""); System.out.println("Data validation: " + (valid ? "Success" : "Failure")); } }
这个 DataValidator
类模拟了一个验证过程,打印传递给它的参数。您可以使用以下命令运行整个 Maven 构建:
$ mvn package
这将按顺序执行所有配置的执行,运行主类、数据验证器和 shell 脚本。
调试支持
Exec 插件通过传递调试标志来支持 JVM 调试。这对于故障排除或在 IDE 中单步执行代码非常有用。
mvn exec:java -Dexec.mainClass="com.example.MainApp" \ -Dexec.jvmArgs="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
或在 pom.xml
中配置
<configuration> <mainClass>com.example.MainApp</mainClass> <jvmArguments> <jvmArgument>-Xdebug</jvmArgument> <jvmArgument>-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005</jvmArgument> </jvmArguments> </configuration>
这将以调试模式启动 JVM,监听端口 5005,允许您连接调试器(例如 IntelliJ IDEA 或 Eclipse)。
环境变量
您可以为执行的程序设置环境变量,这对于配置外部工具或 Java 应用程序很有用。
<configuration> <mainClass>com.example.MainApp</mainClass> <environmentVariables> <JAVA_HOME>/usr/lib/jvm/java-17</JAVA_HOME> <APP_ENV>development</APP_ENV> </environmentVariables> </configuration>
这些变量可以通过 System.getenv
在 Java 应用程序中访问,或者可以被脚本等外部程序访问。
package com.example; public class EnvApp { public static void main(String[] args) { String env = System.getenv("APP_ENV"); System.out.println("Environment: " + (env != null ? env : "Not set")); } }
上面的代码检索 APP_ENV
变量,打印其值或指示它未设置。使用以下命令运行它:
mvn exec:java -Dexec.mainClass="com.example.EnvApp"
这将输出环境变量的值,演示如何将环境变量传递给您的应用程序。
工作目录配置
您可以为执行的程序指定工作目录,这会影响文件操作的执行位置。
<configuration> <mainClass>com.example.MainApp</mainClass> <workingDirectory>${project.basedir}/target</workingDirectory> </configuration>
这会将工作目录设置为 target
文件夹,在执行期间访问生成的文件或输出时很有用。
错误处理和退出代码
Exec 插件可以处理程序退出代码来控制构建过程。例如,如果程序以非零代码退出,您可以使构建失败。
<configuration> <mainClass>com.example.MainApp</mainClass> <successCodes> <successCode>0</successCode> <successCode>1</successCode> </successCodes> </configuration>
此配置将退出代码 0 和 1 视为成功,从而防止构建失败。以下是一个展示退出代码用法的示例:
package com.example; public class ExitCodeApp { public static void main(String[] args) { System.out.println("Running ExitCodeApp"); if (args.length > 0 && "fail".equals(args[0])) { System.exit(2); // Non-success exit code } else { System.exit(0); // Success exit code } } }
如果传递了“fail”参数,此应用程序将以代码 2 退出,否则以代码 0 退出。您可以使用 Exec 插件运行它来查看如何处理退出代码。
使用以下命令运行
mvn exec:java -Dexec.mainClass="com.example.ExitCodeApp" -Dexec.args="fail"
如果没有 successCodes
,非零退出代码将导致构建失败。
最佳实践
以下是有效使用 Maven Exec 插件的最佳实践:
-
显式配置插件 - 在
pom.xml
中定义执行和配置,以实现一致的构建。 - 使用特定阶段 - 将执行绑定到适当的 Maven 阶段(例如,package、verify),以便与构建生命周期集成。
- 最小化命令行覆盖 - 对于可重现性,优先使用 POM 配置而非命令行参数。
-
正确处理线程 - 将
cleanupDaemonThreads
设置为 false,以避免后台线程出现问题。 - 验证可执行文件 - 确保系统命令(例如 python3)在 PATH 中可用,以避免执行失败。
- 明智地使用调试 - 仅在需要时启用调试模式,以避免生产构建中的性能开销。
-
监控退出代码 - 配置
successCodes
来处理预期的退出代码,并防止不必要的构建失败。
来源
在本文中,我们探讨了如何使用 Maven Exec 插件直接从 Maven 运行 Java 应用程序和外部程序,并提供了配置和故障排除的实际示例和最佳实践。
作者
列出所有Java教程。