NoClassDefFoundError: org/junit/AfterClass during annotation processing

◇◆丶佛笑我妖孽 提交于 2019-12-08 05:55:39

问题


I am generating code with CodeModel during annotation processing with maven. That code is for JUnit testing:

JMethod tearDownClass = testClass.method(
        JMod.PUBLIC | JMod.STATIC, Void.class, "tearDownClass");
tearDownClass._throws(Exception.class);
tearDownClass.annotate(AfterClass.class); <- java.lang.NoClassDefFoundError

Yet, the compilation process throws a java.lang.NoClassDefFoundError : org/junit/AfterClass when it tries to retrieve the AfterClass.class, which is an annotation itself.

The dependency to JUnit is defined as following:

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.8.2</version>
</dependency>

so AfterClass.class should be available in my code.

How do I solve this one?

Unclear

The code calling codemodel is in a compiled library where junit is not a 'test' dependency. However, the code calling the generating code has the same junit dependency, but as a test dependency.

If I change that latter dependency to 'not-a-test' dependency, the issue disappears. Why do I have to define this dependency as 'not-a-test' though only the library calling codemodel is explicitely using it?

EDIT

Here is the dependency tree:

net.dwst:codegentest:jar:1.0.0
+- junit:junit:jar:4.8.2:compile
+- org.sonatype.maven.plugin:emma-maven-plugin:jar:1.2:test
|  +- emma:emma:jar:2.0.5312:test
|  \- org.apache.maven.reporting:maven-reporting-impl:jar:2.0.4:test
|     +- commons-validator:commons-validator:jar:1.2.0:test
|     |  +- commons-beanutils:commons-beanutils:jar:1.7.0:test
|     |  +- commons-digester:commons-digester:jar:1.6:test
|     |  |  \- commons-collections:commons-collections:jar:2.1:test
|     |  \- commons-logging:commons-logging:jar:1.0.4:test
|     +- org.apache.maven.doxia:doxia-core:jar:1.0-alpha-7:test
|     +- oro:oro:jar:2.0.7:test
|     \- org.apache.maven.doxia:doxia-site-renderer:jar:1.0-alpha-7:test
|        +- org.codehaus.plexus:plexus-i18n:jar:1.0-beta-6:test
|        +- org.codehaus.plexus:plexus-velocity:jar:1.1.2:test
|        |  +- commons-logging:commons-logging-api:jar:1.0.4:test
|        |  \- velocity:velocity:jar:1.4:test
|        |     \- velocity:velocity-dep:jar:1.4:test
|        \- org.apache.maven.doxia:doxia-decoration-model:jar:1.0-alpha-7:test
+- net.dwst:generics:jar:1.3.0:compile
|  +- org.swinglabs:swing-layout:jar:1.0.3:compile
|  \- com.sun.codemodel:codemodel:jar:2.4.1:compile
+- net.flat:flat:jar:1.3.0:compile
|  \- com.pyx4me:proguard-maven-plugin:jar:2.0.4:compile
|     +- ant:ant:jar:1.6.5:compile
|     +- org.apache.maven:maven-archiver:jar:2.3:compile
|     +- org.codehaus.plexus:plexus-archiver:jar:1.0-alpha-9:compile
|     \- org.codehaus.plexus:plexus-io:jar:1.0-alpha-1:compile
+- org.codehaus.mojo:build-helper-maven-plugin:jar:1.7:compile
|  +- org.apache.maven:maven-model:jar:2.0.6:compile
|  +- org.apache.maven:maven-project:jar:2.0.6:compile
|  |  +- org.apache.maven:maven-settings:jar:2.0.6:compile
|  |  +- org.apache.maven:maven-profile:jar:2.0.6:compile
|  |  +- org.apache.maven:maven-artifact-manager:jar:2.0.6:compile
|  |  +- org.apache.maven:maven-plugin-registry:jar:2.0.6:compile
|  |  \- org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile
|  +- org.apache.maven:maven-core:jar:2.0.6:compile
|  |  +- org.apache.maven.wagon:wagon-file:jar:1.0-beta-2:runtime
|  |  +- org.apache.maven:maven-plugin-parameter-documenter:jar:2.0.6:compile
|  |  +- org.apache.maven.wagon:wagon-http-lightweight:jar:1.0-beta-2:runtime
|  |  |  +- org.apache.maven.wagon:wagon-http-shared:jar:1.0-beta-2:runtime
|  |  |  \- xml-apis:xml-apis:jar:1.0.b2:runtime
|  |  +- org.apache.maven.reporting:maven-reporting-api:jar:2.0.8:compile
|  |  |  \- org.apache.maven.doxia:doxia-sink-api:jar:1.0-alpha-7:compile
|  |  +- org.apache.maven.wagon:wagon-provider-api:jar:1.0-beta-2:compile
|  |  +- org.apache.maven:maven-repository-metadata:jar:2.0.6:compile
|  |  +- org.apache.maven:maven-error-diagnostics:jar:2.0.6:compile
|  |  +- commons-cli:commons-cli:jar:1.0:compile
|  |  +- org.apache.maven.wagon:wagon-ssh-external:jar:1.0-beta-2:runtime
|  |  |  \- org.apache.maven.wagon:wagon-ssh-common:jar:1.0-beta-2:runtime
|  |  +- org.apache.maven:maven-plugin-descriptor:jar:2.0.6:compile
|  |  +- org.codehaus.plexus:plexus-interactivity-api:jar:1.0-alpha-4:compile
|  |  +- org.apache.maven:maven-monitor:jar:2.0.6:compile
|  |  +- org.apache.maven.wagon:wagon-ssh:jar:1.0-beta-2:runtime
|  |  |  \- com.jcraft:jsch:jar:0.1.27:runtime
|  |  \- classworlds:classworlds:jar:1.1:compile
|  +- org.apache.maven:maven-plugin-api:jar:2.0.6:compile
|  +- org.apache.maven:maven-artifact:jar:2.0.6:compile
|  \- org.codehaus.plexus:plexus-utils:jar:1.5.8:compile
\- org.bsc.maven:maven-processor-plugin:jar:2.0.3:compile
   \- org.jfrog.maven.annomojo:maven-plugin-tools-anno:jar:1.4.0:compile
      +- org.jfrog.maven.annomojo:maven-plugin-anno:jar:1.4.0:compile
      +- org.apache.maven.plugin-tools:maven-plugin-tools-api:jar:2.6:compile
      |  \- jtidy:jtidy:jar:4aug2000r7-dev:compile
      \- com.sun:tools:jar:1.5.0:system

Very strange:

+- net.dwst:generics:jar:1.3.0:compile
|  +- org.swinglabs:swing-layout:jar:1.0.3:compile
|  \- com.sun.codemodel:codemodel:jar:2.4.1:compile

does not contain org.junit, yes this library's pom.xml has:

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.8.2</version>
</dependency>

...

回答1:


If I understand your situation correctly, what you have is two libraries (A and B):

A is the code that calls codemodel. This has a dependency on junit 4.8.2 (compile scope).

B is the code that calls A (the generating code). This has a dependency on junit 4.8.2 (test scope).

B has a dependency on A, obviously.

From Maven Dependency Scope, we have the following line,

Each of the scopes (except for import) affects transitive dependencies in different ways, as is demonstrated in the table below. If a dependency is set to the scope in the left column, transitive dependencies of that dependency with the scope across the top row will result in a dependency in the main project with the scope listed at the intersection. If no scope is listed, it means the dependency will be omitted.

A transitive dependency is one that comes from a direct dependency. So library X depends upon library Y. Library Y depends upon library Z. So Z is a transitive dependency of library X.

In your case, B both directly depends upon junit (with test scope) and has a transitive dependency through A on junit (with compile scope). If we read the table, we can see that this means that the scope that takes precendence is test. This is why your code is failing to find AfterClass.class, because it won't be included.

Your best bet is to set the scope to compile as you have already tried.



来源:https://stackoverflow.com/questions/7373105/noclassdeffounderror-org-junit-afterclass-during-annotation-processing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!