问题描述
在使用maven进行注释处理期间,我正在使用CodeModel生成代码.该代码用于JUnit测试:
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
但是,编译过程在尝试检索AfterClass.class
时会抛出一个java.lang.NoClassDefFoundError : org/junit/AfterClass
,而该AfterClass.class
本身就是一个注释.
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.
对JUnit的依赖关系定义如下:
The dependency to JUnit is defined as following:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
因此AfterClass.class
应该在我的代码中可用.
so AfterClass.class
should be available in my code.
我该如何解决?
不清楚
调用代码模型的代码在已编译的库中,其中junit不是测试"依赖项.但是,调用生成代码的代码具有相同的junit依赖关系,但具有测试依赖关系.
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?
编辑
这是依赖关系树:
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具有:
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>
...
推荐答案
如果我正确理解您的情况,那么您拥有的是两个库(A和B):
If I understand your situation correctly, what you have is two libraries (A and B):
A是调用codemodel的代码.这依赖于junit 4.8.2(编译范围).
A is the code that calls codemodel. This has a dependency on junit 4.8.2 (compile scope).
B是调用A的代码(生成代码).这依赖于junit 4.8.2(测试范围).
B is the code that calls A (the generating code). This has a dependency on junit 4.8.2 (test scope).
B显然对A有依赖性.
B has a dependency on A, obviously.
从 Maven依赖范围中,我们有以下行,
可传递依赖项是直接依赖项中的一个.因此,库X依赖于库Y.库Y依赖于库Z.因此Z是库X的可传递依赖项.
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.
在您的情况下,B都直接依赖于junit(具有测试范围),并且通过A对junit(具有编译范围)具有传递依赖关系.如果我们阅读该表,可以看到这意味着优先级为 test .这就是为什么您的代码无法找到AfterClass.class的原因,因为它将不包括在内.
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.
这篇关于NoClassDefFoundError:注释处理期间的org/junit/AfterClass的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!