2011-09-10 19 views
1

我在使用maven進行註釋處理期間使用CodeModel生成代碼。該代碼是JUnit的測試:NoClassDefFoundError:註釋處理期間的org/junit/AfterClass

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當它試圖獲取AfterClass.class,這是一個註釋本身。

的依賴JUnit的定義如下:

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

所以AfterClass.class應該在我的代碼可用。

如何解決這個問題呢?

不清楚

代碼調用codemodel是在編譯圖書館,JUnit是不是一個「測試」的依賴。但是,調用生成代碼的代碼具有相同的junit依賴性,但是作爲測試依賴性。

如果我將後者依賴項更改爲「不是測試」依賴項,則問題會消失。爲什麼我必須將此依賴性定義爲「不是測試」,儘管只有庫調用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> 

... 
+0

你知道問題是junit類在類路徑中不可用嗎? –

+0

@Thorbjorn是的,但仍然令人困惑(請參閱我的問題中的更新) – JVerstry

+0

您是否檢查過此項目的依賴關係樹?運行mvn依賴項:tree -Dverbose併發布輸出,也許junit版本以某種方式不同。 – mtrovo

回答

1

如果我正確理解你的處境,你擁有的是兩個庫(A和B):

一個是調用codemodel的代碼。這依賴於junit 4.8.2(編譯範圍)。

B是調用A(生成代碼)的代碼。這依賴於junit 4.8.2(測試範圍)。

顯然,B對A有依賴性。

Maven Dependency Scope,我們有以下行,

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.

傳遞依賴是一個來自的直接依賴。所以庫X依賴於庫Y.庫Y依賴於庫Z.所以Z是庫X的傳遞依賴關係。

在你的情況下,B既直接依賴於junit(與測試範圍),並有一個傳遞依賴關於junit(帶編譯範圍)。如果我們讀了表格,我們可以看到這意味着優先的範圍是測試。這就是爲什麼你的代碼無法找到AfterClass。類,因爲它不會被包括在內。

最好的辦法是將範圍設置爲您已經嘗試編譯。

+0

你的解釋是有道理的,但這是我可以從maven想象的最差的選擇,因爲它強制用戶總是手動添加總是在運行時需要的東西。 – JVerstry