Maven下java.lang.NoClassDefFoundError


本文轉載自:http://blog.csdn.net/qqhjqs/article/details/51491516

使用maven管理web項目中jar包之間的依賴,非常的方便好用,但是有時也會出現問題

項目里用net.sf.json
使用maven配置了以下jar包

jakarta commons-lang 2.5  
jakarta commons-beanutils 1.8.0  
jakarta commons-collections 3.2.1  
jakarta commons-logging 1.1.1  
ezmorph 1.0.6

如果將以上的jar包放在非maven管理的項目里的lib下,不會出現任何問題
但是在maven下,當代碼跑到
JSONObject.from(str)的時候,控制台報錯,錯誤內容如下:

java.lang.NoClassDefFoundError: org/apache/commons/lang/exception/NestableRuntimeException  
    at java.lang.ClassLoader.defineClass1(Native Method)  
    at java.lang.ClassLoader.defineClass(Unknown Source)  
    at java.security.SecureClassLoader.defineClass(Unknown Source)  
    at org.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2496)  
    at org.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:860)  
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1302)  
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1167)  
    at com.iquant.simulated.messaging.StrategyManageTopicListener.processMessage(StrategyManageTopicListener.java:13)  
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)  
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)  
    at java.lang.reflect.Method.invoke(Unknown Source)

剛開始我以為是包沒有下載成功,或者是版本不對,當時按着這個思路,搞了大半天,確定jar包都下載了,版本也都對。
突然想到,將字符串抽出來,在main方法里跑一下,看是否成功,結果和我想的一樣,是成功的,那也就是說在web運行的過程中
"找不到相關的包"
按照這個思路走了下去各種百度各種查。

然后我去tomcate發布目錄下將項目的web-inf里的lib打開
查看里面有沒有包含找不到的包---沒有
然后看了看pom.xml配置文件commons-lang的配置語句

<dependency>  
    <groupId>commons-lang</groupId>  
    <artifactId>commons-lang</artifactId>  
    <version>2.6</version>  
    <scope>provided</scope>  
</dependency></span>  

<scope>provided</scope> 去掉之后成功!

總結了以下,關於maven下的項目,如果出現jar包的問題,應該這樣查

是否下載完整---可以將該jar包坐在的文件,刪除重新下載
是否版本一致---可以全局定義一個version,下載相關使用version
是否被打包---查看tomcat文件下對應項目中的webinf-lib下有沒有對應的jar包,然后在看看pom.xml中是怎樣配置的

maven對jar包使用的范圍有一些規定

即在jar包配置的后面添加<scope>[compile ,provided,runtime,test,system ]</scope>

 

名稱 解釋
compile (編譯范圍) compile是默認的范圍;如果沒有提供一個范圍,那該依賴的范圍就是編譯范圍。
編譯范圍依賴在所有的classpath 中可用,同時它們也會被打包。
provided (已提供范圍) provided 依賴只有在當JDK 或者一個容器已提供該依賴之后才使用。
例如, 如果你開發了一個web 應用,你可能在編譯classpath 中需要
可用的Servlet API 來編譯一個servlet,但是你不會想要在打包好的WAR 
中包含這個Servlet API;這個Servlet API JAR 由你的應用服務器或者servlet
 容器提供。已提供范圍的依賴在編譯classpath (不是運行時)可用。
它們不是傳遞性的,也不會被打包。
runtime (運行時范圍) runtime 依賴在運行和測試系統的時候需要,但在編譯的時候不需要。
比如,你可能在編譯的時候只需要JDBC API JAR,而只有在運行的時候才需要JDBC驅動實現
test (測試范圍) test范圍依賴 在一般的編譯和運行時都不需要,它們只有在測試編譯和測試運行階段可用。
system (系統范圍) system范圍依賴與provided 類似,但是你必須顯式的提供一個對於本地系統中
JAR 文件的路徑。這么做是為了允許基於本地對象編譯,而這些對象是系統類庫
的一部分。這樣的構件應該是一直可用的,Maven 也不會在倉庫中去尋找它。
如果你將一個依賴范圍設置成系統范圍,你必須同時提供一個 systemPath 
元素。注意該范圍是不推薦使用的(你應該一直盡量去從公共或定制的 Maven 倉庫中引用依賴)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM