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