2015-04-10 9 views
5

Beim Erstellen meines Projekts mit Maven mit JUnit-Tests mit todsicheren und Cobertura, um Testabdeckung zu erhalten, hat normalerweise alles funktioniert. Aber wenn ich vor kurzem eine Ausnahme hinzugefügt, die ausgelöst werden konnte (und ausgenommen ist) von einigen Tests Maven sagte mir immer:Cobertura verursacht ClassNotFoundException

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test (default-test) on project backend-server: Execution default-test of goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test failed: There was an error in the forked process 
[ERROR] java.lang.NoClassDefFoundError: de/unileipzig/irpsim/backend/simulation/TimerowTooShortException 
[ERROR] at java.lang.Class.getDeclaredMethods0(Native Method) 
[ERROR] at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) 
[ERROR] at java.lang.Class.privateGetMethodRecursive(Class.java:3048) 
[ERROR] at java.lang.Class.getMethod0(Class.java:3018) 
[ERROR] at java.lang.Class.getMethod(Class.java:1784) 
[ERROR] at org.apache.maven.surefire.util.ReflectionUtils.tryGetMethod(ReflectionUtils.java:57) 
[ERROR] at org.apache.maven.surefire.common.junit3.JUnit3TestChecker.isSuiteOnly(JUnit3TestChecker.java:64) 
[ERROR] at org.apache.maven.surefire.common.junit3.JUnit3TestChecker.isValidJUnit3Test(JUnit3TestChecker.java:59) 
[ERROR] at org.apache.maven.surefire.common.junit3.JUnit3TestChecker.accept(JUnit3TestChecker.java:54) 
[ERROR] at org.apache.maven.surefire.common.junit4.JUnit4TestChecker.accept(JUnit4TestChecker.java:52) 
[ERROR] at org.apache.maven.surefire.util.DefaultScanResult.applyFilter(DefaultScanResult.java:97) 
[ERROR] at org.apache.maven.surefire.junit4.JUnit4Provider.scanClassPath(JUnit4Provider.java:222) 
[ERROR] at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:107) 
[ERROR] at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203) 
[ERROR] at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155) 
[ERROR] at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103) 
[ERROR] Caused by: java.lang.ClassNotFoundException: de.unileipzig.irpsim.backend.simulation.TimerowTooShortException 
[ERROR] at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 
[ERROR] at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
[ERROR] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) 
[ERROR] at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
[ERROR] ... 16 more 
[ERROR] -> [Help 1] 

Ein Lauf mit -X oder Dinge wie diese leider nicht helfen, und auch bei der Suche http://maven.apache.org/surefire/maven-surefire-plugin/examples/class-loading.html oder Intermittent NoClassDefFoundError when running a maven/surefire build in jenkins haben keinen nützlichen Hinweis für dieses Problem angeboten.

Meine todsichere-Plugin wird wie folgt definiert:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-surefire-plugin</artifactId> 
    <version>2.18.1</version> 
    <configuration> 
     <forkedProcessTimeoutInSeconds>900</forkedProcessTimeoutInSeconds> 
     <argLine>-Djava.library.path=${nativelib.directory}</argLine> 
     <excludes> 
      <exclude>**/DatabaseTest.java</exclude> 
     </excludes> 
    </configuration> 
</plugin> 

Wenn das Forking deaktivieren, alles beginnt funktionierte gut, aber die einheimische Libs ist nicht enthalten, so ist dies keine Option. Auch, wenn ich alle Tests ausschließe, die das TimerowTooShortException verwenden, funktioniert alles gut.

Nach einigen Versuchen fand ich heraus, dass Cobertura, selbst wenn der Test mit -Dcobertura.skip=true ausgeführt wird, das Problem verursacht. Cobertura wurde in dem Plugins wie folgt definiert:

<plugin> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>cobertura-maven-plugin</artifactId> 
    <version>2.6</version> 
    <configuration> 
     <formats> 
      <format>xml</format> 
     </formats> 
    </configuration> 
    <dependencies> 
     <dependency> 
      <groupId>org.ow2.asm</groupId> 
      <artifactId>asm</artifactId> 
      <version>5.0.3</version> 
     </dependency> 
    </dependencies> 
    <executions> 
     <execution> 
      <phase>package</phase> 
      <goals> 
       <goal>cobertura</goal> 
      </goals> 
     </execution> 
    </executions> 
</plugin> 

Leider konnte ich keine Informationen über dieses spezielle Problem finden, wenn todsicheren und cobertura zusammen mit einer erwarteten Ausnahme verwenden. Weiß jemand, warum dies bei der Verwendung von Cobertura passiert? Und gibt es einen Workaround dafür?

Antwort

0

ich denselben Fehler hatte, aber

`<testFailureIgnore>false</testFailureIgnore>` 

Problem lösen hinzufügen. Also nächste Konfiguration sollte das Problem lösen.

 <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-surefire-plugin</artifactId> 
      <version>2.18.1</version> 
      <configuration> 
       <skipTests>${skipTests}</skipTests> 
       <testFailureIgnore>false</testFailureIgnore> 
       <includes> 
       <include>**/*.java</include> 
       </includes> 
      </configuration> 
     </plugin> 
3

Ich habe einen ähnlichen Fehler bei einem Multimodul-Projekt festgestellt. Wann immer ich die -Dcobertura.skip=true hinzugefügt habe, habe ich die NoClassDefFound und ClassNotFound-Ausnahmen.

Leider konnte ich nicht herausfinden, warum. Meine Vermutung ist, dass nicht jedes Cobertura-Ziel den Parameter annimmt.

Allerdings "löste" ich das Problem mit Profilen. Das heißt, ich habe das Cobertura-Plugin von der Standard-Build-Konfiguration in das Cobertura-Profil verschoben.

<profiles> 
    <profile> 
     <id>cobertura-run</id> 
     <properties> 
      <maven.test.skip>false</maven.test.skip> 
     </properties> 
     <build> 
      <plugins> 
       <plugin> 
        <groupId>org.codehaus.mojo</groupId> 
        <artifactId>cobertura-maven-plugin</artifactId> 
        <version>2.7</version> 
        <configuration> 
         <formats> 
          <format>xml</format> 
         </formats> 
        </configuration> 
        <executions> 
         <execution> 
          <phase>package</phase> 
          <goals> 
           <goal>cobertura</goal> 
          </goals> 
         </execution> 
        </executions> 
       </plugin> 
      </plugins> 
     </build> 
    </profile> 
</profiles> 

Immer, wenn ich cobertura ausgeführt werden soll, verwende ich -P cobertura-run statt deaktivieren oder cobertura in Kommandozeile ermöglicht.