简体   繁体   English

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

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

I am having trouble running a java application (static void main) with the m2e plugin. 我在使用m2e插件运行java应用程序(static void main)时遇到问题。 I have created a multi-module project through the ordinary eclipse wizard. 我通过普通的eclipse向导创建了一个多模块项目。 It seems as if code in the test directory of one module cannot reference code in the test directory of another module at runtime (compiling works just fine). 看起来似乎一个模块的测试目录中的代码在运行时无法引用另一个模块的测试目录中的代码(编译工作正常)。

Version information 版本信息

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

I have created an extremely simple (and contrived) example to demonstrate my problem. 我创建了一个非常简单(和人为)的例子来演示我的问题。 Please go easy on me for the pointlessness of this code. 请轻松告诉我这段代码的无意义。 Also, forgive me for the verbosity here. 另外,请原谅我这里的冗长。 Sadly maven questions almost require it. 可悲的是,maven问题几乎需要它。


Here is the project directory structure: 这是项目目录结构:

--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

The parent module 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>

The animals module 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>

  <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>

The dogs module 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>

  <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>

The idea here is to have the Beagle object annotated with @Animal. 这里的想法是让@Animal注释Beagle对象。 The annotation lives under the test directory of "animals", while our java runnable class Beagle lives under the test directory of "dogs". 注释位于“animals”的测试目录下,而我们的java runnable类Beagle位于“dogs”的测试目录下。

Animal.java: 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: 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());
  }
}

In order to run the Beagle class, I have created a new run configuration using the eclipse wizard. 为了运行Beagle类,我使用eclipse向导创建了一个新的运行配置。 The configuration type is "Maven Build". 配置类型是“Maven Build”。 The "JRE" tab has the "Runtime JRE" set to be "Workspace default JRE (jre1.8.0_20)". “JRE”选项卡将“Runtime JRE”设置为“Workspace default JRE(jre1.8.0_20)”。 The following settings are made on the "Main" tab of the configuration: 在配置的“主”选项卡上进行以下设置:

  • "Base directory" field is set to "${workspace_loc:/dogs}" “基目录”字段设置为“$ {workspace_loc:/ dogs}”
  • "Goals" field is set to "exec:java" “目标”字段设置为“exec:java”
  • "Profiles" field is not set “配置文件”字段设置
  • "User settings" field is not set 设置“用户设置”字段
  • "Offline", "Update Snapshots", "Debug Output", "Skip Tests", and "Non-recursive" checkboxes are not checked “脱机”,“更新快照”,“调试输出”,“跳过测试”和“非递归”复选框检查
  • "Resolve Workspace artifacts" checkbox is checked “解决工作区文物”复选框选中
  • Parameters that are added 添加的参数
    • "exec.mainClass" is set to "com.example.problem.animals.Beagle" “exec.mainClass”设置为“com.example.problem.animals.Beagle”
    • "exec.classpathScope" is set to "test" “exec.classpathScope”设置为“test”
  • "Maven Runtime" is set to "EMBEDDED (3.2.1/1.5.0.20140605-2032)" “Maven Runtime”设置为“EMBEDDED(3.2.1 / 1.5.0.20140605-2032)”

Running this configuration ultimately fails and produces the following console output: 运行此配置最终会失败并生成以下控制台输出:

[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

After running the configuration with "Debug Output" set, I dug through the console and found the following interesting lines: 在使用“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

The reason I am so confused is the fact that it looks like it is trying to include the "animals" dependency. 我很困惑的原因是,它看起来似乎试图包含“动物”依赖。 I suspect its including the main dependency and not the test dependency. 我怀疑它包括主依赖,而不是测试依赖。 So... after this extremely long winded info dump... Does anyone have any idea how to get eclipse (m2e) to execute this situation? 所以...在这个极长的蜿蜒信息转储之后......有没有人知道如何让eclipse(m2e)执行这种情况? I have gotten it configured properly to handle the test-test compile dependency, but cannot for the life of me get the runtime dependency to work. 我已经正确配置它来处理测试测试编译依赖项,但是在我的生命中不能让运行时依赖项工作。

Setting exec.classpathScope to test adds the test classes of the executed module to the classpath but not the test classes of the dependency. exec.classpathScope设置为test会将已执行模块的测试类添加到类路径中,但不会将依赖项的测试类添加到类路径中。 As shown in the debug output, it adds the test classes of the dogs module but does not add the test classes of animals : 如调试输出中所示,它添加了dogs模块的测试类,但没有添加animals的测试类:

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

In order to depend on the test classes of animals , you would need to configure a maven-jar-plugin for it by specifying the test-jar goal as explained in this link . 为了依赖animals的测试类,您需要通过指定test-jar目标来为其配置maven-jar-plugin如此链接中所述

animals 动物

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

Then update the dependency of dogs on animals to have a test scope as follows: 然后更新dogsanimals的依赖关系,以获得如下测试范围:

dogs 小狗

<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>

After adding this configuration, install the animals module into your local Maven repository. 添加此配置后, install animals模块install到本地Maven存储库中。 This would create a Jar in your local repo that contains the test classes of the module, specifically the Animal class, along with the normal Jar that's created for the main classes. 这将在您的本地仓库中创建一个Jar,其中包含模块的测试类,特别是Animal类,以及为主类创建的普通Jar。 You can either do the install from the command line or right-clicking on the animals project, and selecting Run As -> Maven install . 您可以从命令行进行安装,也可以右键单击animals项目,然后选择Run As - > Maven install

Then launch the same run configuration in Eclipse but with the "Resolve Workspace artifacts" checkbox unchecked so that the test artifacts are resolved from the local Maven repository. 然后在Eclipse中启动相同的运行配置,但不选中 “Resolve Workspace artifacts”复选框,以便从本地Maven存储库中解析测试工件。

The weird thing I noticed, when reproducing your scenario, is that if I add all of the above Maven configuration (the maven-jar-plugin and the test-scoped dependency) but I keep the "Resolve Workspace artifacts" checkbox ticked, m2eclipse fails to resolve the test Jar in the workspace even if the target folder contains the Jar and the project is refreshed/updated. 在重现你的场景时,我注意到的奇怪之处在于,如果我添加了所有上面的Maven配置( maven-jar-plugin和测试范围的依赖项),但是我保持“Resolve Workspace artifacts”复选框, m2eclipse失败即使目标文件夹包含Jar并且项目已刷新/更新,也要在工作空间中解析测试Jar。 I have a feeling that it's a bug in the plugin itself, specifically when resolving a workspace test Jar dependency configured using the test-jar goal. 我有一种感觉,这是插件本身的一个错误,特别是在解析使用test-jar目标配置的工作空间测试Jar依赖时。

After a ton of incremental changes and trial-and-error, I've figured out how to get this to work. 经过大量的渐进式更改和反复试验,我已经想出了如何让它发挥作用。 The nice thing about this approach is that you can still actively develop in the animals project without having to export it as a test-jar everytime. 这种方法的好处在于,您仍然可以在动物项目中积极开发,而无需每次都将其作为测试罐导出。 The <dependency> tag has a type attribute which must be set. <dependency>标记具有必须设置的type属性。 The dogs pom.xml file then becomes: 狗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>

Executing the original run configuration yields the following output: 执行原始运行配置会产生以下输出:

[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] ------------------------------------------------------------------------

There are a couple of things to note here. 这里有几点需要注意。

The scope attribute is not required to be set to test to get this to run. scope属性不需要设置为test以使其运行。 Adding the <scope>test</scope> tag to the dependency will cause the dependency to be omitted in a non-test scope. 将<scope> test </ scope>标记添加到依赖项将导致在非测试范围中省略依赖项。 Since we are running in test scope it does not matter. 由于我们在测试范围内运行并不重要。

This approach will NOT include a dependency on the main code from animals. 这种方法不包括对动物主要代码的依赖。 In the example in the original question, this did not matter because there was no main code source directory. 在原始问题的示例中,这并不重要,因为没有主代码源目录。 In the event that the test code in animals depends on main code in animals you must add an additional dependency in dogs to pick that up. 如果动物的测试代码依赖于动物的主要代码,则必须在狗中添加额外的依赖关系才能选择它。 Here is what the dogs pom.xml file would look like in that situation: 以下是狗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.

相关问题 如何测试Maven / M2e插件在Eclipse中是否正确配置? - how to test if maven/m2e plugin is configured correctly in eclipse? 当主代码引用测试代码时,我可以使用eclipse(使用maven,m2e)抛出错误/警告吗? - Can I get eclipse (using maven, m2e) to throw an error/warning when main code references test code? m2e wtp部署测试依赖项 - m2e wtp deploying test dependencies m2e可以安装外部jar文件吗? 还是我需要安装Maven命令行工具? - Can m2e install an external jar file? Or do I need to install the maven command line tool? 如何在Eclipse中安装M2E-Maven集成? - How can I install the M2E - Maven Integration in Eclipse? 如何使用Luna Service(4.4.1)上的Eclipse m2e将jar文件添加到本地Maven存储库? - How do I add a jar file to my local Maven repository using Eclipse m2e on Luna Service (4.4.1)? 如何在Eclipse中打开Java项目(使用Maven)? (我使用M2E还是maven-eclipse-plugin) - How do I open a Java project (that uses maven) in Eclipse? (Do I use M2E or maven-eclipse-plugin) Eclipse m2e 不支持带有 JPMS 模块的 Maven test-jar - Eclipse m2e doesn't support Maven test-jar with JPMS modules 如何使M2E(Eclipse的Maven集成)知道在哪里找到依赖项? - How to make m2e (maven integration for eclipse) know where to find dependencies? 如何使在Eclipse中运行JUnit测试的行为与在命令行上运行Maven测试的行为相同? - How do I make running a JUnit test in eclipse behave the same as running the Maven test on the command line?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM