Log4j2/slf4j - Should commons-logging.jar be removed from classpath? - java

My logging dependencies currently look like this:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>2.9.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</dependency>
I noticed that commons-logging.jar is still in my classpath, for some reason. Should I exclude that or doesn't that cause any issues?
I didn't notice any problems so far, but I'm still wondering if that jar would still cause problems somehow.

There are dependencies that use commons-logging. If it's not present, you'll get NoClassDefFoundErrors when they attempt to log. If there were a possibility to have those not even try to use the dependency, it wouldn't be a problem. However that's not very likely.
However, if they use commons-logging but you're using SLF4J, then there's a problem. They're logging in the wrong place (from your point of view). This is where logging bridges come to work. They implement the public API of different logging frameworks, but redirect the logging to what you're using.
For SLF4J there are several bridges (both ways), so instead of bringing in commons-logging, you bring in jcl-over-slf4j. Libraries will think they're using commons-logging, when they're actually using SLF4J (which then uses an actual logging implementation like Logback).
Easy, huh? ;)

Yes, exclude the commons-logging dependency and add the log4j-jcl bridge instead:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
</dependency>
SLF4J API is also redundant because it is already a transitive dependency of the log4j-slf4j-impl binding.

Related

Which slf4j .jar dependency do I need?

I'm getting the following error:
Exception in thread "main" java.lang.NoClassDefFoundError:
org/slf4j/LoggerFactory
I need to include slf4j as a dependency but I'm not sure which jar file to download from https://repo1.maven.org/maven2/org/slf4j/.
I tried org/slf4j/slf4j-api which doesn't work. How do I determine which one is correct?
slf4j is a library that is used as an abstraction of each logging implementation framework such as log4j, logback or Jakarta Commons Logging. If your intent is to use it, you have to also define the concrete framework you want to use under the wood, for example for log4j, your pom dependencies will look like this:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
Depending on the framework you want to use, the dependencies will be a bit different.
This excellent link will give your more details.
SLF4J is a logging API. Combine it with Logback (written by the same people as SLF4J) which implements that logging API:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>runtime</scope>
</dependency>
Find the latest stable versions on mvnrepository.com. Currently logback 1.2.11 and slf4J 1.7.32. Note the the vulnerabilities mentioned on logback 1.2.11 are because of an optional dependency on log4J 1.x (which you don't get automatically, so it's safe to use logback 1.2.11 at the time of writing).

Is it a standard practice to explicitly exclude dependencies?

for example, in my pom.xml
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.15.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.15.0</version>
</dependency>
for some reasons, the dependencies graph is like:
So, there is a conflicting log4j-api (2.7 vs 2.15).
To fix this, I can explicitly exclude log4j-api in the log4j-core dependency. However, is this actually a standard practice since the log4j-api 2.15.0 will always be used anyway due to dependency management.
So first if a app is using log4j-api in version 2.7 this has even not being upgrade for 5 years apart from that I suppose that the api has not being changed (which the api part implies) so you should or could only replace the implementation (log4j-core) and use the more recent version. You can exclude dependencies via the exclusions like this.
<project>
...
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.15.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
This can also being done in dependencyManagement which is even better...In such I would not exclude the api here...

Couldn't understand managed version under Maven dependency hierarchy

In my pom.xml, I have a SikuliX Jar which has a transitive dependency on jna-platform.
As seen in below image, version 4.5.2 has overrided version 5.4.0.
But i dont understand, how this version is overrided as i have not specified any dependency for jna-platform. I had also verified that no any there dependency is fetching this jar.
Please help me understand why this is happening. Any detailed document is well appreciated.
Related dependencies:-
<dependency>
<groupId>com.sikulix</groupId>
<artifactId>sikulixapi</artifactId>
<version>2.0.4</version>
<exclusions>
<exclusion>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
</exclusion>
</exclusions>
</dependency>
Thanks
Since you were using spring boot, as suggested here (there's also the reason of this behaviour):
java.lang.NoClassDefFoundError: com/sun/jna/platform/win32/SspiUtil$ManagedSecBufferDesc #882
you can change your order of dependencies, or specify the exact version, like this:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.4.0</version>
</dependency>
or add this property:
<jna.version>5.4.0</jna.version>

ResolutionException in Java 11

I've started writing a new application in Java 11 and while running the application I got this below error. I read about this issue and looks like it is a case of split package . But I'm not sure how can I fix this issue.
java.lang.module.ResolutionException: Modules slf4j.log4j12 and log4j export package org.apache.log4j to module kubernetes.model.common
I've below dependencies in pom for log4j and slf4j.
log4j
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.26</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.26</version>
</dependency>
log4j2
When I tried to use log4j2 with following dependencies I got different error
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
java.lang.module.ResolutionException: Modules log4j.core and log4j.api export package org.apache.logging.log4j to module java.annotation
slf4j-log4j12 contains a class named org.apache.log4j.MDCFriend.
As I recall this is to fix a bug in log4j 1.x that occurred when the version detection pattern was changed in Java 9. Since Log4j 1.x reached the end of life in August 2015 the bug cannot be fixed there so SLF4J introduced this "fix". Unfortunately, using the org.apache.log4j package outside of the log4j jar is forbidden in the Java module system which is what is causing the problem you are seeing.
Also, note that the security bug CVE-2019-17571 has been created for Log4j 1.x. While your application probably won't be vulnerable to the problem it will show up on security scans.
You have a few options:
Create a bug report against SLF4J and hope that it gets fixed.
Create your own fork of slf4j-log4j12 and fix it yourself.
Upgrade from Log4j 1 to Log4j 2 (the solution I would recommend for a new application).
Use an SLF4J implementation other than Log4j 2.
I encounterd the same error, but when I use log4j-core version 2.13.3 ,the error disappears.

Writing Maven Dependency for javax.persistence

Can someone help me write the dependency for javax.persistence. I have googled it but nothing worked.
I bumped into this page that gives some details on how to write the dependency, but yet i am unable to write it. Can someone help me out?
This is the one for javax.persistence:
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
<scope>provided</scope>
</dependency>
and this is for the whole Java EE 6 stack:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
Edit
Note that I specified a provided scope here, which means that your dependency is available at compile- and test-time, but will not be packaged into your artifacts. This is usually needed if you want to deploy your artifacts in an application server, since they provide their own implementation of the api.
And add this dependency in your pom.xml:
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>
That "Coping with Sun JARs" page might be a little outdated, this JAR is available in the Maven Central Repository
Updated link:
https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api/2.2 is here.
and the maven dependency is as below:
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
For the latest versions javax.persistance is not working instead of that we can use jakarta.persistence to create an entity or resolve the error Cannot resolve symbol 'Entity'. For that need to add the dependency
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.1.6.Final</version>
<type>pom</type>
</dependency>

Categories

Resources