本文轉載自: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 倉庫中引用依賴)。 |
