JBOSS日志异常解决方案
JBOSS日志错误解决方案
在JBOSS启动的时候,相信很多人都见到过下面这个日志错误:
[STDERR:152] - log4j:ERROR Could not instantiate class [org.jboss.logging.appender.FileAppender]. [STDERR:152] - java.lang.ClassNotFoundException: org.jboss.logging.appender.FileAppender [STDERR:152] - at java.net.URLClassLoader$1.run(URLClassLoader.java:202) [STDERR:152] - at java.security.AccessController.doPrivileged(Native Method) [STDERR:152] - at java.net.URLClassLoader.findClass(URLClassLoader.java:190) [STDERR:152] - at java.lang.ClassLoader.loadClass(ClassLoader.java:307) [STDERR:152] - at java.lang.ClassLoader.loadClass(ClassLoader.java:248) [STDERR:152] - at java.lang.Class.forName0(Native Method) [STDERR:152] - at java.lang.Class.forName(Class.java:169) [STDERR:152] - at org.apache.log4j.helpers.Loader.loadClass(Loader.java:198) [STDERR:152] - at org.apache.log4j.helpers.OptionConverter.instantiateByClassName(OptionConverter.java:326) [STDERR:152] - at org.apache.log4j.helpers.OptionConverter.instantiateByKey(OptionConverter.java:123) [STDERR:152] - at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:752) [STDERR:152] - at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:735) [STDERR:152] - at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:615) [STDERR:152] - at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:502) [STDERR:152] - at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:547) [STDERR:152] - at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:483) [STDERR:152] - at org.apache.log4j.LogManager.<clinit>(LogManager.java:127) [STDERR:152] - at org.apache.log4j.Logger.getLogger(Logger.java:104) [STDERR:152] - at org.apache.commons.logging.impl.Log4JLogger.getLogger(Log4JLogger.java:289) [STDERR:152] - at org.apache.commons.logging.impl.Log4JLogger.<init>(Log4JLogger.java:109) [STDERR:152] - at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [STDERR:152] - at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) [STDERR:152] - at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) [STDERR:152] - at java.lang.reflect.Constructor.newInstance(Constructor.java:513) [STDERR:152] - at org.apache.commons.logging.impl.LogFactoryImpl.createLogFromClass(LogFactoryImpl.java:1116) [STDERR:152] - at org.apache.commons.logging.impl.LogFactoryImpl.discoverLogImplementation(LogFactoryImpl.java:858) [STDERR:152] - at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:604) [STDERR:152] - at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:336) [STDERR:152] - at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:310) [STDERR:152] - at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:685) [STDERR:152] - at org.apache.hadoop.conf.Configuration.<clinit>(Configuration.java:137) ...... [STDERR:152] - log4j:ERROR Could not instantiate appender named "FILE".
这个其实跟ClassLoader和Log4j的加载顺序有关,大致过程如下:
- Commons-Logging查询LogFactory的实现,这里只能是Log4j(相关顺序参考我的另外一篇博客)
- Log4j通过加载其的ClassLoader去查找log4j.xml文件,详细代码可以查询LogManager的static初始化块
第一步:查询log4j.xml文件,查询的方式是通过Loader.getResource方法,而这个方法里面会一直查询Parent ClassLoader的Resource:
public URL getResource(String name) { URL url; if (parent != null) { url = parent.getResource(name); } else { url = getBootstrapResource(name); } if (url == null) { url = findResource(name); } return url; }
如果你的应用中没有配置log4j.xml,则会继续下一步去查找log4j.properties文件(JBOSS中也没有log4j.xml)
第二步:查询log4j.properties文件,查询方法和上面的一样,通过调试发现最终会找到JBOSS的bin目录中的run.jar中的log4j.properties文件,而其中就是有FILE这个org.jboss.logging.appender.FileAppender,日志出错的原因就在这里。
解决方法:在你的应用中配置log4j.xml,而不是配置log4j.properties文件。