This is a short article explaining how to migrate your Java applications running with Log4j 1.x to Log4j 2.x with special focus on WildFly / JBoss EAP.
Firstly, if you are new to using Log4j 1 and 2 with JBoss EAP and WildFly we recommend checking these articles:
Migration Option 1: Use the Log4j 1.x bridge
This is the simplest option, but it is not recommended for production environments. The Log4j 1.x bridge is a compatibility layer that allows you to use Log4j 1.x configuration files and loggers with Log4j 2. However, it is not as performant as using the Log4j 2 API directly.
Steps:
- Add the Log4j 1.x bridge library to your project. You can do that by replacing the Log4j 1.x jar file with Log4j 2’s log4j-1.2-api.jar
- Set the
log4j1.compatibility
property totrue
in your logging configuration file. - You should now be able to use your existing Log4j 1.x configuration file with Log4j 2.
If you are running WildFly/JBoss in standalone mode, you can set Log4j compatibility in standalone.conf
as follows:
JAVA_OPTS="log4j1.compatibility=true"
Migration Option 2: Convert your application to use Log4j 2 API
This is the more complex option, but it is recommended for production environments. It will give you the best performance and features.
Steps:
- Remove all references to Log4j 1.x in your code. This includes removing the Log4j 1.x library and any references to Log4j 1.x classes or methods.
- Replace your Log4j 1.x configuration file with a Log4j 2 configuration file. There are many different ways to configure Log4j 2, so you will need to find a configuration file format that works for your application.
In terms of packages, the official Log4j guide depicts all the changes you need to apply. As a quick summary, here are they key changes:
Log4j 1.x | Log4j 2.x |
---|---|
Package name: org.apache.log4j | org.apache.logging.log4j |
Calls to org.apache.log4j.Logger.getLogger() | org.apache.logging.log4j.LogManager.getLogger() |
Calls to org.apache.log4j.Logger.getRootLogger() or org.apache.log4j.LogManager.getRootLogger() | org.apache.logging.log4j.LogManager.getRootLogger() |
Calls to org.apache.log4j.Logger.getLogger that accept a LoggerFactory | Remove the org.apache.log4j.spi.LoggerFactory and use one of Log4j 2’s other extension mechanisms |
Calls to org.apache.log4j.Logger.getEffectiveLevel() | org.apache.logging.log4j.Logger.getLevel() |
Calls to org.apache.log4j.LogManager.shutdown() | Not needed in version 2 because the Log4j Core now automatically adds a JVM shutdown hook on start up |
Calls to org.apache.log4j.Logger.setLevel() or similar methods | Not supported at API level. |
String concatenation like logger.info("hi " + userName) | Parameterized messages like logger.info("hi {}", userName) |
Using OpenRewrite recipes to migrate Log4j
You can accelerate the migration to Log4j2 using the OpenRewrite recipes . This recipe does not require extra configuration besides the dependency on org.openrewrite.recipe:rewrite-logging-frameworks:2.2.2 in your build file:
<project> <build> <plugins> <plugin> <groupId>org.openrewrite.maven</groupId> <artifactId>rewrite-maven-plugin</artifactId> <version>5.15.4</version> <configuration> <activeRecipes> <recipe>org.openrewrite.java.logging.log4j.Log4j1ToLog4j2</recipe> </activeRecipes> </configuration> <dependencies> <dependency> <groupId>org.openrewrite.recipe</groupId> <artifactId>rewrite-logging-frameworks</artifactId> <version>2.2.2</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
Which option should I choose?
If you are only migrating your application for testing purposes, then you can use the Log4j 1.x bridge with the log4j1.compatibility
property set to true
. However, if you are migrating your application for production use, then you should convert your application to the Log4j 2 API.
Here is a table summarizing the pros and cons of each option:
Found the article helpful? if so please follow us on Socials