Apache Logging Services
Moving on to Log4j 2: Log4j 1.2 is broken on Java 9
Log4j 1 has had a good run. First released in 1999, it is still widely used in a variety of Java-based projects. With Java 9, that is likely to come to an end: Log4j 1.2 is broken on Java 9. Essentially the MDC depends on the Java version string, which does not play well with Java 9's new version-string format.
The Apache Logging PMC announced in August 2015 that Log4j 1 reached End Of Life and there would be no further releases. The announcement encouraged users to upgrade to its successor, Log4j 2.
What does this mean, concretely? Most of Log4j 1.2 will still work on Java 9. The issue described above is with the MDC (what is now called the ThreadContext map). If you don't use the MDC you may not be impacted, and even if you are impacted this workaround may help.
What has changed is that doing nothing is no longer the safest option. You could endeavor to continue using Log4j 1.2 even on Java 9, but why would you?
If you're not using Log4j 2, this is what you're missing out on:
- Improved reliability. Messages are not lost while reconfiguring the framework like in Log4j 1 or Logback
- Extensibility: Log4j 2 supports a plugin system to let users define and configure custom components
- Simplified configuration syntax, with support for xml, json, yaml and properties configurations
- Improved Filters which can be defined globally or on any configuration element to give you fine-grained control over which log messages should be processed by which Loggers and Appenders.
- Property lookup support for values defined in arbitrary places including, but not limited to, the configuration file, system properties, environment variables, the application container, the ThreadContext Map, and other attributes of the log event
- Support for multiple APIs: Log4j 2 can be used with applications using the Log4j 2, Log4j 1.2, SLF4J, Commons Logging and java.util.logging (JUL) APIs
- Custom Log Levels
- Java 8-style lambda support for "lazy logging"
- Support for user-defined Message objects
- "Garbage-free or low garbage" in common configurations
- Improved speed overall. Worth mentioning especially is the performance of the Asynchronous Loggers. Log4j 2 makes use of the LMAX Disruptor. The library reduces the need for kernel locking and increases the logging performance by a factor 12. For example, in the same environment Log4j 2 can write more than 18,000,000 messages per second, whereas other frameworks like Logback and Log4j 1 just write up to 2,000,000 messages per second.
Log4j 2 has an active and enthusiastic community who would be happy to help out with any migration issues that may come up.
To any project that is interested in running on Java 9, I'd strongly recommend migrating to Log4j 2 now.