slf4j-log4j12-1.7.2.jar unwanted dependency - java

I'm working in a multi module maven eap project. Previously it was implemented to use slf4j to use as logging framework. I changed it's logging configuration to use log4j2 as the underlying logging framework (still uses the slf4j). I referred to this document when I do so. But when I build the project and deploy it in jboss I get the following error.
Class path contains multiple SLF4J bindings, Found binding in xxx/lib/log4j-slf4j-impl-2.0.2.jar/org/slf4j/impl/StaticLoggerBinder.class and xxx/lib/slf4j-log4j12-1.7.2.jar/org/slf4j/impl/StaticLoggerBinder.class
P.S: I never add the slf4j-log4j12-1.7.2.jar dependency to pom.xml or in any of sub modules. I have no idea how that dependency is copied in to the lib folder.
Any comments guys ?

Well as it says it means you have indeed several slf4j bindings in your project.
You are right to deal with it now as it can become nasty and hide logs.
You should run
mvn dependency:tree
to see which of your modules adds the dependency to slf4j-log4j12-1.7.2.jar. It is probably that you have a transitive dependency to it.
You problem has in fact several solutions:
you can exclude slf4j-log4j explicitely
you can use the "provided" scope
you can use empty artifacts
I am referring to the following FAQ. It is about excluding commons-logging, but should be the same for you with slf4j-log4j.
When I ran into the same kind of problems, I found solution 2 to be the easiest to set and maintain. But solution 3 should work fine as well.

Related

How can I check if my Java project uses Log4j and which version?

Due to the Log4Shell vulnerability I would like to search and find out if my Java project is implementing Log4j directly or by dependencies, and which version.
I have, for example, projects with these dependency management tools:
Maven project
Apache Ivy project
Old legacy project without any dependency management
How can I do this on these types of dependency management tools?
Details about the vulnerability (including mitigation steps):
CVE-2021-44228
Apache Log4j Security Vulnerabilities
You may run Maven dependency tree from the command line inside your project:
mvn dependency:tree
In the output do a search for log4j. If you find it, it might mean that your project is either directly including log4j, or another dependency is including log4j as a transitive dependency.
If you use Maven and Linux, you can run:
mvn dependency:tree | grep log4j
This will check your dependencies and show results only if you have Log4j as a dependency.
And if it is a transitive dependency, and you want to check the dependency it came from, you can use:
mvn dependency: tree | grep -B20 log4j
It will show 20 lines before Log4j on the screen. If you still can't see the main dependency where it comes from, you can increase from 20 to 50, and so on until you find it.
KKKK
So far I'm satisfied what Syft and Grype provide. These tools list all code dependencies of a given Docker image or a directory containing code - independent of the stack! Easy setup and quick execution.
It's Java-independent though and more generic than your specific question for a Maven-based solution. So it is up to you if it's of use or not.

BOM override order (with overlapping BOMs)

I have a parent POM and a normal Maven project.
Both define BOMs in their dependencyManagement. In some cases, these BOMs may overlap, e.g. both specify a version for log4j.
From my tests it seems that:
For overlapping BOMs in the parent POM, the first one wins, i.e. supplies the version for the artifact.
If a BOM from the child and from the parent overlap, then the version from the BOM in the child wins.
Unfortunately, I did not find any documentation about this.
Am I right and can I rely on this behaviour?
Logging framework traditionally lives "next to" your actual code, so it is a bit unclear how to handle this.
I found that separating the build phase dependencies from the deployment phase dependencies works for me.
The basic idea is that you write the code only requiring a dependency to the API of the logging framework (slf4j used to be a natural choice), and then you have several deployment Maven configurations (one for JBoss, one for WebSphere, one for running in your IDE etc) where you add the dependencies relevant to that deployment.
So my suggestion is to change your codebase accordingly to only have API dependencies for the logging framework, and then create a new Maven project for each actual deployment type. You might also want to bake in deployment specific configuration files if needed.

Avoid getting slf4j from maven

Maven uses slf4j, so as soon as it is launched, it initializes it with its default implementation contained into apache-maven-3.3.9\lib\slf4j-simple-1.7.5.jar and with configuration file defined in apache-maven-3.3.9\conf\logging\simplelogger.properties.
After that it loads the pom file and found my jetty-maven-plugin which launch a webapp. But in this webapp I want to use a different implementation for slf4j, but I can't because slf4j is already initialized.
I understand that maven is mainly a tool for build and not to launch apps, but I can't modify log configuration of apache-maven for each project to get pretty logs for each of them.
Is someone already face this issue and find a way to avoid that?
Note:
run-forked instead run works but in this case I can't no more debug from eclipse so I prefer an another solution.
older version of maven works as 3.0.3 because it didn't used slf4j

OSGi (Karaf) Resolution vs Maven dependencies

In my example below there seems to be a discrepancy / duplication in the required steps in OSGi resolution and Maven dependency support.
I have a jar which is dependent on a external 3rd party jar, in this case time4j.
<dependency>
<groupId>net.time4j</groupId>
<artifactId>time4j-core</artifactId>
<version>4.16</version>
</dependency>
I can then run my simple jar locally by importing the packages and running etc.
When importing into OSGi I have to ensure that this jar is imported first, often using the PAX Wrap Url.
This is ok for 1 jar dependency but what about when there are multiple dependencies. I could use a features.xml file to collect these jars but why? I've already specified them in my pom.xml.
It seems there should be a way for OSGi / Karaf to read the pom.xml dependencies and import these into the container using the PAX Wrap url when needed.
Have I missed something here?
Sorry but your expectations are not in sync with reality.
First of all Maven dependencies are build-time dependencies. That's why you declare dependencies you know to be available in the runtime as provided
<scope>provided</scope>
Neither OSGi nor Karaf can do anything about your build time dependencies.
BUT with OSGi you can make sure your build dependencies are also available in your runtime and don't interfere with other libraries that might be available.
That's why you need to declare your imports and exports etc.
Karaf does help you with some of the dependencies for example with feature files.
If you have a feature definition maven project, all of your compile scope dependencies can be included in one feature file.
BUT, the OSGi resolver only looks at the currently available bundles and nothing more, no connection what so ever to maven, if you want to have some sort of automagic resolving of external dependencies you need to make sure that you have
a) an OBR resolver enabled (this depends on the karaf version you are using, with 4.x it's already included) and
b) an OBR repository at hand, Karaf Cave would be the project to look for in that case, cause it can reside like a proxy on top of a maven repository.

How to find which maven dependencies are missing

I have a web project and a pom.xml file. It has enough dependencies to compile and package but not enough to start the project. In my IDE it's shown that everything is ok, but when a start the application it has errors. When i add external pom.xml from another app, my application launches.
So is there any way i can find out which dependencies are missing and how in future i can determine which dependencies are needed for using this or that?
You can use mvn dependency:analyze for determining which dependencies are used and declared or used and undeclared or unused and declared.
For more information refer to: http://maven.apache.org/plugins/maven-dependency-plugin/analyze-mojo.html.
Hope this helps.
There's no maven command to accomplish this. You need to check which classes are causing NoClassDefFoundError, figure out the dependency (Google) - which JARs they are shipped in, and add them with the runtime scope in your pom.xml.
In web projects specifically you oftentimes compile against servlets or Java EE specification JARs (they would only contain interfaces), but you need actual implementation JARs to be present in runtime. These JARs are typically and presumed to be available in the container you are running in (like Tomcat or JBoss), in this case they would be marked as provided scope in your pom.xml.
You need to check the NoClassDefFoundError in your output logs and add dependencies accordingly.
The best resource to search for missing dependencies is Maven Central Repository
To get a detailed debug log of your build, use -X in the command line.
You can check The dependency tree of your project by following command - mvn dependency:tree. This will only list the information about the deoendencies listed in your pom.xml More on it here
should be able to do it with :
maven dependency resolve

Categories