Software development never gets simple. A simple logging in modern Java applications is not simple enough. There are several logging frameworks: java.util.logging, log4j, log4j2, SLF4J, Logback etc. A typical Java application these days brings in one, or more, or even all of these dependencies. It's often a confusion which one is better, which one to use, which one is in action, which one to configure, and how to configure etc. It becomes worse if you need to exclude any.
I was recently working on a task to fix Security Vulnerabilities detected and reported by a commercial SaaS tool that scans Java project codebase and it's dependent libraries. The tool scans and generates a report listing vulnerabilities detected by categorizing each into Critical/High/Medium/Low. Obviously, when there is an unpatched dependent library marked Critical, that draws superior-attention and brings in a worry with the word: "hacking"- a scary or not-scary word in Software Engineering, it depends ;).
This post is NOT about the messy path that Java logging has been going on right from the beginning. It's about dealing with a need to support both log4j (ver 1) and log4j2 (ver 2) in a Java project but want to exclude log4j from the dependency list to fix the security vulnerability reported in reference to the specific vulnerability reported on log4j in the National Vulnerability Database.
To deal with this issue, all you ned to do is exclude log4j from the dependency library that depends on it, and add an explicit dependency of log4j2 and the log4j1-2 bridge.
The following is a snipper of maven pom.xml.
...
<properties>
<log4j.version>2.15.0</log4j.version>
</properties>
<dependencies>
...
<dependency>
<groupId>com.some.lib</groupId>
<artifactId>somelib-need-log4j</artifactId>
<exclusions>
<!--
Fix Security Vulnerability reported with log4j-1.2.17, the last discontinued version of log4j 1.
Exclude log4j 1 and depend on the log4j 1 to 2 bridge and bring in log4j 2 explicitly
-->
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--
Fix Security Vulnerabily reported with log4j-1.2.17
Log4j 1 to 2 bridge to forward log4j 1 calls to 2
-->
<!-- log4j 1 to 2 bridge -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- log4j 2 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
...
</dependencies>
...
TIP
Leverage maven dependency:tree goal to see which dependency's transitive dependencies bring in the library that needs an attention.
mvn dependency:tree
References
- Log4j security vulnerability
- Log4j 2
- Log4j (1.x) - end of life
- Log4j 1.x to 2.x bridge
- Maven Log4j (1.x) dependency - 1.2.17 is the last version, no updates since 2021. Also got moved to org.apache.logging.log4j » log4j-core, this means a package change and requires code changes.
- Maven log4j 1.2 dependencies
- Maven log4j 1 to 2 bridge dependency