NoClassDefFoundError:注释处理期间的 org/junit/AfterClass
我在使用 Maven 进行注释处理期间使用 CodeModel 生成代码。该代码用于 JUnit 测试:
JMethod tearDownClass = testClass.method(
JMod.PUBLIC | JMod.STATIC, Void.class, "tearDownClass");
tearDownClass._throws(Exception.class);
tearDownClass.annotate(AfterClass.class); <- java.lang.NoClassDefFoundError
然而,当编译过程尝试检索 AfterClass.class
时,它会抛出 java.lang.NoClassDefFoundError : org/junit/AfterClass
,这本身就是一个注释。
对 JUnit 的依赖定义如下:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
所以 AfterClass.class
应该在我的代码中可用。
我该如何解决这个问题?
不清楚
调用 codemodel 的代码位于编译库中,其中 junit 不是“测试”依赖项。但是,调用生成代码的代码具有相同的 junit 依赖项,但作为测试依赖项。
如果我将后一个依赖项更改为“非测试”依赖项,问题就会消失。为什么我必须将此依赖项定义为“非测试”,尽管只有调用代码模型的库明确使用它?
编辑
这是依赖关系树:
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
非常奇怪:
+- 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
不包含org.junit
,是的,这个库的pom.xml有:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
...
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>
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果我正确理解你的情况,你拥有的是两个库(A和B):
A是调用codemodel的代码。这依赖于 junit 4.8.2(编译范围)。
B 是调用 A 的代码(生成代码)。这依赖于 junit 4.8.2(测试范围)。
显然,B 对 A 有依赖性。
从 Maven 依赖范围,我们有以下内容线,
传递依赖是来自直接依赖的依赖。因此,库 X 依赖于库 Y。库 Y 依赖于库 Z。因此 Z 是库 X 的传递依赖项。
在您的情况下,B 既直接依赖于 junit(具有测试范围),又通过 A 对 junit 具有传递依赖项(具有编译范围)。如果我们阅读该表,我们可以看到这意味着优先的范围是test。这就是为什么您的代码无法找到 AfterClass.class,因为它不会被包含在内。
您最好的选择是按照您已经尝试过的方式设置编译范围。
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,
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.