log4j2 RROR StatusLogger Caught java.lang.AbstractMethodError setting feature...setFeature(Ljava..异常

下午将log4j的版本由2.3升级到了2.9.1,并且改用slf4j接口,而不直接调用log4j2的接口。slf4j的好处有多个:

  • 强制输出String,避免不规范代码。 例如直接调用log4j的方法log.info(obj),obj可以是个对象,但是当这个对象没有重写toString()方法时,则输出的只是hashcode值。强制输出String则可以避免这种情况。
  • 日志模板功能. 例如直接使用log4j的时候经常写这样的代码
    logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
    这引发了两个问题:
    (1)需要编写拼接字符串的代码,使开发效率降低
    (2)即使不需要输出这条日志(比如当前日志级别是ERROR时),也会执行拼接字符串的操作,消耗额外性能,占用额外内存
   而slf4j使用日志模板功能解决了这两个问题:
   
logger.debug("Entry number: {} is {}", i, String.valueOf(entry[i]));
   不仅开发变得简单了,而且slf4j只会在此条日志确实需要输出时才会去拼装字符串。
   并且在输出异常信息时也可以使用模板,不会妨碍stacktrace的输出:
   
String s = "Hello world";
try {
  Integer i = Integer.valueOf(s);
} catch (NumberFormatException e) {
  logger.error("Failed to format {}", s, e);
}

下面问题来了:

  使用的slf4j-api版本是1.7.25,jdk是1.8.0_101, log4j2版本是2.9.1

启动程序报异常:

ERROR StatusLogger Caught java.lang.AbstractMethodError setting feature http://xml.org/sax/features/external-general-entities to false on DocumentBuilderFactory org.apache.xerces.jaxp.DocumentBuilderFactoryImpl@53251a66: java.lang.AbstractMethodError: javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
 java.lang.AbstractMethodError: javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
	at org.apache.logging.log4j.core.config.xml.XmlConfiguration.setFeature(XmlConfiguration.java:213)
	at org.apache.logging.log4j.core.config.xml.XmlConfiguration.disableDtdProcessing(XmlConfiguration.java:205)
	at org.apache.logging.log4j.core.config.xml.XmlConfiguration.newDocumentBuilder(XmlConfiguration.java:194)
	at org.apache.logging.log4j.core.config.xml.XmlConfiguration.(XmlConfiguration.java:92)
	at org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory.getConfiguration(XmlConfigurationFactory.java:46)
	at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:451)
	at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:385)
	at org.apache.logging.log4j.core.config.ConfigurationFactory.getConfiguration(ConfigurationFactory.java:260)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:613)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:634)
	at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:229)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
	at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
	at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:122)
	at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:43)
	at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
	at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
	at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
	at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132)
	at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:655)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:301)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
	at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:549)
	at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
	at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1282)
	at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:518)
	at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:499)
	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
	at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
	at org.mortbay.jetty.Server.doStart(Server.java:224)
	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
	at runjettyrun.Bootstrap.main(Bootstrap.java:97)
ERROR StatusLogger Caught java.lang.AbstractMethodError setting feature http://xml.org/sax/features/external-parameter-entities to false on DocumentBuilderFactory org.apache.xerces.jaxp.DocumentBuilderFactoryImpl@53251a66: java.lang.AbstractMethodError: javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
 java.lang.AbstractMethodError: javax.xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V
	at org.apache.logging.log4j.core.config.xml.XmlConfiguration.setFeature(XmlConfiguration.java:213)
	at org.apache.logging.log4j.core.config.xml.XmlConfiguration.disableDtdProcessing(XmlConfiguration.java:206)
	at org.apache.logging.log4j.core.config.xml.XmlConfiguration.newDocumentBuilder(XmlConfiguration.java:194)
	at org.apache.logging.log4j.core.config.xml.XmlConfiguration.(XmlConfiguration.java:92)
	at org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory.getConfiguration(XmlConfigurationFactory.java:46)
	at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:451)
	at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:385)
	at org.apache.logging.log4j.core.config.ConfigurationFactory.getConfiguration(ConfigurationFactory.java:260)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:613)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:634)
	at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:229)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
	at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
	at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
	at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:122)
	at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:43)
	at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
	at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
	at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
	at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:132)
	at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:655)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:301)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
	at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:549)
	at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
	at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1282)
	at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:518)
	at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:499)
	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
	at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
	at org.mortbay.jetty.Server.doStart(Server.java:224)
	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
	at runjettyrun.Bootstrap.main(Bootstrap.java:97)
出现异常的第一反应是跑去Google问问咋回事,发现Apache log4j2讨论区描述的是这个问题在2.9.0出现了,在2.9.1版本已经解决,可是我用的就是2.9.1版本啊。。。

没办法Google搞不定,第二反应是去调试下代码发现DocumentBuilderFactoryImpl在两个库中有,其中有一个库中的类并没有setFeature这个方法,而代码报异常应该就是进到这个方法了。于是知道应该是jar包冲突导致的这个异常,把这个类的包exclude掉吧  留下jdk中的rt.jar中的com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl,重新编译运行搞定了。

PS:以后遇到问题还是先自己调试下代码吧,看下究竟是哪里出的问题





你可能感兴趣的:(java笔记)