今天寫一個項目的時候,我發現我把我需要的JAR都引入進來了呀,爲什麼它還提示ClassNotFoundException呢?
我這樣猜想的:
是不是我沒有這個包啊?
我按照樹形結構找到了這個JAR裏的這個類,哦,原來不是,繼續找別的原因。
我的這個JAR是不是和JDK的版本有衝突啊?
我當時用的是JDK1.7,所以我果斷換了JDK1.6,可是還是不行。
是不是這個JAR依賴了別的JAR?
我用反編譯工具編譯了這個JAR,發現裏面繼承的或引入的包在這個項目裏都能找到。也不是這個原因,那會是什麼呢?
無意中,我把所有的JAR複製到項目的web-inf/lib下,然後一跑程序,唉,成功了,沒有異常了。這是怎麼回事?
通俗的講是和classLoader有關,對於純java項目,它不存在WEB-INF目錄,所以在引入jar包的時候一般都是通過buildpath直接引入,例如我要引入Spring3X,那麼先定義一個user library,然後通過build path引入。
java項目使用的本地自己的JRE,那麼classLoader在加載jar和class時候是分開的,對於我們自己編寫的class,會在 APP_HOME/bin下。導入的jar包或者user library的配置信息會出現在APP_HOME/.classpath文件中,ClassLoader會很智能去加載這些classes和 jar。.classpath文件內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre6"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Spring3.1.0"/>
<classpathentry kind="lib" path="E:/Jar_Framework/cglib/cglib-2.2.2.jar" sourcepath="E:/Jar_Framework/cglib/cglib-src-2.2.2.jar"/>
<classpathentry kind="lib" path="E:/Jar_Framework/commons-logging-1.1.1-bin/commons-logging-1.1.1/commons-logging-1.1.1.jar"/>
<classpathentry kind="lib" path="E:/Jar_Framework/aopalliance-1.0/aopalliance-1.0.jar"/>
<classpathentry kind="lib" path="E:/Jar_Framework/cglib/cglib-nodep-2.2.2.jar"/>
<classpathentry kind="lib" path="E:/Jar_Framework/spring revelant/aspectj-1.6.12.jar"/>
<classpathentry kind="lib" path="E:/Jar_Framework/spring revelant/aspectjweaver-1.6.8.jar"/>
<classpathentry kind="lib" path="E:/Jar_Framework/spring revelant/asm-3.2.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
這樣ClassLoader就會正確的找到所有需要的類。
而對於java web項目,就不一樣了,雖然eclipse的workspace中仍然有.classpath文件,但即使你導入的了自己定義的user library,它也不會出現在.classpath中,這就是問題的關鍵。這到底是爲什麼呢?
對於java web項目,它最終不是通過本地的JRE去運行,而是部署到web 服務器,如Tomcat、Weblogic、WebSphere等,這些服務器都實現了自身的類加載器。
以Tomcat典型結果爲例,它的四組目錄結構common、server、shared、webapps分別對應四個不同的自定義類加載器 CommonClassLoader、CatalinaClassLoader、SharedClassLoader和 WebappClassLoader,WebappClassLoader加載器專門負責加載webapps下面各個web項目的WEB-INF下的類庫。而我們通過user library引入的jar包自然不會被WebappClassLoader加載器加載,所以必然會報ClassNotFoundException。
另外再說一點,導出Excel想要提示的可以加(response.setHeader),要不會直接瀏覽器打開。
response.setHeader("Content-Disposition", "attachment;filename="
+ fileName);
大家調錯誤的時候一定要細心啊,犯了這麼個低級錯誤,以後要注意啦。。。
本文出自 “On My Way” 博客,請務必保留此出處http://shuyangyang.blog.51cto.com/1685768/1020025