首先要说说Weblogic的classloading的机制(不同的Applicaiton Server,classloading的方式各有不同)。简而言之,weblogic默认情况下采用的是parent first的方式。但这个parent first,是有“讲究”(tricky)的。
1。父类加载器和子类加载器之间的关系类似于Java中,父类和子类之间的对象关系。
2。Weblogic会将所有load到的class缓存到cache中。(子类classloader能看到父类classloader加载到cache中的class)
默认情况下,当我们的应用程序(ear,war)运行时,会先去cache中查找class,如果找不到。就去System Classpath loader 里去找class。如果System Classpath loader里能找到你需要的类,那么不好意思,你在ear和war包里包含的class就没用了。
如果System ClassPath Loader找不到,接下来去ear的class path里找,接着去EJB class path里找,最后到war的class path里找。一旦找到了该类,就会load起这个类,并将该类放入cache中。
上面的描述,没什么奇怪,但需要注意的是下面的情况。当应用程序执行时,classloader需要的类还未在classloader里存在。默认情况下,此时classloader会由上至下从class path里找,也就是说先去System和Application的class path里找,而不是先向war的class path里找。所以,这种情况下,如果application的class path里能找到所需要的class,那么就算war的class path里有同样的class,war里的class是不会被load到的。
假设情况1:(只在webapp里有class A)
No Class A in current class loader cache -> Find System class path (Not found class A) -> Find Application class path (Not found class A) -> Find EJB class path (Not found class A) -> Find WebApp class loader (Found class A)
假设情况2:(在application和webapp里都有class A)
No Class A in current class loader cache -> Find System class path (Not found class A) -> Find Application class path (Found class A)
实际案例:
前几天,有同事用到一个第三方类库wsdl4j.jar,并该类库放在在Webapp的lib目录里。但是系统运行时,总是报类库版本不对的错误。问题就是在于,之前该项目在Application的class path里已经存在该类库了(给其他的war用),而且application class path里的类库和war里用的是不同的版本。
app.ear
|----->lib
|-->wsdl4j.jar
|------>a.war (using wsdl4j.jar in ear/lib)
|------>b.war (using wsdl4j.jar in ear/lib)
|------>c.war (using wsdl4j.jar in war/lib)
|---->WEB-INF
|---->lib
|--->wsdl4j.jar
解决方法:
weblogic提供了一个标签<prefer-web-inf-classes>,这个标签默认是false的,只要设置这个标签为true,就可以让WEB-INF里的类先被load到了。
特殊案例:(当第三方jar和weblogic.jar有冲突)
项目中使用CXF的webservice,CXF里有自己的javax.jws.*实现,而weblogic.jar里也有类似实现,Weblogic启动的时候似乎已经把weblogic.jar里的类都load进所谓的system classpath classloader了,程序在使用javax.jws.*的类时,类已经被system classpath classloader加载了,所以就算使用<prefer-web-inf-classes>标签也没有用。CXF总是用不上自己的javax.jws.*。
解决方法:
根据weblogic的官方文档,只要是在$CLASSPATH里的jar包都会在weblogic启动的时候load起来,存入“system classpath classloader”的cache里,所以程序运行时,classloader先从cache里找class,也就找到weblogic.jar里的javax.jws.*,所以永远不会尝试查找CXF里的javax.jws.*了。weblogic9以后提供了一个新的标签<prefer-application-packages>。用这个新标签能够让应用程序遇到javax.jws.*时,程序会直接到指定的ear的application class loader里找类,而不使用在“system classpath classloader”里的class。
大部分情况下,使用<prefer-web-inf-classes>,应该能解决classloading的问题,在<prefer-web-inf-classes>不生效的时候,就考虑使用<prefer-application-packages>。在网上还有人提到,同时使用这两个标签(一个在weblogic.xml里设,另一个在weblogic-application.xml在设)时,<prefer-web-inf-classes>的配置无效,这个问题还有待考证。
Reference:
http://chang.baidu.com/e_ville/snap/90dd96b459e4b1f74394861f.html
http://e-docs.bea.com/wls/docs100/programming/classloading.html#wp1082452
http://svn.apache.org/repos/asf/webservices/axis2/site/1_4/app_server.html
http://cwiki.apache.org/CXF20DOC/appserverguide.html#AppServerGuide-swappingOracle%257B%257Bwsdl.jar%257D%257Dwith%257B%257Bwsdl4j.jar%257D%257Dand%257B%257Bjaxb.jar%257D%257DAPIwith%257B%257Bjaxbapi2.0.jar%257D%257D
http://way.iteye.com/blog/36056
相关推荐
weblogic weblogic生成的class
weblogic10配置.pdf weblogic10配置.pdf weblogic10配置.pdf weblogic10配置.pdf
WebLogic10安装配置 WebLogic10 & MyEclipse 配置 windows下。
WebLogic10配置部署手册 WebLogic10 配置部署说明书 图文并茂 手把手教程 很好用的
结束weblogic10的部署项目过程。weblogic10是中文版
weblogic日常巡检的方法,包括weblogic8和weblogic10,,如果weblogic中间件出现问题,也可以通过这些地方入手排查。
oralce weblogic 官方文档教程 自己下载了看去吧
Weblogic10静默安装,生成responsefile
主要是webLogic_10的软件介绍、环境部署过程及环境搭建 主要是webLogic_10的软件介绍、环境部署过程及环境搭建
linux系统下安装weblogic10
WebLogic10安装 1.1 配置Domain 1.2 配置Data Source 1.3 部署
WebLogic10 配置 部署 JNDI 数据源
WebLogic10设置虚拟内存大小,帮助使用weblogic部署工程朋友
linux 安装 weblogic10集群 数据源配置 应用发布
weblogic10在linux下创建域步骤,具体到每一步骤的选择
weblogic10 安装
Weblogic10 详细配置及性能优化大全 绝对全面 欢迎收藏
包括weblogic的配置方式 内存大小设置,登录延时设置,线程设置,集群设置等操作步骤。
weblogic10_for_linux安装文档
将应用部署到weblogic10及oracle linux遇到的问题及解决方案