1

我在使用 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

然而,编译过程java.lang.NoClassDefFoundError : org/junit/AfterClass在尝试检索 时会抛出 a ,它AfterClass.class本身就是一个注解。

对 JUnit 的依赖定义如下:

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

所以AfterClass.class应该在我的代码中可用。

我该如何解决这个问题?

不清楚

调用 codemodel 的代码位于 junit 不是“测试”依赖项的编译库中。但是,调用生成代码的代码具有相同的 junit 依赖,但作为测试依赖。

如果我将后一种依赖项更改为“非测试”依赖项,问题就会消失。为什么我必须将此依赖项定义为“not-a-test”,尽管只有调用 codemodel 的库明确使用它?

编辑

这是依赖树:

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>

...
4

1 回答 1

1

如果我正确理解您的情况,您拥有的是两个库(A 和 B):

A是调用codemodel的代码。这依赖于 junit 4.8.2(编译范围)。

B 是调用 A 的代码(生成代码)。这依赖于 junit 4.8.2(测试范围)。

显然,B 依赖于 A。

Maven Dependency Scope,我们有以下行,

每个作用域(导入除外)以不同的方式影响传递依赖关系,如下表所示。如果将依赖项设置为左列中的范围,则该依赖项与顶行范围的传递依赖项将导致主项目中的依赖项具有交叉点列出的范围。如果没有列出范围,则意味着将省略依赖项。

传递依赖是来自直接依赖的依赖。所以库 X 依赖于库 Y。库 Y 依赖于库 Z。所以 Z 是库 X 的传递依赖。

在您的情况下, B 既直接依赖于 junit(具有测试范围),又通过 A 对 junit 具有传递依赖(具有编译范围)。如果我们阅读表格,我们可以看到这意味着优先的范围是test。这就是您的代码无法找到 AfterClass.class 的原因,因为它不会被包含在内。

你最好的选择是设置你已经尝试过的编译范围。

于 2011-09-10T23:37:19.740 回答