NoClassDefFoundError:注释处理期间的 org/junit/AfterClass

发布于 2024-12-04 02:31:11 字数 5340 浏览 1 评论 0原文

我在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疾风者 2024-12-11 02:31:11

如果我正确理解你的情况,你拥有的是两个库(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,

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文