jar包放置在WEB-INF/lib下和通過build path導入的區別是什么?
jar包直接拷貝到WEB-INF/lib下和以userLibrary形式引入的區別?
jar包放置在WEB-INF/lib下和通過build path導入的區別是什么? 問題: 1、web架包找不到 2、maven項目轉變web項目通過 Deployment Assembly把架包添加到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應用服務器,它有其自己的類加載器,根據J2EE的規范去%web-project%/WEB-INF/lib的規范去找相應的lib,這就是為什么我們發布的WEB應用要符合那個格式 以Tomcat典型結果為例,它的目錄結構分別對應四個不同的類加載器,關系如下:
common --- CommonClassLoader
server --- CatalinaClassLoader
shared --- SharedClassLoader
webapps --- WebappClassLoader
我們的 web 應用都是部署到 webapps 目錄下,而WebappClassLoader加載器專門負責加載 webapps 下所有web項目的 WEB-INF 下的類庫和類文件。而我們通過 build path 引入的 jar 包自然不會被 WebappClassLoader 加載器加載,所以才會出現 ClassNotFoundException 。
eclipse引用library 是為了編譯代碼生成WEB-INF/classes里面的class文件使用,使用eclipse j2ee IDE時,會將WEB-INF/lib中所有的lib自動加入到library中 eclipse工程下的library是用來編譯里面的src中java文件的 實際發布到tomcat時,僅僅只復制了WEB-INF/lib里面的jar包,所以出現eclipse可以正常編譯但tomcat運行是找不到類, 如果你是用的eclipse j2ee IDE,你去WorkSpace\.metadata\.plugins\*re\wtpwebapps找到運行時發布的工程就可以明白了 說白了就是用eclipse j2ee IDE開發web的時候,如果是編譯java代碼用到的jar可以作為library引用,如果是框架非java代碼部分用到的jar就必須放在lib下面。
maven 轉變成web項目時經常會出現架包沖突(servlet -api.jar這個架包會和Tomcat中的沖突)但是把項目打成架包就會不由沖突這是怎么解決的呢:
解決的方法是:<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.4</version> <scope>provided</scope> </dependency> 把scope的值填成provided就可以了,意思是在打包時不把這個架包打進去