问题描述
我试图在最新的Java 11上运行我的项目.除了特定的文件记录器外,一切都有效.记录在以前的Java版本上正常工作-10、9、8,但在Java 11中不行.
在服务器运行期间,我只看到1个警告:
警告:不支持Sun.Reflect.Reflection.GetCallerClass.这 将影响性能.
这是我的配置:
<Configuration> <Appenders> <RollingFile name="postgresDBLog" fileName="${sys:logs.folder}/postgres.log" filePattern="${sys:logs.folder}/archive/postgres.log.%d{yyyy-MM-dd}"> <PatternLayout> <pattern>%d{HH:mm:ss.SSS} - %msg%n</pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy/> </Policies> </RollingFile> <RollingFile name="workersLog" fileName="${sys:logs.folder}/worker.log" filePattern="${sys:logs.folder}/archive/worker.log.%d{yyyy-MM-dd}"> <PatternLayout> <pattern>%d{HH:mm:ss.SSS} - %msg%n</pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy/> </Policies> </RollingFile> <RollingFile name="statsLog" fileName="${sys:logs.folder}/stats.log" filePattern="${sys:logs.folder}/archive/stats.log.%d{yyyy-MM-dd}"> <PatternLayout> <pattern>%msg%n</pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy/> </Policies> </RollingFile> <RollingFile name="userLog" fileName="${sys:logs.folder}/blynk.log" filePattern="${sys:logs.folder}/archive/blynk.log.%d{yyyy-MM-dd}"> <PatternLayout> <pattern>%d{HH:mm:ss.SSS} %-5level- %msg%n</pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy/> </Policies> </RollingFile> </Appenders> <Loggers> <Logger name="cc.blynk.server.workers" level="debug" additivity="false"> <appender-ref ref="workersLog"/> </Logger> <Logger name="cc.blynk.server.workers.StatsWorker" level="debug" additivity="false"> <appender-ref ref="statsLog"/> </Logger> <Logger name="cc.blynk.server.db" level="debug" additivity="false"> <appender-ref ref="postgresDBLog"/> </Logger> <Logger name="com.zaxxer.hikari" level="OFF" additivity="false"> </Logger> <Logger name="org.asynchttpclient.netty.channel" level="OFF" additivity="false" /> <!-- turn off netty errors in debug mode for native library loading https://github.com/blynkkk/blynk-server/issues/751 --> <Logger name="io.netty" level="INFO" additivity="false" /> <Root> <AppenderRef ref="userLog"/> </Root> </Loggers> </Configuration>
除userLog外,所有记录仪都很好.但是,userLog是空的.
log4j2 version 2.11.1 Ubuntu 16.04.5 LTS java version "11.0.1" 2018-10-16 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)
更新:
将level="info"添加到根级解决问题.
<Root level="info"> <AppenderRef ref="userLog"/> </Root>
但是,在我的项目中,我使用的是基于属性文件设置日志级别的代码.这是一个代码:
private static void changeLogLevel(String level) { Level newLevel = Level.valueOf(level); LoggerContext ctx = (LoggerContext) LogManager.getContext(false); Configuration conf = ctx.getConfiguration(); conf.getLoggerConfig(LogManager.ROOT_LOGGER_NAME).setLevel(newLevel); ctx.updateLoggers(conf); }
似乎这部分不再与Java 11一起使用.
推荐答案
如果有人在使用Maven并在组装平坦的罐子时遇到相同的问题,这是我为解决相同问题所做的工作:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>foo.bar.Generate</mainClass> <manifestEntries> <Multi-Release>true</Multi-Release> </manifestEntries> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers> </configuration> </execution> </executions> </plugin>
重要部分是<Multi-Release>true</Multi-Release>.
请注意,我现在正在使用的Java代码更改记录器级别是:
Configurator.setAllLevels("foo.bar", Level.DEBUG);
其他推荐答案
log4j2当然是兼容的,它使用 更多细节.
但是...
1)首先,当您使用 - 像我一样 - SLF4J接口时,您需要使用其他Maven文物,请参见 http://logging.apache.org/log4j/2.x/log4j-slf4j-impl/index.html
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j18-impl</artifactId> <version>2.12.1</version> </dependency>
添加所有依赖项为" MVN依赖性:树"揭示:
\- org.apache.logging.log4j:log4j-slf4j18-impl:jar:2.12.1:compile [INFO] +- org.slf4j:slf4j-api:jar:1.8.0-alpha2:compile [INFO] +- org.apache.logging.log4j:log4j-api:jar:2.12.1:compile [INFO] \- org.apache.logging.log4j:log4j-core:jar:2.12.1:runtime
2),其次,当您像我一样创建一个单个JAR时,其中包含所有依赖项,您还需要添加多释放清单条目,请参见 https://issues.apache.org/jira/browse/browse/logse/log4j2-2537 或在我的项目的 a>并搜索
<Multi-Release>true</Multi-Release>
其他推荐答案
如果您收到此消息,则您的应用程序未设置用于使用多释放罐子. Log4J通过在位于Meta-Inf/versions/9中的StackLocator中使用StackWalker支持Java 9+.根据应用程序的工作原理,您可能需要在JAR清单中将多元释放设置为true.对于弹簧靴罐来说是正确的.如果没有多释放支持,您将使用java前9版的stackLocator,该版本试图使用reflection.getCallerClass().该课程在Java 9中被删除.Log4j将落回较慢的方法来计算堆栈位置,但仍将起作用.因此警告.
问题描述
I tried to run my project on the latest Java 11. Everything works, except the specific file logger. Logging works fine on previous Java versions - 10, 9, 8, but not on Java 11.
During server run I see only 1 warning:
WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance.
Here is my configuration:
<Configuration> <Appenders> <RollingFile name="postgresDBLog" fileName="${sys:logs.folder}/postgres.log" filePattern="${sys:logs.folder}/archive/postgres.log.%d{yyyy-MM-dd}"> <PatternLayout> <pattern>%d{HH:mm:ss.SSS} - %msg%n</pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy/> </Policies> </RollingFile> <RollingFile name="workersLog" fileName="${sys:logs.folder}/worker.log" filePattern="${sys:logs.folder}/archive/worker.log.%d{yyyy-MM-dd}"> <PatternLayout> <pattern>%d{HH:mm:ss.SSS} - %msg%n</pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy/> </Policies> </RollingFile> <RollingFile name="statsLog" fileName="${sys:logs.folder}/stats.log" filePattern="${sys:logs.folder}/archive/stats.log.%d{yyyy-MM-dd}"> <PatternLayout> <pattern>%msg%n</pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy/> </Policies> </RollingFile> <RollingFile name="userLog" fileName="${sys:logs.folder}/blynk.log" filePattern="${sys:logs.folder}/archive/blynk.log.%d{yyyy-MM-dd}"> <PatternLayout> <pattern>%d{HH:mm:ss.SSS} %-5level- %msg%n</pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy/> </Policies> </RollingFile> </Appenders> <Loggers> <Logger name="cc.blynk.server.workers" level="debug" additivity="false"> <appender-ref ref="workersLog"/> </Logger> <Logger name="cc.blynk.server.workers.StatsWorker" level="debug" additivity="false"> <appender-ref ref="statsLog"/> </Logger> <Logger name="cc.blynk.server.db" level="debug" additivity="false"> <appender-ref ref="postgresDBLog"/> </Logger> <Logger name="com.zaxxer.hikari" level="OFF" additivity="false"> </Logger> <Logger name="org.asynchttpclient.netty.channel" level="OFF" additivity="false" /> <!-- turn off netty errors in debug mode for native library loading https://github.com/blynkkk/blynk-server/issues/751 --> <Logger name="io.netty" level="INFO" additivity="false" /> <Root> <AppenderRef ref="userLog"/> </Root> </Loggers> </Configuration>
All loggers, except userLog works fine. However, userLog is empty.
log4j2 version 2.11.1 Ubuntu 16.04.5 LTS java version "11.0.1" 2018-10-16 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)
Update:
Adding level="info" to the root level fixes the issue.
<Root level="info"> <AppenderRef ref="userLog"/> </Root>
However, in my project I was using a code that was setting a log level based on properties file. Here is a code:
private static void changeLogLevel(String level) { Level newLevel = Level.valueOf(level); LoggerContext ctx = (LoggerContext) LogManager.getContext(false); Configuration conf = ctx.getConfiguration(); conf.getLoggerConfig(LogManager.ROOT_LOGGER_NAME).setLevel(newLevel); ctx.updateLoggers(conf); }
Seems like this part is no longer work with Java 11.
推荐答案
If someone is using Maven and is having the same issue while assembling a flat jar, here is what I did to fix the same issue:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>foo.bar.Generate</mainClass> <manifestEntries> <Multi-Release>true</Multi-Release> </manifestEntries> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers> </configuration> </execution> </executions> </plugin>
The important part is <Multi-Release>true</Multi-Release>.
Note that the Java code I'm using now to change loggers level is:
Configurator.setAllLevels("foo.bar", Level.DEBUG);
其他推荐答案
Log4J2 is of course compatible it uses the JDK Multi-Release feature or in more detail.
BUT...
1) First, when you are using - like me - the slf4j interface, you need to use a different Maven artefact, see http://logging.apache.org/log4j/2.x/log4j-slf4j-impl/index.html
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j18-impl</artifactId> <version>2.12.1</version> </dependency>
which adds all dependencies as 'mvn dependency:tree' reveals:
\- org.apache.logging.log4j:log4j-slf4j18-impl:jar:2.12.1:compile [INFO] +- org.slf4j:slf4j-api:jar:1.8.0-alpha2:compile [INFO] +- org.apache.logging.log4j:log4j-api:jar:2.12.1:compile [INFO] \- org.apache.logging.log4j:log4j-core:jar:2.12.1:runtime
2) And second, when you are creating - like me - one single JAR, which includes all dependencies, you need to add the Multi-Release manifest entry as well, see https://issues.apache.org/jira/browse/LOG4J2-2537 or in my project's pom.xml and search for
<Multi-Release>true</Multi-Release>
其他推荐答案
If you are getting this message then your application is not setup to use multi-release jars. Log4j supports Java 9+ by using Stackwalker in a version of StackLocator that is located in META-INF/versions/9. Depending on how your application works, you may need to have Multi-Release set to true in the jar manifest. This is true for Spring Boot jars. Without multi-release support you will use the pre-Java 9 version of StackLocator which tries to use Reflection.getCallerClass(). That class was removed in Java 9. Log4j will fall back to a slower way to calculate stack locations but it will still work. Hence the warning.