1. 程式人生 > >java.lang.ClassNotFoundException web專案載入時找不到類

java.lang.ClassNotFoundException web專案載入時找不到類

1.概述

作為一個屌絲程式猿,怎麼能不會配置log4j呢,這樣在控制檯或者日誌檔案中很容易找到程式出BUG的地方。尤其是在控制檯輸出日誌的時候,那叫一個爽啊!

=-=  但是出現了問題,我擦,啟動web的時候spring建立上下文的時候居然會找不到類,我去,檢查了一下jar包,spring.jar   spring-web.jar 都有啊,怎麼會找不到呢,我的jar包是放在web-inf/lib 下的,要是這樣都找不到的話,你要鬧哪樣!

於是急忙網上搜羅了一下,大多人犯得錯誤就是,直接通過build path去新增的jar包,這樣會導致web啟動的時候java.lang.ClassNotFoundException: 

org.springframework.web.context.ContextLoaderListener

java.lang.ClassNotFoundException: org.springframework.web.util.Log4jConfigListener

    為什麼會同時出現這兩種錯誤呢?是應為載入初始化log4j的時候需要使用spring的上下文,由於找不到ContextLoaderListener,所以沒辦法去初始化載入log4j。於是想到是不是因為沒有這個ContextLoaderListener類的jar包啊。感覺看到了光明似的,但是一檢視發現,我去,有啊,有這個包啊!這我就頓時無語了。

    換了個思路,實在不行,俺就新建個專案,然後把所有的東西都搬遷到新專案中,clean了一下專案,clean一下tomcat,最後釋出了一下!T(太)M(萌)D(了)!居然好使了,你們說我能說啥呢?

    雖然我的這種解決之道,很無奈,別說科學,甚至連神學都解釋不了。沒有辦法,Java這東西,大家都懂得,頭天晚上有問題,回家睡一覺,第二天上班居然好了。這尼瑪社麼邏輯!沒有辦法,藉此在這裡吐槽一下。

對於這類問題的規避,還是建議,大家操作的時候要謹慎,不要什麼東西都往專案裡面新增,一定要了解你新增的jar包,你需要什麼jar包,就新增什麼jar包。有時間後新增多了未必有好處。對,你猜對了,jar包衝突也是屌絲程式猿的必修課。

2.解決辦法

我就簡單的總結一下,這種問題的解決方法:

2.1 缺少jar包

對!如果出現ClassNotFoundException這個錯誤,你第一反應就是,缺少jar包,說明你還是個合格的程式猿。一般出現這中情況,50%是出現了缺少jar包的問題。你就可以去調戲一下度娘,問一下,為嘛沒有jar包,缺少了什麼jar包。

 2.2 jar包的位置匯入有問題

我們知道在匯入我們自己定義或者封裝的jar包是一般是通過build  path 來新增一個jar包,但是當我們用這種方法匯入第三方提供的jar時,web project啟動時會出現這種找不到jar的情況。所以此時你需要手動將需要的jar放到web-inf/lib下,然後clean一下專案,重新發布一下,就OK了。

2.3 jar包衝突

有一部分情況會因為jar包衝突或者jar包的版本不對出現問題。剛出現這個問題的時候,我也以為是版本不對發生了衝突,到官網一看,全是最新的jar包啊,應該不存在衝突!

2.4 其他的情況

應對這種位置的情況,膽寒啊,有木有!最好的方法就是嘗試,clean一下專案,重新發布一下。不行的話重啟一下機器(當然這個不用擔心伺服器上,因為伺服器上是沒有eclipse環境的,有的問題在本地開發的時候會碰到而且不好解決的時候,有時候在伺服器上確實好用的)。如果再不行的話,最好的辦法就是新建專案,將檔案逐個遷移到專案中。在重新搞一下就OK了!什麼!還沒搞定,那最後一招了,找你們專案經理或者有經驗的同事幫助吧!

3 Java載入順序

Java虛擬機器是根據Java ClassLoader(類載入器)決定如何載入Class。
系統預設提供了3個ClassLoader 
Root ClassLoader,ClassPath Loader,Ext ClassLoader
我們也可以編寫自己的ClassLoader,去載入特定環境下的Jar檔案。 
能不能載入Jar,載入哪裡的Jar,是由ClassLoader決定的。 
問題可能是 匯入的僅僅是jar包的引用,例如在eclipse中通過build path加進user lib……(類似快捷方式)
這種在Java Application中沒問題,但在web Application中可能會出現找不到類的異常。
在WEB Application中jar包最好放在webroot或webcontent下的lib資料夾內,特別是xml中用到的jar包。

4 log4j的配置

既然牽扯到log4j怎麼能不講它的配置方法搞清楚呢。網上版本眾多,當然你也可以去重新那些載入時的init方法,這裡推薦的是通過web.xml,使用預設的類載入方式去初始化log4j,比較原生態。web.xml如下:
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"id="WebApp_ID"version="2.5">
  3.   <welcome-file-list>
  4.     <welcome-file>login.jsp</welcome-file>
  5.   </welcome-file-list>
  6.   <display-name>springMVC</display-name>
  7.   <servlet>
  8.     <servlet-name>spring</servlet-name>
  9.     <servlet-class>
  10.             org.springframework.web.servlet.DispatcherServlet  
  11.         </servlet-class>
  12.     <load-on-startup>1</load-on-startup>
  13.   </servlet>
  14.   <servlet-mapping>
  15.     <servlet-name>spring</servlet-name>
  16.     <url-pattern>*.do</url-pattern>
  17.   </servlet-mapping>
  18.   <listener>
  19.     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  20.   </listener>
  21.   <context-param>
  22.     <param-name>contextConfigLocation</param-name>
  23.     <param-value>classpath:config/spring/applicationContext.xml</param-value>
  24.   </context-param>
  25.   <!-- log4j配置 -->
  26.  <context-param>
  27.     <param-name>log4jConfigLocation</param-name>
  28.     <param-value>classpath:config/properties/log4j.properties</param-value>
  29. </context-param>
  30.   <!-- log4j監聽器 -->
  31. <listener>
  32.     <listener-class>
  33.         org.springframework.web.util.Log4jConfigListener    
  34.     </listener-class>
  35. </listener><spanstyle="font-family: Arial, Helvetica, sans-serif;"></web-app></span>

對了從上面可以看出我的路徑實在src下的config/properties/log4j.properties中

log4j.properties 檔案如下
  1.  ### set log levels ###  
  2. log4j.rootLogger = debug ,  stdout ,  D ,  E  
  3. ### 輸出到控制檯 ###  
  4. log4j.appender.stdout = org.apache.log4j.ConsoleAppender  
  5. log4j.appender.stdout.Target = System.out  
  6. log4j.appender.stdout.layout = org.apache.log4j.PatternLayout  
  7. log4j.appender.stdout.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{1}:%L - %m%n  
  8. ### 輸出到日誌檔案 ###  
  9. log4j.appender.D = org.apache.log4j.DailyRollingFileAppender  
  10. log4j.appender.D.File = logs/log.log  
  11. log4j.appender.D.Append = true
  12. log4j.appender.D.Threshold = DEBUG ## 輸出DEBUG級別以上的日誌  
  13. log4j.appender.D.layout = org.apache.log4j.PatternLayout  
  14. log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n  
  15. ### 儲存異常資訊到單獨檔案 ###  
  16. log4j.appender.D = org.apache.log4j.DailyRollingFileAppender  
  17. log4j.appender.D.File = logs/error.log ## 異常日誌檔名  
  18. log4j.appender.D.Append = true
  19. log4j.appender.D.Threshold = ERROR ## 只輸出ERROR級別以上的日誌!!!  
  20. log4j.appender.D.layout = org.apache.log4j.PatternLayout  
  21. log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n  
如果想看詳細的配置講解請訪問:http://blog.csdn.net/azheng270/article/details/2173430/             這裡我就不做贅述了。這篇部落格有個錯誤的地方就是
  1. <spanstyle="font-size:18px;">log4j.appender.stdout.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{1}:%L - %m%n     1的左右是沒有空格的,否則會報錯</span>