Log4j2 - Unable to invoke factory method in class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFileAppender for element RollingFile
问题与分析
在使用Log4j2时,虽然可以正确读取配置文件并生成log文件,但偶然发现控制台打印了异常信息如下:
2018-12-31 17:28:14,282 Log4j2-TF-19-ConfiguratonFileWatcher-6 ERROR Unable to invoke factory method in class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile: java.lang.IllegalStateException: No factory method found for class org.apache.logging.log4j.core.appender.RollingFileAppender java.lang.IllegalStateException: No factory method found for class org.apache.logging.log4j.core.appender.RollingFileAppender
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.findFactoryMethod(PluginBuilder.java:235)
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:135)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:959)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:899)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:891)
at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:514)
at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:238)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:250)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:547)
at org.apache.logging.log4j.core.LoggerContext.onChange(LoggerContext.java:670)
at org.apache.logging.log4j.core.config.ConfiguratonFileWatcher$ReconfigurationRunnable.run(ConfiguratonFileWatcher.java:68)
at java.lang.Thread.run(Thread.java:748)
将控制台的所有信息都复制出来,仔细查找,又发现了相关的异常信息:
2018-12-31 17:28:14,241 Log4j2-TF-19-ConfiguratonFileWatcher-6 ERROR Unable to create file logs/${ctx:domainId}/CNTCore.log java.io.IOException: The filename, directory name, or volume label syntax is incorrect
at java.io.WinNTFileSystem.canonicalize0(Native Method)
at java.io.WinNTFileSystem.canonicalize(WinNTFileSystem.java:428)
at java.io.File.getCanonicalPath(File.java:618)
at ....
2018-12-31 17:28:14,280 Log4j2-TF-19-ConfiguratonFileWatcher-6 ERROR Could not create plugin of type class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile: java.lang.IllegalStateException: ManagerFactory [...] unable to create manager for [logs/${ctx:domainId}/CNTCore.log] with data [...] java.lang.IllegalStateException: ManagerFactory [...] unable to create manager for [logs/${ctx:domainId}/CNTCore.log] with data [...]
at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:115)
at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:114)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.getFileManager(RollingFileManager.java:188)
at ....
看起来是因为配置文件里的RollingFile使用到了${ctx:domainId}导致了这个问题。百度了下,发现了log4j2的jira issue:Unable to invoke factory method in class class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile
该问题和我遇到的一样,而在jira里有comment如下:
Question: Does system property logfile have a value?
结合项目的配置文件log4j2.xml:
<RollingFile name="logfile" immediateFlush="true" fileName="logs/${ctx:domainId}/CNTCore.log"
filePattern="logs/${ctx:domainId}/CNTCore.log.%d{yyyy-MM-dd-a}.gz" append="true">
<PatternLayout>
<pattern>%d %t %p %X{TracingMsg} %c - %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy modulate="true" interval="1" />
</Policies>
</RollingFile>
可以看出,这个异常是由于RollingFile使用到了${ctx:domainId},而该变量值是null,导致无法创建对应的RollingFile文件到磁盘。但是这个domainId是通过ThreadContext把值put进去的,不可能是null,从最终的效果来看,这个变量其实也是拿到了值的,因为对应的日志文件以及存在于磁盘上了。
既然如此,为什么还会出现这个异常呢?通过观察控制台可以发现,每过一段时间就会出现一次该异常。从异常中可以看到ConfiguratonFileWatcher,好像有些明白为什么了。
ConfiguratonFileWatcher是用来扫描配置文件是否被改动过的,在配置文件中设置的扫描间隔是30s:
<configuration monitorInterval="30">
....
</configuration>
由于扫描文件时另外起一个线程去扫描的,而${ctx:domainId}的值是存放于ThreadContext中的,ThreadContext是线程安全的,同一个key对应的value在不同线程中是不一定相同的。而对于新启动的线程来说,并没有将domainId的值存放进去,于是新线程在扫描配置文件的RollingFile时,自然是无法获取到${ctx:domainId}的值,故而每隔一段时间就会报上边的异常。
解决方法
方案一
既然问题是因为扫描配置文件是否改动造成的,那么只要将动态加载的功能关闭就行了,如下:
<configuration monitorInterval="0">
....
</configuration>
方案二
如果希望不关闭动态加载配置文件的功能,可以将domainId的值存放到System.properties里:
System.setProperty("domainId", "xxx");
然后通过${sys:xxx}的方式来获取该properties的值:
<RollingFile name="logfile" immediateFlush="true" fileName="logs/${sys:domainId}/CNTCore.log"
filePattern="logs/${sys:domainId}/CNTCore.log.%d{yyyy-MM-dd-a}.gz" append="true">
<PatternLayout>
<pattern>%d %t %p %X{TracingMsg} %c - %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy modulate="true" interval="1" />
</Policies>
</RollingFile>
在log4j2中关于这些变量取值有以下这些种类:
| Prefix | Context |
|---|---|
| bundle | Resource bundle. The format is ${bundle:BundleName:BundleKey}. The bundle name follows package naming conventions, for example: ${bundle:com.domain.Messages:MyKey}. |
| ctx | Thread Context Map (MDC) |
| date | Inserts the current date and/or time using the specified format |
| env | System environment variables. The formats are ${env:ENV_NAME} and ${env:ENV_NAME:-default_value}. |
| jndi | A value set in the default JNDI Context. |
| jvmrunargs | A JVM input argument accessed through JMX, but not a main argument; see RuntimeMXBean.getInputArguments(). Not available on Android. |
| log4j | Log4j configuration properties. The expressions ${log4j:configLocation} and ${log4j:configParentLocation} respectively provide the absolute path to the log4j configuration file and its parent folder. |
| main | A value set with MapLookup.setMainArguments(String[]) |
| map | A value from a MapMessage |
| sd | A value from a StructuredDataMessage. The key "id" will return the name of the StructuredDataId without the enterprise number. The key "type" will return the message type. Other keys will retrieve individual elements from the Map. |
| sys | System properties. The formats are ${sys:some.property} and ${sys:some.property:-default_value}. |
参考链接
- Unable to invoke factory method in class class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile
- Property Substitution
Log4j2 - Unable to invoke factory method in class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFileAppender for element RollingFile的更多相关文章
- 关于dubbo调度时出现Request processing failed; nested exception is com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method insertTestTb in the service cn.cuibusi.core.service.TestTbService.的解决办法
在用dubbo跨项目调度service时出现如下错误: 错误原因:pojo没有实现序列化 解决方法:在pojo实现序列化接口即可
- mybatis + log4j2 问题 java.lang.NoClassDefFoundError: org/apache/logging/log4j/spi/AbstractLoggerWrapper
root cause java.lang.NoClassDefFoundError: org/apache/logging/log4j/spi/AbstractLoggerWrapper 网上资料比较 ...
- java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.love5/com.example.love5.Main11Activity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.
若有 java.lang.RuntimeException和 java.lang.NullPointerException: Attempt to invoke virtual method 'voi ...
- 4.工厂方法模式(Factory Method)
耦合关系: 动机(Motivation): 在软件系统中,由于需求的变化,"这个对象的具体实现"经常面临着剧烈的变化,但它却有比较稳定的接口. 如何应对这种 ...
- springBoot集成Elasticsearch抛出Factory method 'restHighLevelClient' threw exception; nested exception is java.lang.NoSuchFieldError: IGNORE_DEPRECATIONS
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'restHighLeve ...
- C#面向对象设计模式纵横谈——5.Factory Method 工厂方法模式(创建型模式)
动机 (Motivation) 在软件系统中,经常面临着“某个对象”的创建工作; 由于需求的变化,这个对象经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何应对这种变化?如何提供一种“封装机制” ...
- C#设计模式系列:工厂方法模式(Factory Method)
1. 工厂方法模式简介 1.1 定义 工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法模式是以一个类的实例化延迟到其子类. Factory Method模式用于在不指定待创建 ...
- 小菜学习设计模式(三)—工厂方法(Factory Method)模式
前言 设计模式目录: 小菜学习设计模式(一)—模板方法(Template)模式 小菜学习设计模式(二)—单例(Singleton)模式 小菜学习设计模式(三)—工厂方法(Factory Method) ...
- 浅谈C++设计模式之工厂方法(Factory Method)
为什么要用设计模式?根本原因是为了代码复用,增加可维护性. 面向对象设计坚持的原则:开闭原则(Open Closed Principle,OCP).里氏代换原则(Liskov Substitution ...
随机推荐
- Linux就该这么学--命令集合6(打包压缩文件、文件查询搜索命令)
1.tar命令用于对文件打包压缩或解压:(tar [选项] [文件]) 打包并压缩文件:tar -czvf 压缩包名.tar.gz 文件名 解压并展开压缩包:tar -xzvf 压缩包名.tar.gz ...
- Hexo建站过程总结
Hexo 是一个基于 Node.js 快速.简洁且高效的博客框架,可以将 Markdown 文件快速的生成静态网页,托管在 GitHub Pages 上. 由于原来博客的主机费用问题,我没有办法再在那 ...
- ThinkPHP验证码不现实的处理方法
ThinkPHP测试的时候遇到验证码不显示的问题,主要解决思路如下: 1.php.ini是否开启gd库: 2.页面编码是否一致: 3.检查页面头部信息BOM,这是最主要的,把下面代码复制到根目录下,然 ...
- 管中窥Vue
博客文章链接:管中窥Vue Vue和Angular.React.js的相同点和不同点? 与React的相同: 都使用了Virtual DOM 提供了响应式和组件化的视图组件 将注意力集中保持在核心库, ...
- Retina屏幕下image-set
实现Retina屏幕下图像的显示方法,还特别给我截取了一段代码: .soso .logo .qqlogo { display: block; width: 134px; height: 44px; b ...
- “cannot be resolved to a type” 错误解决方法
(1)jdk不匹配(或不存在) 项目指定的jdk为“jdk1.6.0_18”,而当前eclipse使用的是“jdk1.6.0_22”.需要在BuildPath | Libraries,中做简单调整. ...
- html5--5-9 绘制扇形
html5--5-9 绘制扇形 学习要点 综合运用已经学过的知识绘制一个扇形 矩形的绘制方法 rect(x,y,w,h)创建一个矩形 strokeRect(x,y,w,hx,y,w,h) 绘制矩形(无 ...
- Vue表格数据增删改查及搜索
<div id="app"> <div class="item"> <span class="name"> ...
- ZOJ3496 Assignment
传送门 这题也是真恶心-- 题目大意是俩公司要运货,每条路有容量上限.然后B公司手里有p个--(技能点?)如果在一条路上放了x个技能点,这条路经过了y个货物,那么B公司就会收x*y的钱.现在要求的是, ...
- 如何判断一个for循环执行完毕
在外面一个变量a=arr.leng; 然后就是进行for循环, 在for循环下面进行判断,因为如果结束那么i的值就会>=a;if条件成立的话,可以在里面进行循环完毕要做的操作.