log4j:ERROR setFile(null,true) call failed.
java.io.FileNotFoundException: /logs/log.txt (No such file or directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:133)
at org.apache.log4j.FileAppender.setFile(FileAppender.java:294)
at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:165)
at org.apache.log4j.DailyRollingFileAppender.activateOptions(DailyRollingFileAppender.java:223)
at org.apache.log4j.config.PropertySetter.activate(PropertySetter.java:307)
at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:172)
at org.apache.log4j.config.PropertySetter.setProperties(PropertySetter.java:104)
at org.apache.log4j.PropertyConfigurator.parseAppender(PropertyConfigurator.java:809)
at org.apache.log4j.PropertyConfigurator.parseCategory(PropertyConfigurator.java:735)
at org.apache.log4j.PropertyConfigurator.configureRootCategory(PropertyConfigurator.java:615)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:502)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:547)
at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:483)
at org.apache.log4j.LogManager.<clinit>(LogManager.java:127)
at org.apache.log4j.Logger.getLogger(Logger.java:104)
at org.apache.commons.logging.impl.Log4JLogger.getLogger(Log4JLogger.java:262)
at org.apache.commons.logging.impl.Log4JLogger.<init>(Log4JLogger.java:108)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.apache.commons.logging.impl.LogFactoryImpl.createLogFromClass(LogFactoryImpl.java:1025)
at org.apache.commons.logging.impl.LogFactoryImpl.discoverLogImplementation(LogFactoryImpl.java:844)
at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:541)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:292)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:269)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:655)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:270)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5118)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5634)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1571)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1561)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
log4j:ERROR Either File or DatePattern options are not set for appender [logfile].
web.xml 产生问题配置:
<context-param>
<param-name>webAppRootPath</param-name>
<param-value>webapp.root</param-value>
</context-param>
<context-param><!-- log4j.properties 配置 -->
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>3000</param-value>
</context-param>
<!--配置监听器 ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- IntrospectorCleanupListener 1、此监听器主要用于解决java.beans.Introspector导致的内存泄漏的问题
2、此监听器应该配置在web.xml中与Spring相关监听器中的第一个位置(也要在ContextLoaderListener的前面) 3、JDK中的java.beans.Introspector类的用途是发现Java类是否符合JavaBean规范如果有的框架或程序用到了Introspector类,那么就会启用一个系统级别的缓存,此缓存会
存放一些曾加载并分析过的JavaBean的引用。当Web服务器关闭时,由于此缓存中存放着这些JavaBean的引用,所以垃圾回收器无法回收Web容器中的JavaBean对象,最后导致
内存变大。而org.springframework.web.util.IntrospectorCleanupListener就是专门用来处理Introspector内存泄漏问题的辅助类。IntrospectorCleanupListener会在
Web服务器停止时清理Introspector缓存,使那些Javabean能被垃圾回收器正确回收。Spring自身不会出现这种问题,因为Spring在加载并分析完一个类之后会马上刷新
JavaBeans Introspector缓存,这就保证Spring中不会出现这种内存泄漏的问题。但有些程序和框架在使用了JavaBeans Introspector之后,没有进行清理工作(如
Quartz,Struts),最后导致内存泄漏 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- IntrospectorCleanupListener -->
<!-- Log4jConfigListener -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- Log4jConfigListener 就是为输出LOG准备的,可以控制台输出、文件、等很多种输出。 这些LOG可以为开发调试、发布后运行的意外调试、等 -->
log4j.properties 配置:
#DEBUG < INFO < WARN < ERROR < FATAL
log4j.rootLogger=DEBUG,console,logfile
#console configure
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[BIKE] %d{yyyy-MM-dd HH:mm:ss} [%5p] (%F:%L) - %m%n
log4j.appender.console.Encoding=UTF-8
#logfile configure
log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logfile.File=${webapp.root}/logs/log.txt
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern= %d %p [%c] - <%m>%n
log4j.appender.logfile.Threshold=INFO
log4j.appender.logfile.Encoding=UTF-8
log4j.logger.freemarker=FATAL
log4j.logger.org.springframework=WARN
log4j.logger.org.mybatis=DEBUG
log4j.logger.net.sf.ehcache=ERROR
解决方法:把
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
移动所以
context-param 之后就行
解决后web.xml配置:
<context-param>
<param-name>webAppRootPath</param-name>
<param-value>webapp.root</param-value>
</context-param>
<context-param><!-- log4j.properties 配置 -->
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>3000</param-value>
</context-param>
<!-- Log4jConfigListener -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- Log4jConfigListener 就是为输出LOG准备的,可以控制台输出、文件、等很多种输出。 这些LOG可以为开发调试、发布后运行的意外调试、等 -->
猜想:
此问题与web.xml加载顺序有关 “context-param -> listener -> filter -> servlet” ;
特别说明 如果在web.xml中已经配置了org.springframework.web.util.Log4jConfigListener这个监听器,
则不需要配置WebAppRootListener了。因为Log4jConfigListener已经包含了WebAppRootListener的功能。
WebAppRootListener要在ApplicationContext的ContextLoaderListener之前, 否则ApplicationContext的bean注入根目录值时会发生无法注入异常