【问题标题】:Running main method from test class via maven通过maven从测试类运行main方法
【发布时间】:2023-04-01 23:56:02
【问题描述】:

我的 pom.xml 中有以下内容:

<build>
   ...
   <plugins>
   ...
      <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>exec-maven-plugin</artifactId>
          <version>1.2.1</version>
          <configuration>
              <mainClass>com.myorg.MyClass</mainClass>
          </configuration>
      </plugin>
   </plugins>
</build>

com.myorg.MyClass 类在我的测试源目录中,我可以使用以下命令运行它:

mvn -e exec:java -Dexec.classpathScope="test"

我想:

  1. 避免使用-Dexec.classpathScope="test",但我不知道如何配置该插件以查看测试类路径。
  2. 为其他类编写更多插件(每个类都有不同的配置),但现在我只能运行exec:java。有没有办法给这个插件贴上标签,这样我就可以通过这个标签来调用它,而不仅仅是说“运行 exec:java 中的任何内容”?
  3. 拉入-javaagent 属性。我在我的 pom.xml 中定义了这个属性,测试用例正在使用它。我的“自定义”插件会获取这些属性,还是我需要做任何事情才能将它们引入?

这里是属性,直接在&lt;project&gt;下定义。

<properties>
   <spring.version>3.2.6.RELEASE</spring.version>
   <atomikos.version>3.9.2</atomikos.version>
   <loadTimeWeaverArgLine>-javaagent:"${settings.localRepository}/org/springframework/spring-agent/2.5.6/spring-agent-2.5.6.jar"</loadTimeWeaverArgLine>
</properties>

尝试配置文件

根据@Michal 的建议 (https://stackoverflow.com/a/30839824/257233),这是我尝试过的:

<profile>
   <id>run-importer</id>
   <properties>
      <loadTimeWeaverArgLine>-javaagent:"${settings.localRepository}/org/springframework/spring-agent/2.5.6/spring-agent-2.5.6.jar"</loadTimeWeaverArgLine>
   </properties>
   <build>
      <plugins>
         <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>
            <configuration>
               <executable>java</executable>
                  <!--
                     None of these three options work.
                     <commandlineArgs>-javaagent:C:/Users/robbram/.m2/repository/org/springframework/spring-agent/2.5.6/spring-agent-2.5.6.jar</commandlineArgs>
                     <commandlineArgs>${loadTimeWeaverArgLine}</commandlineArgs>
                     <commandlineArgs>-javaagent:"${settings.localRepository}/org/springframework/spring-agent/2.5.6/spring-agent-2.5.6.jar"</commandlineArgs>
                     <argLine>${loadTimeWeaverArgLine}</argLine>
                  -->
               <classpathScope>test</classpathScope>
               <mainClass>com.myorg.MyClass</mainClass>
            </configuration>
         </plugin>
      </plugins>
   </build>
</profile>

我运行它:

mvn -e exec:java -Prun-importer 

我得到以下任一选项的异常:

[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:java (default-cli) on project TOLTAT-Model: An exception occured while executing the Java class. null: InvocationTargetException: Error creating bean with name 'loadTimeWeaver' defined in class org.springframework.context.annotation.LoadTimeWeavingConfiguration: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.instrument.classloading.LoadTimeWeaver org.springframework.context.annotation.LoadTimeWeavingConfiguration.loadTimeWeaver()] threw exception; nested exception is java.lang.IllegalStateException: ClassLoader [java.net.URLClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:java (default-cli) on project TOLTAT-Model: An exception occured while executing the Java class. null
   at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:216)
   at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
   at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)

我可以确认主类com.myorg.MyClass 正在执行。我可以看到它的其他输出。我还可以确认 loadTimeWeaverArgLine 在此 POM 的其他部分中有效。它已成功用于集成测试:

<profile>
   <id>integration-tests</id>
   <build>
      <plugins>
         <!-- Integration tests require additional loadtime Spring argument -->
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.16</version>
            <configuration>
               <forkMode>once</forkMode>
               <argLine> ${loadTimeWeaverArgLine}</argLine>
               <skip>false</skip>
            </configuration>
         </plugin>
      </plugins>
   </build>
</profile>

使用配置文件和 mvn exec:exec 尝试 2

更新(2015 年 6 月 17 日,星期三,下午 12:11:17):关注 Michal's latest comment 我现在可以按照我的意愿进行操作:

<profile>
   <id>run-importer</id>
   <properties>
      <loadTimeWeaverArg>-javaagent:"${settings.localRepository}/org/springframework/spring-agent/2.5.6/spring-agent-2.5.6.jar"</loadTimeWeaverArg>
      <log4JConfigArg>-Dlog4j.configuration=file:${project.build.directory}/path/to/log4j.properties</log4JConfigArg>
      <mainClassArg>com.myorg.MyClass</mainClassArg>
      <arg1>foo</arg1>
   </properties>
   <build>
      <plugins>
         <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>
            <goals>
               <goal>exec</goal>
            </goals>
            <configuration>
               <executable>java</executable>
               <classpathScope>test</classpathScope>
               <arguments>
                  <argument>${log4JConfigArg}</argument>
                  <argument>${loadTimeWeaverArg}</argument>
                  <argument>-classpath</argument>
                  <classpath />
                  <argument>${mainClassArg}</argument>
                  <argument>${arg1}</argument>
               </arguments>
            </configuration>
         </plugin>
      </plugins>
   </build>
</profile>

我运行它:

mvn -e exec:exec -Prun-importer

这种方法的优点:

  • 此配置文件的全部目的是运行“特殊代码”,这些代码永远不应部署,但需要使用 src 中的代码并测试 src。
    • 我注意到 Michal 的建议,即这应该成为一个模块。如果这个代码库还没有那么完善(大型、陈旧、复杂),我会认真考虑这一点。
  • 它留出了空间以防万一需要复制,因此对于使用 mvn -e exec:exec 运行的内容没有“竞争”。
  • 我可以使用 pom 中已经存在的变量指定 java 代理、log4j 和许多其他配置。
  • 我可以在命令行上用-Darg1="bar" 覆盖这些参数中的任何一个

【问题讨论】:

    标签: maven maven-plugin


    【解决方案1】:

    我不确定你实际上要通过这个来完成什么,因为它对 Maven 的使用非常生硬。然而,所有这些东西在技术上都是可行的:

    1/

    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.2.1</version>
        <configuration>
            <mainClass>com.myorg.MyClass</mainClass>
            <classpathScope>test</classpathScope>
        </configuration>
    </plugin>
    

    2/

    您可以为此使用配置文件并将不同的插件配置放在不同的配置文件中。然后你打电话:

    mvn -e exec:java -Pmy-first-profile
    

    我觉得这真的很奇怪。我的建议是重新考虑您的情况,并为此选择另一种方式或工具。

    3/

    作者编辑后问题本身的最终解决方案。

    【讨论】:

    • 谢谢 Michal,我会在早上尝试这第一件事。不过,我想解释一下我使用 Maven 的理由。这是一个预先存在的项目,已经在 Maven 中进行了很多配置。我的代码需要很多这样的配置,而且它使用 src 目录中的类,但我的代码也是一种永远不应该部署的特殊情况(因此它位于测试目录中)。我不想使用其他工具,因为那样我就必须弄清楚如何复制已经存在的所有配置。
    • 好的,知道了。对于测试代码库非常复杂并且可能单独使用(无论出于何种原因)的这种情况,我真的建议使用单独的 Maven 模块(例如my-superb-project-testing-support),其中所有测试内容(junitmockito,支持类, builder 等)被放入 src/main/java 树中。这样的模块可以在其他(业务)模块中用作测试范围的依赖项。
    • 嗯,前两部分已经解决了,但第三部分要害死我了。我已经更新了我的问题,以展示我到目前为止所做的尝试。
    • 如需更新说明,请致电mvn -e exec:exec -Prun-importer 而不是mvn exec:java ...
    • 非常感谢 - 根据您的建议,我终于想出了如何解决我遇到的所有问题。 :)
    猜你喜欢
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 2017-07-12
    • 1970-01-01
    • 2019-10-31
    相关资源
    最近更新 更多