How to deal with conflicts from application servers
I have a question that is not 100% related to slf4j, but I hope you can give me some advise on something that has never been very clear to me. Or at least I'm not sure what the possibilities are of developing a web application independent of the application server.
Let's say I have a web application (war) that uses the slf4j API. It includes the slf4j-api and logback libraries in WEB-INF/lib. It also includes a logback configuration file. The web application is deployed in a standard Tomcat application server. At that point the web application log output is determined by the bundled logback configuration file. Tomcat will also have its own log files where stuff will be logged regarding starting the application server and anything else not directly coming from the web application.
Now let's say I would like Tomcat to also use slf4j and logback. I add the necessary libraries to Tomcat, let jul bridge to slf4j and add a logback configuration file. When I deploy the same application to this new Tomcat things are going not so well now. SLF4J complains there are multiple bindings, and the logback configuration file of Tomcat is being used instead of the one for the web application.
Things would get even worse if I decided to modify Tomcat to use slf4j-over-log4j.
These conflict from application server libraries to web application libraries really always bothered me, and it becomes really apparent regarding logging. It seems I would need to know exactly which application server I target and what libraries it contains for developing a web application. It means I need to be really careful when configuring the dependency scopes with maven. And it makes it really tricky and time-consuming switching from one application server to another.
How do you deal with this? Is there a way to let Maven easily create different wars for the same web application? One including logging libraries and one without?
Re: How to deal with conflicts from application servers
Am 26.10.2016 um 19:16 schrieb Robert .:
> How do you deal with this?
1) Make two artifacts at different Maven coordinates.
2) Make two artifacts at the same Maven coordinate, using classifiers to
distinguish them. This may run into trouble if some Maven plugin does
not know how to handle classifiers - *most* plugins do, but I would be
surprised if all did.
3) Make *three* artifacts: a standalone main program, a WAR artifact,
and a library artifact that contains the common code. The common code
has a compile-scope dependency on SLF4J, that's all.
4) Use the Spring Boot plugin, which can generate a dual-use "fat jar"
which can run standalone or inside a web container. The fat jar contains
a class loader and a logging backend jar, inside a container the backend
is ignored, standalone the backend's classes are added to the classpath.
(Personally, I think that Spring Boot's fat-jar support alone is totally
worth it, even for projects that do not use Spring and to not run inside
a Java container. YMMV.)