OSGI Bundle和Web容器加载类冲突问题的分析和解决

http://blog.csdn.net/achilles12345/article/details/7260000

 

上面这篇文章解释的算是比较清楚的。我自己遭遇的问题如下(HSF使用了log4j,我自己也使用了log4j,然后问题就来了):

 

  1. 信息: Dual registration of jndi stream handler: factory already defined 
  2. log4j:WARN No appenders could be found for logger (com.taobao.remoting.common). 
  3. log4j:WARN Please initialize the log4j system properly. 
  4. DeployServer started, listen at: 12201 
  5. log4j:ERROR Could not create an Appender. Reported error follows. 
  6. java.lang.ClassCastException: org.apache.log4j.DailyRollingFileAppender cannot b 
  7. e cast to org.apache.log4j.Appender 
  8.         at org.apache.log4j.xml.DOMConfigurator.parseAppender(DOMConfigurator.ja 
  9. va:175) 
  10.         at org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMConfigurat 
  11. or.java:150) 
  12.         at org.apache.log4j.xml.DOMConfigurator.findAppenderByReference(DOMConfi 
  13. gurator.java:163) 
  14.         at org.apache.log4j.xml.DOMConfigurator.parseChildrenOfLoggerElement(DOM 
  15. Configurator.java:425) 
  16.         at org.apache.log4j.xml.DOMConfigurator.parseCategory(DOMConfigurator.ja 
  17. va:345) 
  18.         at org.apache.log4j.xml.DOMConfigurator.parse(DOMConfigurator.java:827) 
  19.         at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java 
  20. :712) 
  21.         at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java 
  22. :618) 
  23.         at org.apache.log4j.xml.DOMConfigurator.configure(DOMConfigurator.java:7 
  24. 43) 
  25.         at com.taobao.config.client.ConfigClientLogger.initialize(ConfigClientMa 
  26. nager.java:52) 
  27.         at com.taobao.config.client.ConfigClientLogger.<clinit>(ConfigClientMana 
  28. ger.java:102) 
  29.         at com.taobao.config.client.SubscriberRegistrar.<clinit>(SubscriberRegis 
  30. trar.java:72) 
  31.         at com.taobao.hsf.model.metadata.component.MetadataComponent.subscriber( 
  32. MetadataComponent.java:106) 
  33.         at com.taobao.hsf.process.component.ProcessComponent.consume(ProcessComp 
  34. onent.java:107) 
  35.         at com.taobao.hsf.app.spring.util.HSFSpringConsumerBean.init(HSFSpringCo 
  36. nsumerBean.java:251) 
  37.         at com.taobao.hsf.app.spring.util.HSFSpringConsumerBean.afterPropertiesS 
  38. et(HSFSpringConsumerBean.java:264) 
  39.         at org.springframework.beans.factory.support.AbstractAutowireCapableBean 
  40. Factory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514) 
  41.         at org.springframework.beans.factory.support.AbstractAutowireCapableBean 
  42. Factory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) 
  43.         at org.springframework.beans.factory.support.AbstractAutowireCapableBean 
  44. Factory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
  45.         at org.springframework.beans.factory.support.AbstractAutowireCapableBean 
  46. Factory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
  47.         at org.springframework.beans.factory.support.AbstractBeanFactory$1.getOb 
  48. ject(AbstractBeanFactory.java:294) 
  49.         at org.springframework.beans.factory.support.DefaultSingletonBeanRegistr 
  50. y.getSingleton(DefaultSingletonBeanRegistry.java:225) 
  51.         at org.springframework.beans.factory.support.AbstractBeanFactory.doGetB 
  52. an(AbstractBeanFactory.java:291) 
  53.         at org.springframework.beans.factory.support.AbstractBeanFactory.getBean 
  54. (AbstractBeanFactory.java:193) 
  55.         at org.springframework.beans.factory.support.DefaultListableBeanFactory. 
  56. preInstantiateSingletons(DefaultListableBeanFactory.java:591) 
  57.         at org.springframework.context.support.AbstractApplicationContext.finish 
  58. BeanFactoryInitialization(AbstractApplicationContext.java:918) 
  59.         at org.springframework.context.support.AbstractApplicationContext.refres 
  60. h(AbstractApplicationContext.java:469) 
  61.         at org.springframework.web.context.ContextLoader.configureAndRefreshWebA 
  62. pplicationContext(ContextLoader.java:383) 
  63.         at org.springframework.web.context.ContextLoader.initWebApplicationConte 
  64. xt(ContextLoader.java:283) 
  65.         at org.springframework.web.context.ContextLoaderListener.contextInitiali 
  66. zed(ContextLoaderListener.java:111) 
  67.         at org.apache.catalina.core.StandardContext.listenerStart(StandardContex 
  68. t.java:3934) 
  69.         at org.apache.catalina.core.StandardContext.start(StandardContext.java:4 
  70. 429) 
  71.         at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045) 
  72.  
  73.         at org.apache.catalina.core.StandardHost.start(StandardHost.java:722) 
  74.         at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045) 
  75.  
  76.         at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443 
  77.         at org.apache.catalina.core.StandardService.start(StandardService.java:5 
  78. 16) 
  79.         at org.apache.catalina.core.StandardServer.start(StandardServer.java:710 
  80.         at org.apache.catalina.startup.Catalina.start(Catalina.java:583) 
  81.         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
  82.         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl. 
  83. java:39) 
  84.         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces 
  85. sorImpl.java:25) 
  86.         at java.lang.reflect.Method.invoke(Method.java:597) 
  87.         at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288) 
  88.         at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413) 
  89. log4j:ERROR Could not parse url [bundleresource://2/configclient.log4j.xml]. 
  90. java.lang.NullPointerException 
  91.         at java.util.Hashtable.put(Hashtable.java:394) 
  92.         at org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMConfigurat 
  93. or.java:151) 
  94.         at org.apache.log4j.xml.DOMConfigurator.findAppenderByReference(DOMConfi 
  95. gurator.java:163) 
  96.         at org.apache.log4j.xml.DOMConfigurator.parseChildrenOfLoggerElement(DOM 
  97. Configurator.java:425) 
  98.         at org.apache.log4j.xml.DOMConfigurator.parseCategory(DOMConfigurator.ja 
  99. va:345) 
  100.         at org.apache.log4j.xml.DOMConfigurator.parse(DOMConfigurator.java:827) 
  101.         at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java 
  102. :712) 
  103.         at org.apache.log4j.xml.DOMConfigurator 
  104. .doConfigure(DOMConfigurator.java 
  105. :618) 
  106.         at org.apache.log4j.xml.DOMConfigurator.configure(DOMConfigurator.java:7 
  107. 43) 
  108.         at com.taobao.config.client.ConfigClientLogger.initialize(ConfigClientMa 
  109. nager.java:52) 
  110.         at com.taobao.config.client.ConfigClientLogger.<clinit>(ConfigClientMana 
  111. ger.java:102) 
  112.         at com.taobao.config.client.SubscriberRegistrar.<clinit>(SubscriberRegis 
  113. trar.java:72) 
  114.         at com.taobao.hsf.model.metadata.component.MetadataComponent.subscriber( 
  115. MetadataComponent.java:106) 
  116.         at com.taobao.hsf.process.component.ProcessComponent.consume(ProcessComp 
  117. onent.java:107) 
  118.         at com.taobao.hsf.app.spring.util.HSFSpringConsumerBean.init(HSFSpringCo 
  119. nsumerBean.java:251) 
  120.         at com.taobao.hsf.app.spring.util.HSFSpringConsumerBean.afterPropertiesS 
  121. et(HSFSpringConsumerBean.java:264) 
  122.         at org.springframework.beans.factory.support.AbstractAutowireCapableBean 
  123. Factory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514) 
  124.         at org.springframework.beans.factory.support.AbstractAutowireCapableBean 
  125. Factory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) 
  126.         at org.springframework.beans.factory.support.AbstractAutowireCapableBean 
  127. Factory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
  128.         at org.springframework.beans.factory.support.AbstractAutowireCapableBean 
  129. Factory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
  130.         at org.springframework.beans.factory.support.AbstractBeanFactory$1.getOb 
  131. ject(AbstractBeanFactory.java:294) 
  132.         at org.springframework.beans.factory.support.DefaultSingletonBeanRegistr 
  133. y.getSingleton(DefaultSingletonBeanRegistry.java:225) 
  134.         at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBe 
  135. an(AbstractBeanFactory.java:291) 
  136.         at org.springframework.beans.factory.support.AbstractBeanFactory.getBean 
  137. (AbstractBeanFactory.java:193) 
  138.         at org.springframework.beans.factory.support.DefaultListableBeanFactory. 
  139. preInstantiateSingletons(DefaultListableBeanFactory.java:591) 
  140.         at org.springframework.context.support.AbstractApplicationContext.finish 
  141. BeanFactoryInitialization(AbstractApplicationContext.java:918) 
  142.         at org.springframework.context.support.AbstractApplicationContext.refres 
  143. h(AbstractApplicationContext.java:469) 
  144.         at org.springframework.web.context.ContextLoader.configureAndRefreshWebA 
  145. pplicationContext(ContextLoader.java:383) 
  146.         at org.springframework.web.context.ContextLoader.initWebApplicationConte 
  147. xt(ContextLoader.java:283) 
  148.         at org.springframework.web.context.ContextLoaderListener.contextInitiali 
  149. zed(ContextLoaderListener.java:111) 
  150.         at org.apache.catalina.core.StandardContext.listenerStart(StandardContex 
  151. t.java:3934) 
  152.         at org.apache.catalina.core.StandardContext.start(StandardContext.java:4 
  153. 429) 
  154.         at org.apache.catalina.core.C 
  155. ontainerBase.start(ContainerBase.java:1045) 
  156.  
  157.         at org.apache.catalina.core.StandardHost.start(StandardHost.java:722) 
  158.         at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045) 
  159.  
  160.         at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443 
  161.         at org.apache.catalina.core.StandardService.start(StandardService.java:5 
  162. 16) 
  163.         at org.apache.catalina.core.StandardServer.start(StandardServer.java:710 
  164.         at org.apache.catalina.startup.Catalina.start(Catalina.java:583) 
  165.         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
  166.         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl. 
  167. java:39) 
  168.         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces 
  169. sorImpl.java:25) 
  170.         at java.lang.reflect.Method.invoke(Method.java:597) 
  171.         at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288) 
  172.         at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413) 
  173. [2012-12-14 10:07:52,121] [main] WARN  com.mchange.v2.c3p0.management.ActiveMana 
  174. gementCoordinator  - A C3P0Registry mbean is already registered. This probably m 
  175. eans that an application using c3p0 was undeployed, but not all PooledDataSource 
  176. s were closed prior to undeployment. This may lead to resource leaks over time. 
  177. Please take care to close all PooledDataSources. 
  178. 2012-12-14 10:07:53 org.apache.coyote.http11.Http11Protocol start 
  179. 信息: Starting Coyote HTTP/1.1 on http-8080 
  180. 2012-12-14 10:07:53 org.apache.jk.common.ChannelSocket init 
  181. 信息: JK: ajp13 listening on /0.0.0.0:8009 
  182. 2012-12-14 10:07:53 org.apache.jk.server.JkMain start 
  183. 信息: Jk running ID=0 time=0/16  config=null 
  184. 2012-12-14 10:07:53 org.apache.catalina.startup.Catalina start 
  185. 信息: Server startup in 6509 ms 

 核心指示是这一句:

 

  1. java.lang.ClassCastException: org.apache.log4j.DailyRollingFileAppender cannot b 
  2. e cast to org.apache.log4j.Appender 

 

根源就是org.apache.log4j.DailyRollingFileAppender的一个实例无法转换成org.apache.log4j.Appender,

虽然,这两个类存在是子-父关系,但是,DailyRollingFileAppender的实例所对应的类与org.apache.log4j.Appender不是由同一个类加载器加载,这就导致无法转型。

注意,具体分析的话,需要调试,把类的加载器给弄出来,才能真正搞清楚。因为,因为当前类的上下文加载器是可以被更换的,所以,产生冲突的情形会更复杂,需要具体场景具体分析。

至于为什么会产生转型,多半是将对象放入了某个容器,然后不同的上下文将容器中的实例取出来,这个时候就会发生转型失败。因为类型是兼容的,所以,编译器无法把关。只有在运行时才会报错。

    稍微提一下,淘宝的HSF在反序列化时,可以访问应用自身的类,那是因为HSF使用web context classloader来载入这样的实体类,反序列化后,返回给HSF消费者。这时可以确保和消费者是同一个类的加载器加载,所以,就不再会发生转型失败。