繁体   English   中英

如何在测试范围内使用m2e(Eclipse / Maven)运行命令行程序,并具有测试依赖性?

[英]How do I run a command line program using m2e (Eclipse/Maven) in the test scope, with test dependencies?

我在使用m2e插件运行java应用程序(static void main)时遇到问题。 我通过普通的eclipse向导创建了一个多模块项目。 看起来似乎一个模块的测试目录中的代码在运行时无法引用另一个模块的测试目录中的代码(编译工作正常)。

版本信息

  • Eclipse = Luna,Build 4.4.0,Build id 20140612-0600
  • m2e = 1.5.0.20140606-0033

我创建了一个非常简单(和人为)的例子来演示我的问题。 请轻松告诉我这段代码的无意义。 另外,请原谅我这里的冗长。 可悲的是,maven问题几乎需要它。


这是项目目录结构:

--Project Explorer
 |--animals/
   |--src/test/java/
     |--com.example.problem.animals
       |--Animal.java
   |--JRE System Library [JavaSE-1.8]
   |--src/
   |--target/
   |--pom.xml
 |--dogs/
   |--src/test/java/
     |--com.example.problem.animals
       |--Beagle.java
   |--JRE System Library [JavaSE-1.8]
   |--Maven Dependencies
     |--animals/
   |--src/
   |--target/
   |--pom.xml
 |--parent/
   |--animals/
   |--dogs/
   |--src/
   |--pom.xml

父模块pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example.problem</groupId>
  <artifactId>parent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>Parent</name>
  <description>Parent module for example project.</description>

  <modules>
    <module>animals</module>
    <module>dogs</module>
  </modules>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

动物模块pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.example.problem</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>animals</artifactId>

  <name>Animals</name>
  <description>Module to hold common animal code.</description>
</project>

狗模块pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.example.problem</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>dogs</artifactId>

  <name>Dogs</name>
  <description>Module to hold dog specific code.</description>

  <dependencies>
    <dependency>
      <groupId>com.example.problem</groupId>
      <artifactId>animals</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>
  </dependencies>
</project>

这里的想法是让@Animal注释Beagle对象。 注释位于“animals”的测试目录下,而我们的java runnable类Beagle位于“dogs”的测试目录下。

Animal.java:

package com.example.problem.animals;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Simple annotation to denote an animal.
 * 
 * @author Rich - created 03/Sep/2014
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Animal {
  String noise();
}

Beagle.java:

package com.example.problem.animals;

/*
 * Runnable java class that simply prints the animal noise for Beagle to the console.
 *
 * @author Rich - created 03/Sep/2014
 */
@Animal(noise = "Woof!")
public class Beagle {
  public static void main(String[] args) {
    Animal animal = Beagle.class.getAnnotation(Animal.class);
    System.out.println(animal.noise());
  }
}

为了运行Beagle类,我使用eclipse向导创建了一个新的运行配置。 配置类型是“Maven Build”。 “JRE”选项卡将“Runtime JRE”设置为“Workspace default JRE(jre1.8.0_20)”。 在配置的“主”选项卡上进行以下设置:

  • “基目录”字段设置为“$ {workspace_loc:/ dogs}”
  • “目标”字段设置为“exec:java”
  • “配置文件”字段设置
  • 设置“用户设置”字段
  • “脱机”,“更新快照”,“调试输出”,“跳过测试”和“非递归”复选框检查
  • “解决工作区文物”复选框选中
  • 添加的参数
    • “exec.mainClass”设置为“com.example.problem.animals.Beagle”
    • “exec.classpathScope”设置为“test”
  • “Maven Runtime”设置为“EMBEDDED(3.2.1 / 1.5.0.20140605-2032)”

运行此配置最终会失败并生成以下控制台输出:

[INFO] Scanning for projects...
[INFO] 
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder with a thread count of 1
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Dogs 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- exec-maven-plugin:1.3.2:java (default-cli) @ dogs ---
[WARNING] Warning: killAfter is now deprecated. Do you need it ? Please comment on MEXEC-6.
[WARNING] 
java.lang.reflect.InvocationTargetException
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  at java.lang.reflect.Method.invoke(Unknown Source)
  at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
  at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: com/example/problem/animals/Animal
  at com.example.problem.animals.Beagle.main(Beagle.java:6)
  ... 6 more
Caused by: java.lang.ClassNotFoundException: com.example.problem.animals.Animal
  at java.net.URLClassLoader$1.run(Unknown Source)
  at java.net.URLClassLoader$1.run(Unknown Source)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.net.URLClassLoader.findClass(Unknown Source)
  at java.lang.ClassLoader.loadClass(Unknown Source)
  at java.lang.ClassLoader.loadClass(Unknown Source)
  ... 7 more
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.282 s
[INFO] Finished at: 2014-09-13T18:25:51-08:00
[INFO] Final Memory: 9M/155M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.3.2:java (default-cli) on project dogs: An exception occured while executing the Java class. null: InvocationTargetException: com/example/problem/animals/Animal: com.example.problem.animals.Animal -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

在使用“Debug Output”设置运行配置后,我在控制台中挖掘并找到以下有趣的行:

[DEBUG] Configuring mojo 'org.codehaus.mojo:exec-maven-plugin:1.3.2:java' with basic configurator -->
[DEBUG]   (f) arguments = []
[DEBUG]   (f) classpathScope = test
[DEBUG]   (f) cleanupDaemonThreads = true
[DEBUG]   (f) daemonThreadJoinTimeout = 15000
[DEBUG]   (f) includePluginDependencies = false
[DEBUG]   (f) includeProjectDependencies = true
[DEBUG]   (f) keepAlive = false
[DEBUG]   (f) killAfter = 1
[DEBUG]   (f) localRepository =        id: local
...
[DEBUG] Project Dependencies will be included.
[DEBUG] Collected project artifacts [com.example.problem:animals:jar:0.0.1-SNAPSHOT:compile]
[DEBUG] Collected project classpath [C:\Users\cairnsjr13\workspace\parent\dogs\target\test-classes, C:\Users\cairnsjr13\workspace\parent\dogs\target\classes]
[DEBUG] Adding to classpath : file:/C:/Users/cairnsjr13/workspace/parent/dogs/target/test-classes/
[DEBUG] Adding to classpath : file:/C:/Users/cairnsjr13/workspace/parent/dogs/target/classes/
[DEBUG] Adding project dependency artifact: animals to classpath

我很困惑的原因是,它看起来似乎试图包含“动物”依赖。 我怀疑它包括主依赖,而不是测试依赖。 所以...在这个极长的蜿蜒信息转储之后......有没有人知道如何让eclipse(m2e)执行这种情况? 我已经正确配置它来处理测试测试编译依赖项,但是在我的生命中不能让运行时依赖项工作。

exec.classpathScope设置为test会将已执行模块的测试类添加到类路径中,但不会将依赖项的测试类添加到类路径中。 如调试输出中所示,它添加了dogs模块的测试类,但没有添加animals的测试类:

[DEBUG] Adding to classpath : file:/C:/Users/cairnsjr13/workspace/parent/dogs/target/test-classes/

为了依赖animals的测试类,您需要通过指定test-jar目标来为其配置maven-jar-plugin如此链接中所述

动物

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>test-jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

然后更新dogsanimals的依赖关系,以获得如下测试范围:

小狗

<dependencies>
    <dependency>
        <groupId>com.example.problem</groupId>
        <artifactId>animals</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <type>test-jar</type> 
        <scope>test</scope>
    </dependency>
</dependencies>

添加此配置后, install animals模块install到本地Maven存储库中。 这将在您的本地仓库中创建一个Jar,其中包含模块的测试类,特别是Animal类,以及为主类创建的普通Jar。 您可以从命令行进行安装,也可以右键单击animals项目,然后选择Run As - > Maven install

然后在Eclipse中启动相同的运行配置,但不选中 “Resolve Workspace artifacts”复选框,以便从本地Maven存储库中解析测试工件。

在重现你的场景时,我注意到的奇怪之处在于,如果我添加了所有上面的Maven配置( maven-jar-plugin和测试范围的依赖项),但是我保持“Resolve Workspace artifacts”复选框, m2eclipse失败即使目标文件夹包含Jar并且项目已刷新/更新,也要在工作空间中解析测试Jar。 我有一种感觉,这是插件本身的一个错误,特别是在解析使用test-jar目标配置的工作空间测试Jar依赖时。

经过大量的渐进式更改和反复试验,我已经想出了如何让它发挥作用。 这种方法的好处在于,您仍然可以在动物项目中积极开发,而无需每次都将其作为测试罐导出。 <dependency>标记具有必须设置的type属性。 狗pom.xml文件然后变成:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.example.problem</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>dogs</artifactId>

  <name>Dogs</name>
  <description>Module to hold dog specific code.</description>

  <dependencies>
    <dependency>
      <groupId>com.example.problem</groupId>
      <artifactId>animals</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <type>test-jar</type>
    </dependency>
  </dependencies>
</project>

执行原始运行配置会产生以下输出:

[INFO] Scanning for projects...
[INFO] 
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder with a thread count of 1
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Dogs 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- exec-maven-plugin:1.3.2:java (default-cli) @ dogs ---
[WARNING] Warning: killAfter is now deprecated. Do you need it ? Please comment on MEXEC-6.
Woof!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.310 s
[INFO] Finished at: 2014-09-21T13:53:21-08:00
[INFO] Final Memory: 9M/155M
[INFO] ------------------------------------------------------------------------

这里有几点需要注意。

scope属性不需要设置为test以使其运行。 将<scope> test </ scope>标记添加到依赖项将导致在非测试范围中省略依赖项。 由于我们在测试范围内运行并不重要。

这种方法不包括对动物主要代码的依赖。 在原始问题的示例中,这并不重要,因为没有主代码源目录。 如果动物的测试代码依赖于动物的主要代码,则必须在狗中添加额外的依赖关系才能选择它。 以下是狗pom.xml文件在这种情况下的样子:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.example.problem</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>dogs</artifactId>

  <name>Dogs</name>
  <description>Module to hold dog specific code.</description>

  <dependencies>
    <!-- Including both dependencies for jar and test-jar to get main src included. -->
    <dependency>
      <groupId>com.example.problem</groupId>
      <artifactId>animals</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>com.example.problem</groupId>
      <artifactId>animals</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <type>test-jar</type>
    </dependency>
  </dependencies>
</project>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM