如何使用Exec Maven Plugin运行测试源码中的主类且不纳入发布包?
问题
配置了Exec Maven Plugin后,只能运行src/main/java下的主类,无法运行src/test/java下的com.mypackage.SomeMainClass。该主类用于生成测试源码*TestCase.java,且不希望它进入发布包。当前配置的执行阶段是generate-test-sources,但这个阶段早于测试类编译阶段,导致运行时找不到主类,又不想开发自定义Maven插件。
当前插件配置:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>myexec</id> <phase>generate-test-sources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>java</executable> <classpathScope>test</classpathScope> <arguments> <argument>-classpath</argument> <classpath/> <argument>com.mypackage.SomeMainClass</argument> </arguments> </configuration> </execution> </executions> </plugin>
解决方案
方案1:调整执行阶段到测试类编译完成后
将插件的执行阶段从generate-test-sources改为process-test-classes,这个阶段在测试类编译完成之后,能确保SomeMainClass已经被编译好,可以正常执行。
修改后的插件配置:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>myexec</id> <!-- 切换到process-test-classes阶段,确保测试类已编译 --> <phase>process-test-classes</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>java</executable> <classpathScope>test</classpathScope> <arguments> <argument>-classpath</argument> <classpath/> <argument>com.mypackage.SomeMainClass</argument> </arguments> </configuration> </execution> </executions> </plugin>
注意:如果生成的测试源码需要参与后续的测试编译,这个阶段可能偏晚,此时可以考虑其他方案。
方案2:将主类移到src/main/java,排除出发布包
把SomeMainClass移到src/main/java下,这样它会在compile阶段被编译,能在generate-test-sources阶段正常执行;同时通过maven-jar-plugin排除该类,避免进入发布包。
步骤1:修改Exec插件配置
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>myexec</id> <phase>generate-test-sources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>java</executable> <classpathScope>compile</classpathScope> <arguments> <argument>-classpath</argument> <classpath/> <argument>com.mypackage.SomeMainClass</argument> </arguments> </configuration> </execution> </executions> </plugin>
步骤2:配置maven-jar-plugin排除主类
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <excludes> <!-- 排除生成测试源码的主类,不进入发布包 --> <exclude>com/mypackage/SomeMainClass.class</exclude> </excludes> </configuration> </plugin>
方案3:单独编译测试主类到临时目录再执行
通过maven-compile-plugin在generate-test-sources阶段前单独编译src/test/java下的SomeMainClass到临时目录,再用Exec插件执行该类,既保证执行时机,又不用移动主类位置。
配置示例
<!-- 先单独编译测试主类到临时目录 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compile-plugin</artifactId> <version>3.11.0</version> <executions> <execution> <id>compile-test-main</id> <!-- 在generate-test-sources阶段前执行编译 --> <phase>generate-test-sources</phase> <goals> <goal>compile</goal> </goals> <configuration> <sourceDirectory>src/test/java</sourceDirectory> <!-- 输出到临时目录,避免和正式测试类混淆 --> <outputDirectory>${project.build.directory}/temp-test-classes</outputDirectory> <!-- 只编译目标主类,提升效率 --> <includes> <include>com/mypackage/SomeMainClass.java</include> </includes> </configuration> </execution> </executions> </plugin> <!-- 执行主类,使用临时目录的类文件 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>myexec</id> <phase>generate-test-sources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>java</executable> <!-- 包含临时编译目录、主类输出目录及测试依赖 --> <classpath> <pathelement location="${project.build.directory}/temp-test-classes"/> <pathelement location="${project.build.outputDirectory}"/> <dependencySet> <scope>test</scope> </dependencySet> </classpath> <arguments> <argument>com.mypackage.SomeMainClass</argument> </arguments> </configuration> </execution> </executions> </plugin>
内容的提问来源于stack exchange,提问作者Nicolas Baumann
相关产品推荐
相关产品推荐

