How is l4j ending up on my classpath after maven package? - maven

I have a rest service running on dropwizard. Dropwizard requires slf4j to be configured with logback. When launching this service directly from my maven project in eclipse, the service starts up with the proper logback binding. When I do a maven package with the maven shade plugin, however, the resulting jar is still pulling log4j onto the classpath, which is resulting in slf4j choosing org.slf4j.impl.Log4jLoggerFactory instead of the logback binding.
I have made sure to exclude every transitive instance of log4j in my pom, as well as slf4j-log4j12 (mvn dependency:tree shows neither of these in my hierarchy), yet somehow it still always shows up in my uber jar after running mvn clean package.
How can I figure out what is causing log4j to always exist on my classpath?

Related

How do I instruct Spring Boot Devtools where to find dependencies in a Maven project

I've got a Spring Boot Maven project that creates an executable fat .war. I can run this .war using java -jar without any issues as all dependencies are located within the far .war.
However, I can't run the project with the Spring Boot Devtools using mvn spring-boot:run as it fails to find some dependencies at runtime and throws unhandled exceptions.
For example, we've got an indirect dependency on jaxb-runtime-2.3.1.jar which in turn has a dependency on jaxb-api.2.3.1.jar. Both .jars are present in the fat .war but if I run the project with mvn spring-boot:run it can find jaxb-runtime ok but fails to find jaxb-api with the message:
java.nio.file.NoSuchFileException: ~/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.1/jaxb-api-2.3.1.jar
Note, jaxb-api-2.3.1.jar is present in the maven cache at:
~/.m2/repository/javax/xml/bind/jaxb-api/2.3.1/jaxb-api-2.3.1.jar
however it seems to be looking for it in the same location as the parent jaxb-runtime-2.3.1.jar which is located at:
~/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.1/
There's a long list of similar exceptions that follow this pattern. It's quite a large project but here are some of the versions we're using:
Spring Boot: 2.1.9.RELEASE
spring-boot-maven-plugin: 2.1.9.RELEASE
maven-compiler-plugin: 3.8.1
spring-boot-devtools: not specified in pom
Why does spring-boot:run not locate dependencies in the same way as the maven build? How can I instruct it where to find these dependencies?

removing unwanted jars pom.xml automatically downloads

In my pom.xml ,even though i have not declared a dependency for commons logging and slf4j i can see them being automatically getting downloaded by maven.Is there a way to specify globally in pom.xml for the exclusion of these jars?
This is because your included a dependency in your pom.xml which is dependent on commons logging and sl4j. This is transitive dependency mechanism used by maven.
Go to Dependency Heirarchy Tab in eclipse to find out which dependency is downloading the logging dependencies.
Then you need use the <exclusions>{dependency}</exclusions> to exclude the dependency.
This maven page has good information on how to exclude transitive dependencies.

Maven Plugin log4j logging with slf4j does not log in file

I have an issue with logging in a maven plugin for my applicaton. The maven plugin uses log4j with slf4j as facade, and I have configured (in the plugin) a special file logger for outputs.
When I run my plugin application (local, not as a plugin), the output is written to the file as intended.
However, when I use the maven plugin in another project and build it with mvn clean install, the output is only on the console. It seems not to be a problem of configuration as I do find my logger and (file-)appender.
My assumption is that maven absorbs the slf4j output to display it on its own console. Can anybody confirm or determine this respective tell me how to fix it? I appreciate any help.
It would be helpful to see your actual POM file. However, there are a few potential problems that I know about.This dependency is required because the
The maven-javadoc-plugin:2.10.3 has a dependency on maven-core:2.2.1, which has direct or indirect dependencies on sl4j-nop:1.5.3 and slf4j-jdk14:1.5.6. I introduced a dependency on maven-core:3.3.9, which didn't have this problem. The artifact maven-javadoc-plugin:2.10.3 also has a dependency on log4j:log4j. I placed an exclusion on the dependency for maven-javadoc-plugin so that it didn't include log4j:log4j.
See https://bradleyaross.wordpress.com/2016/05/05/java-logging-frameworks/ and the referenced GitHub libraries, especially the pom.xml files for the parent module and tutorials-common.

maven transitive dependencies lost in jetty:run

I have a largish project that needs to be usable either with a command-line interface or through a web-app. The core server is deployed as 10 separate jars. The web-app is currently deployed as a .war, but that is a huge file that duplicates all the individual deployments and makes updating a module a big pain - you have to re-deploy this huge .war file every time you update anything, and much of the time we don't use the web-app.
So I am trying to deploy a "skinny war", without the dependencies. However, there's no .ear file to carry them, so at runtime, I unpack the skinny war and use jetty:run, with the classesDirectory and webAppSourceDirectory pointing into the unpacked content. That all seems to work. The problem is that the dependencies from the web-app module do not make it into the classpath for jetty:run. When I use jetty:run in the web-app module, the classpath includes all parent, local, and transitive dependencies. But when I use jetty:run in the "distribution" project that depends on the web-app module, the only dependencies that get into the classpath are from the parent module, not from the web-app module. Note that the web-app module is the only local dependency in the distribution module.
What am I missing?
If I'm understanding you correctly, your problem is that Maven doesn't resolve transitive dependencies for war dependencies.

maven classpath order between dependency jars and src/main/resources?

I'm trying to run
mvn exec:java .....
then it uses the runtime classpath defined by my pom, which I think defaults to the compile classpath. the problem is that I found that my src/main/resources/log4j.xml is not reflected, since I put DEBUG logging in the file, but I only see WARN in the output.
I suspect that it's actually the log4j.xml from some of the dependency jars that is being used.
so I need to elevate the src/main/resources/log4j.xml to the front of my compile/runtime classpath. but how do I specify the relative order of src/main/resources vs dependency jars in the classpath?
Thanks
Yang
One workaround is to explicitly specify the log4j.xml that you want log4j to use using a command-line argument.
-Dlog4j.configuration=file:/log4j.xml

Resources