Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
log4j2与java11兼容吗?_Java_Log4j2_Java 11 - Fatal编程技术网

log4j2与java11兼容吗?

log4j2与java11兼容吗?,java,log4j2,java-11,Java,Log4j2,Java 11,我试图在最新的Java11上运行我的项目。除了特定的文件记录器之外,其他一切都正常工作。日志记录在以前的Java版本(10、9、8)上运行良好,但在Java11上运行不好 在服务器运行期间,我只看到1条警告: 警告:不支持sun.reflect.Reflection.getCallerClass。这 将影响性能 以下是我的配置: <Configuration> <Appenders> <RollingFile name="postgres

我试图在最新的Java11上运行我的项目。除了特定的文件记录器之外,其他一切都正常工作。日志记录在以前的Java版本(10、9、8)上运行良好,但在Java11上运行不好

在服务器运行期间,我只看到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>
更新:

level=“info”
添加到根级别可以解决此问题

    <Root level="info">
        <AppenderRef ref="userLog"/>
    </Root>

这一部分似乎不再适用于Java 11。

如果您收到此消息,则您的应用程序未设置为使用多版本JAR。Log4j通过在位于META-INF/versions/9中的StackLocator版本中使用Stackwalker来支持Java 9+。根据应用程序的工作方式,您可能需要在jar清单中将Multi-Release设置为true。这对于Spring Boot jar是正确的。如果没有多版本支持,您将使用Java 9之前版本的StackLocator,它尝试使用Reflection.getCallerClass()。该类在Java9中被删除。Log4j将退回到一种较慢的方法来计算堆栈位置,但它仍然可以工作。因此出现了警告。

如果有人在使用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>
这一部分似乎不再适用于Java11

在从JDK 8升级到JDK 11之后,我遇到了同样的问题,即使用LoggerContext以编程方式更新日志级别设置。如果
LogManager.getContext(boolean)
找不到LoggerContext,它将创建并返回一个新实例-更改该新对象将无效。指定Log4j的LogManager类的类加载器修复了本例中的问题:

LoggerContext ctx = (LoggerContext) LogManager.getContext(LogManager.class.getClassLoader(), false);

Log4J2当然是兼容的,它在中使用or

但是

1) 首先,当您像我一样使用slf4j接口时,您需要使用不同的Maven人工制品,请参见

2) 其次,当您像我一样创建一个包含所有依赖项的JAR时,您还需要添加多版本清单条目,请参见 或者在我的项目中搜索

<Multi-Release>true</Multi-Release>
true

此消息来自
org/apache/logging/log4j/util/StackLocator.
它是
log4j2 api.jar
的一部分(或
log4j-api-2.x.y.jar
等)

你得到这个消息是因为一些聪明人决定从JRE中删除
sun.reflect.Reflection.getCallerClass
(猜他们从Herostratus的书中删除了一页或其他内容)。这实际上发生在Openjdk11中

请注意,如果您有一个不太旧的
log4j2 api.jar
,那么您不应该得到这个消息,因为这意味着它包含了另一个针对Java9+的此类实现(
META-INF/versions/9/org/apache/logging/log4j/util/StackLocator.class
),而该类没有给出这个消息


但是,如果您使用一些帮助产品(TM),例如Spring Boot,它有自己的类加载器,它可能不兼容multi-relase jar,因此它会加载与Java8兼容的
StackLocator.class,而不是与Java9+兼容的,您仍然会收到此消息。

您可以使用类名作为字符串来设置和更改日志级别,而不是使用
class

public static MyLogger loggerFor(String name, String logLevel) {
    Configurator.setRootLevel(Level.toLevel(logLevel, Level.INFO));
    return new MyLogger(LogManager.getLogger(name));
  }

您观察到从Java10到Java11的任何变化吗?看起来很奇怪。我没有改变任何东西,相同的jar,相同的环境,不同的JVM。可能是因为
2.11.1
中的更改。您是否可以使用以前版本的log4j(2.11.0)和Java 11进行测试?@nullpointer在JDK 11(2.11.1和2.11.0)上运行我的应用程序时,我可以看到相同的警告。JDK10上没有警告。我的项目很大,所以很难创建一个可复制的示例。“似乎这部分不再适用于Java11。”-警告没有说它不起作用。它说它正在工作。。。慢慢来,谢谢。但是,多版本jar不是必须的。我不需要它,所以我不把它打包成多版本。为什么log4j2无法检查所需的类是否可用,如果可用则继续?依赖舱单有什么意义?这可能是错误的配置或误导。对我来说似乎是log4j2 bug。你说得对,这不是必须的。如果您不关心应用程序的性能会受到影响,并且可以接受警告,那么就没有问题。依赖清单的要点是,这是库支持Java9上多个Java版本的标准方式。如果你不喜欢它的工作方式,恐怕你得和OpenJDK的人谈谈。使用其他方法来确定要使用的正确实现可能会导致其他问题,因为在类路径上为多个java版本构建类可能会导致工具失败。对不起。我还是不明白这个问题。log4j2在运行时可以使用System.getProperty(“java.version”)。我错了吗?是的,你错了。StackWalker API只能使用Java 9+编译器进行编译,并且具有Java 9的类版本号。Log4j的其余部分是为Java7编译的。如果Java 9类与针对Java 7的类位于一起,那么许多工具在遇到该类时都会失败。当它们打包在多版本位置时不会失败,因为在Java9之前这是无效的。所以问题与检测版本无关。啊哈,所以log4j2被打包为multijar。。。这是个坏消息。也许为java7+和java9+提供不同的构建更好、更简单。只是想法,这是我的想法。在我的
log4j2.xml
中有
。同样适用于我。使用Gradle,我将
“Multi-Release”:true
添加到
jar{manifest.attributes
。这修复了我的日志记录问题,但在AWS版本1 jars中与Jackson产生了许多其他问题。在尝试修复它几个小时后,我不得不回滚它。对于Gradle,我做了这个jar{
LoggerContext ctx = (LoggerContext) LogManager.getContext(LogManager.class.getClassLoader(), false);
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j18-impl</artifactId>
<version>2.12.1</version>
</dependency>
\- 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
<Multi-Release>true</Multi-Release>
public static MyLogger loggerFor(String name, String logLevel) {
    Configurator.setRootLevel(Level.toLevel(logLevel, Level.INFO));
    return new MyLogger(LogManager.getLogger(name));
  }