[英]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 版本信息
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:
在配置的“主”选项卡上进行以下设置:
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: 然后更新
dogs
对animals
的依赖关系,以获得如下测试范围:
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.