How do I setup Java 9 so that System.Logger
instances write to log4j 2.10.0, instead of writing to JUL?
This is the paragraph you refer to:
This release contains the first support of Java 9 as well as bugfixes and minor enhancements. The Log4j API was modified to use
java.util.ServiceLoader
to locate Log4j implementations, although the former binding mechanism is still supported. The Log4j jar is now a multi-release jar to provide implementations of the Java 9 specific classes.
It doesn't mention System.LoggerFinder
and indeed a full-text search of the repo (of version 2.10) didn't turn up any mention of "LoggerFinder" and nothing promising for "java.lang.System". I'm hence sure that Log4J 2.10 does not yet integrate with JEP 264: Platform Logging API and Service.
What the release notes seem to refer to instead is that Log4J now uses the ServiceLoader
API when looking for implementations of its own API.
Do it yourself
If you really need/want Log4J to log these messages, you can roll your own adapter as I did here for SLF4J. All you need are Log4J adapters for System.Logger
and System.LoggerFinder
(both straightforward to implement if you skimp on some of the details) and either a META-INF/services
file or a module declaration like the following:
module org.slf4j.platform {
// put the right module name here
requires log4j;
provides java.lang.System.LoggerFinder
// put the right class name here
with org.log4J.Log4JSystemLoggerFinder;
}
Launching your application with that artifact will then lead to Log4J getting platform log messages.
Log4j 2 supports JDK platform logging since version 2.13.2. If you want to use System.Logger
with Log4j 2 as a backend, you need to use log4j-jpl
adapter:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${replace.with.right.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${replace.with.right.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jpl</artifactId>
<version>${replace.with.right.version}</version>
<scope>runtime</scope>
</dependency>
After that, your System.Logger
will redirect logs to Log4j:
public final class Main {
private static final Logger LOGGER = System.getLogger("");
public static void main(String[] args) {
LOGGER.log(Level.ERROR, "Hello, {}!", "user");
}
}
Output:
11:02:44.736 [main] ERROR - Hello, user!
Why not simply use Log4j2’s Java util logging adapter to route all JUL logging to Log4j2?
To enable this, set system property java.util.logging.manager
to org.apache.logging.log4j.jul.LogManager
and add log4j-jul
to your dependencies.
© 2022 - 2024 — McMap. All rights reserved.
System.Logger
yet. You have to write a service provider manually. – Ellingerjava.util.ServiceLoader
can now locate log4j, andjava.lang.System.LoggerFinder
javadocs say thatjava.util.ServiceLoader
loads the logging implementation… – Soria