【问题标题】:jcl-slf4j and axis 1.4 exception while substituting commons-loggingjcl-slf4j 和轴 1.4 异常同时替换 commons-logging
【发布时间】:2014-11-21 16:10:33
【问题描述】:

我们正在尝试用 jcl-over-slf4j 和 logback 替换 commons-logging + log4j(好的,首先我们将尝试 jcl-over-slf4j 和 log4j)。我们的应用程序在 WAS 8.0 下运行。一旦 commons-logging jar 被删除并被 jcl-over-slf4j、slf4j 和 slf4j-log4j 替换,我们会收到以下错误消息:

[21/11/14 16:12:08:430 CET] 0000006a webapp        E com.ibm.ws.webcontainer.webapp.WebApp commonInitializationFinally SRVE0266E: Se ha producido un error al inicializar los servlets: {0}
                                 javax.servlet.ServletException: SRVE0207E: No se ha detectado la excepción de inicialización creada por el servlet
        at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:404)
        at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.init(ServletWrapperImpl.java:168)
        at com.ibm.ws.webcontainer.servlet.ServletWrapper.loadOnStartupCheck(ServletWrapper.java:1366)
        at com.ibm.ws.webcontainer.webapp.WebApp.doLoadOnStartupActions(WebApp.java:615)
        at com.ibm.ws.webcontainer.webapp.WebApp.commonInitializationFinally(WebApp.java:584)
        at com.ibm.ws.webcontainer.webapp.WebAppImpl.initialize(WebAppImpl.java:421)
        at com.ibm.ws.webcontainer.webapp.WebGroupImpl.addWebApplication(WebGroupImpl.java:88)
        at com.ibm.ws.webcontainer.VirtualHostImpl.addWebApplication(VirtualHostImpl.java:169)
        at com.ibm.ws.webcontainer.WSWebContainer.addWebApp(WSWebContainer.java:749)
        at com.ibm.ws.webcontainer.WSWebContainer.addWebApplication(WSWebContainer.java:634)
        at com.ibm.ws.webcontainer.component.WebContainerImpl.install(WebContainerImpl.java:422)
        at com.ibm.ws.webcontainer.component.WebContainerImpl.start(WebContainerImpl.java:714)
        at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:1164)
        at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectStart(DeployedApplicationImpl.java:1369)
        at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:639)
        at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:967)
        at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:770)
        at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplicationDynamically(ApplicationMgrImpl.java:1361)
        at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:2162)
        at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:446)
        at com.ibm.ws.runtime.component.CompositionUnitImpl.start(CompositionUnitImpl.java:123)
        at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:389)
        at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.access$500(CompositionUnitMgrImpl.java:117)
        at com.ibm.ws.runtime.component.CompositionUnitMgrImpl$1.run(CompositionUnitMgrImpl.java:664)
        at com.ibm.ws.security.auth.ContextManagerImpl.runAs(ContextManagerImpl.java:5468)
        at com.ibm.ws.security.auth.ContextManagerImpl.runAsSystem(ContextManagerImpl.java:5594)
        at com.ibm.ws.security.core.SecurityContext.runAsSystem(SecurityContext.java:255)
        at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.startCompositionUnit(CompositionUnitMgrImpl.java:678)
        at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.startCompositionUnit(CompositionUnitMgrImpl.java:622)
        at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:1251)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:57)
        at sun.reflect.GeneratedMethodAccessor71.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:260)
        at javax.management.modelmbean.RequiredModelMBean$4.run(RequiredModelMBean.java:1141)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
        at javax.management.modelmbean.RequiredModelMBean.invokeMethod(RequiredModelMBean.java:1135)
        at javax.management.modelmbean.RequiredModelMBean.invoke(RequiredModelMBean.java:988)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:835)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:771)
        at com.ibm.ws.management.AdminServiceImpl$1.run(AdminServiceImpl.java:1335)
        at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
        at com.ibm.ws.management.AdminServiceImpl.invoke(AdminServiceImpl.java:1228)
        at com.ibm.ws.management.connector.AdminServiceDelegator.invoke(AdminServiceDelegator.java:181)
        at com.ibm.ws.management.connector.ipc.CallRouter.route(CallRouter.java:247)
        at com.ibm.ws.management.connector.ipc.IPCConnectorInboundLink.doWork(IPCConnectorInboundLink.java:360)
        at com.ibm.ws.management.connector.ipc.IPCConnectorInboundLink$IPCConnectorReadCallback.complete(IPCConnectorInboundLink.java:602)
        at com.ibm.ws.ssl.channel.impl.SSLReadServiceContext$SSLReadCompletedCallback.complete(SSLReadServiceContext.java:1819)
        at com.ibm.ws.tcp.channel.impl.WorkQueueManager.requestComplete(WorkQueueManager.java:558)
        at com.ibm.ws.tcp.channel.impl.WorkQueueManager.attemptIO(WorkQueueManager.java:608)
        at com.ibm.ws.tcp.channel.impl.WorkQueueManager.workerRun(WorkQueueManager.java:985)
        at com.ibm.ws.tcp.channel.impl.WorkQueueManager$Worker.run(WorkQueueManager.java:1074)
        at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1702)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tareaIntegrationLectSolicitNuevasFacturas': Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private es.nexus.facturaelectronica.service.interfaces.integrations.IIntegracionPersistirNuevasFacturas es.nexus.facturaelectronica.service.impl.integrations.IntegrationLectSolicitNuevasFacturas.integracionPersistirNuevasFacturas; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tareaIntegrationPersistirNuevasFacturas' defined in ServletContext resource [/WEB-INF/classes/bean-application-config.xml]: Initialization of bean failed; nested exception is java.lang.ExceptionInInitializerError
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:243)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:959)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:729)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:381)
        at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
        at com.ibm.ws.webcontainer.webapp.WebApp.notifyServletContextCreated(WebApp.java:1686)
        at com.ibm.ws.webcontainer.webapp.WebAppImpl.initialize(WebAppImpl.java:410)
        ... 53 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private es.nexus.facturaelectronica.service.interfaces.integrations.IIntegracionPersistirNuevasFacturas es.nexus.facturaelectronica.service.impl.integrations.IntegrationLectSolicitNuevasFacturas.integracionPersistirNuevasFacturas; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tareaIntegrationPersistirNuevasFacturas' defined in ServletContext resource [/WEB-INF/classes/bean-application-config.xml]: Initialization of bean failed; nested exception is java.lang.ExceptionInInitializerError
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:435)
        at org.springframework.beans.factory.annotation.InjectionMetadata.injectFields(InjectionMetadata.java:105)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:240)
        ... 71 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tareaIntegrationPersistirNuevasFacturas' defined in ServletContext resource [/WEB-INF/classes/bean-application-config.xml]: Initialization of bean failed; nested exception is java.lang.ExceptionInInitializerError
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:221)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:671)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:610)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:412)
        ... 73 more
Caused by: java.lang.ExceptionInInitializerError
        at org.apache.axis.description.TypeDesc.<clinit>(TypeDesc.java:61)
        at es.gob.face.webservice.SRCFFactura.<clinit>(SRCFFactura.java:196)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:171)
        at com.sun.proxy.$Proxy450.<clinit>(Unknown Source)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at java.lang.reflect.Proxy.newInstance(Proxy.java:715)
        at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:706)
        at org.springframework.aop.framework.JdkDynamicAopProxy.getProxy(JdkDynamicAopProxy.java:117)
        at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110)
        at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:488)
        at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:363)
        at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:324)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:361)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1343)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
        ... 84 more
Caused by: org.apache.commons.discovery.DiscoveryException: Class org.apache.commons.logging.impl.LogFactoryImpl does not implement org.apache.commons.logging.LogFactory
        at org.apache.commons.discovery.tools.ClassUtils.verifyAncestory(ClassUtils.java:180)
        at org.apache.commons.discovery.tools.SPInterface.verifyAncestory(SPInterface.java:201)
        at org.apache.commons.discovery.tools.SPInterface.newInstance(SPInterface.java:195)
        at org.apache.commons.discovery.tools.DiscoverClass.newInstance(DiscoverClass.java:579)
        at org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:418)
        at org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:378)
        at org.apache.axis.components.logger.LogFactory$1.run(LogFactory.java:45)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.apache.axis.components.logger.LogFactory.getLogFactory(LogFactory.java:41)
        at org.apache.axis.components.logger.LogFactory.<clinit>(LogFactory.java:33)
        ... 103 more

这一切都以 org.apache.commons.discovery.DiscoveryException 结束:类 org.apache.commons.logging.impl.LogFactoryImpl 没有实现 org.apache.commons.logging.LogFactory 错误信息。

commons-logging 与其 jcl-over-slf4j 替代品之间是否存在某种不兼容? 我们检查了其他一些项目,这似乎是一个常见的模式:axis 1.4 + jcl-over-slf4j = exception。

[注1] 类加载器策略:测试。 为了让 commons-logging 在应用程序级别与 log4j 一起工作,我们已将这些库分配给应用程序(首先我们将它们都声明为“共享库”,我们对 commons-logging.properties 和 log4j.properties 文件执行相同操作, 然后我们将它们全部分配给应用程序,然后我们将应用程序的类加载器策略设置为“Parent Last”。这样,我们强制应用程序加载并使用它自己的 commons-logging 副本,以及它自己的配置文件,因此克服 WAS 中包含的 commons-logging.properties。也就是说,我们尝试了一些“愚蠢”的配置,比如让所有应用程序使用单个应用程序类加载器,或者将 web 模块类加载器策略设置为 Parent Last。这些更改没有任何区别,正如预期的那样。

到目前为止,我们发现了一些令人讨厌的场景:

  1. Axis + WAS 日志记录工具(全部写入 SystemOut):好的,它可以工作, 但我们不希望将所有内容都写入 SystemOut!
  2. Axis + commons-logging + log4j + 他们分配的配置文件 到应用程序类加载器级别的应用程序,policy=Parent 最后的。有些应用程序可以工作,有些则不能(它们显示消息 就像之前引用的一样)。
  3. jcl-over-slf4j + log4j + log4j 的配置文件:结果相同 与此列表的第 2 点相同。

我们现在正在处理的最后一个应用程序,由于前面引用的代码块中的异常而失败的应用程序:我们发现它只在我们使用配置 3(在此列表中)时失败,但它没有失败使用配置 2,这是非常令人惊讶和意想不到的:在之前对其他应用程序的测试中,如果配置 2 配置失败,那么配置 3 也会失败。

[注释1结束]

欢迎任何帮助。

【问题讨论】:

  • 父类加载器策略呢?
  • 我会用 [Note 1] 标签添加一些关于类加载器策略的信息。
  • 是的,我做到了。但是我们正在尝试使用 slf4j 1.7.6,它在 services 目录下包含一个 org.apache.commons.logging.LogFactory 文件。也许有什么东西阻止了 Java 读取这个文件,(例如,如果在任何其他 jar 文件中有另一个同名的文件)......我想我会在库集和跨平台上运行一些 jar tvf,我会在帮助请求中添加注释来解释它。我会及时通知你(这里)。
  • 我已经检查过了,没有更多的 org.apache.commons.logging.LogFactory 出现在任何 jar 文件中,也没有出现在 EAR 或 WAR 中。

标签: java logging axis slf4j


【解决方案1】:

我们这里的设置完全相同:

  • 是 8.0.0.9
  • log4j 用于日志记录
  • EAR 包含 jcl-over-slf4jslf4jslf4j-log4j
  • 轴 1.4
  • 类加载器策略上一个父对象和 WAR 策略应用程序的单个类加载器

一旦轴类被加载,一些静态初始化程序块就会被执行,我们会得到这个异常:

DiscoveryException: Class org.apache.commons.logging.impl.LogFactoryImpl does not implement org.apache.commons.logging.LogFactory

似乎 org.apache.commons.logging.LogFactory 是从 jcl-over-slf4jorg.apache.commons.logging.impl 加载的.LogFactoryImpl 由 WebSphere 提供。

它对我们有用的唯一方法是从我们的 EAR 中删除 jcl-over-slf4j.jar。当然,这样我们可能会丢失一些日志或在 WebSphere SystemOut.log 中找到它们,但至少“它有效”......

【讨论】:

  • 该解决方案的问题在于,如果您不包括 jcl-over-slf4j,那么对 commons-logging 的轴调用将针对 WebSphere 基础架构中包含的 commons-logging 执行。充其量,您将轴日志消息转储到 SystemOut.log 文件中......这是我们试图避免的一件事。我们还在 WAS 管理控制台上为服务器启用了类加载器调试跟踪,因此我们可以确定这个噩梦中涉及 commons-discovery(正如其他论坛中的一些帖子所建议的那样)
  • 我编辑了答案以包含此后果。似乎没有办法让它“运行”并且使用 log4j 进行日志记录也可以工作。我们接受这一点,不会花更多时间寻找解决方案...
  • 就我而言,将 commons-logging-1.0.3 升级到 1.0.4 版似乎可以修复 DiscoveryException
【解决方案2】:

我们遇到了同样的问题。我们的解决方案是告诉 commons-logging 在我们的类加载上下文中使用 slf4j 工厂实现(在我们的例子中是一个 ejb.jar)。

为了实现这一点,我们简单地将 commons-logging.properties 文件添加到我们的 ejb.jar 根文件夹中,其中包含以下内容:

priority=1
org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.SLF4JLogFactory

这解决了我们应用程序中的问题。

【讨论】:

    【解决方案3】:

    也许这可以帮助你。我遇到了类似的问题,并在 SLF4J 文档中找到了解决方案。

    http://slf4j.org/faq.html#excludingJCL

    alternative 2) 提供范围 Commons-logging 可以相当简单并且 通过在提供的声明中方便地将其排除为依赖项 项目的 pom.xml 文件中的范围。实际上 公共日志记录类将由 jcl-over-slf4j 提供。这个 翻译成以下pom文件sn-p:

    <dependency>  
       <groupId>commons-logging</groupId>  
       <artifactId>commons-logging</artifactId>
       <version>1.1.1</version>  
       <scope>provided</scope>
    </dependency> 
    
    <dependency>
       <groupId>org.slf4j</groupId>  
       <artifactId>jcl-over-slf4j</artifactId>
       <version>1.7.21</version>
    </dependency>
    

    第一个依赖声明本质上说 commons-logging 将由您的环境“以某种方式”提供。这 第二个声明将 jcl-over-slf4j 包含到您的项目中。作为 jcl-over-slf4j 是一个完美的二进制兼容替代品 commons-logging,第一个断言变为真。很遗憾, 在提供的范围内声明 commons-logging 得到工作 完成,您的 IDE,例如Eclipse,仍会将 commons-logging.jar 放在 IDE 看到的项目的类路径。你需要做 确保 jcl-over-slf4j.jar 在 commons-logging.jar 之前可见 你的 IDE。

    SLF4J 文档提供了更多选择,这对我有用。

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-29
      • 2017-05-26
      • 2011-08-24
      • 1970-01-01
      相关资源
      最近更新 更多