here is an short introduction of how to use slf4j’s logback.xml configuration file within an EAR.
Everybody who uses slf4j (or other Logging Frameworks) knows the following
When you deliver the configuration file of the logging framework within an WAR works everything as expected and without any problems. But if you try this with an EAR something magically happens, the logging framework can’t find the configuration file. And it uses it’s default behavior – System.out.println often by default -.
Searching this issue with Google shows up several possible solutions, for example exchanging the complete logging mechanism of your application server, or put the configuration file into lib/classes (Glassfish). If you dig a little bit deeper you may also find, that you should put the file into a dedicated jar-archive which is deployed as an ordinary library or that you must put the file into the EAR and extend the classpath, via MANIFEST.MF.
The problems of these possible solutions are, when
- exchanging the complete server logging
If you ever update your server, you must ensure, that your modifications weren’t removed and / or were working. If not you must do the manual work again.
- the configuration file is in lib/classes
Works only fine – and without manual work -, when the server isn’t used as a cluster node. Otherwise you must put the file after every single restart, creation, .. again manually.
Additionally you can’t use different log-configuration files for single applications, that includes, that you must edit the single configuration file for every deployed application.
- using the JAR-Archive
Works, but you can’t change the configuration during runtime, because the JAR isn’t exploded.
- using EAR with Class-Path extension
Doesn’t work for us
After doing a little bit research and try-and-error, I could develop this working solution:
- The configuration file is placed in a folder in the EAR, for example config
- Every module uses slf4j-API as a direct dependency. If you put this dependency as a common on into the EAR, the configuration file can’t be found.
- A new module, ‘slf4j’ for example, is introduced and contains, beneath an empty class, an extension of the Class-Path, which points to the folder created above. The empty class is a constraint of the EAR-specification. This module also includes the wished implementation of slf4j.
- Each module which would like to use logging needs now, a dependency to the ‘slf4j’ module.
As usual you’ll find a minimal example on github.
As a last step a little bit
The cause for this issue depends on the way an EAR-Container is handled by the application servers. The servers uses a kind of sandboxing for the classloaders that are available for an EAR. This means, that the way of providing any kind of resource is affected.
The initial classloader of an EAR-container provides only access to resources, that are available outside of the EAR. That means only standard libraries, libraries provided by the server and everything in the <domain|node>/lib-folder.
A direct impact of this way is, that classes that were provided via the EAR/lib directory have only access to resources outside of the EAR. And here is the reason, why SLF4J can’t find the configuration, when it is located in the EAR-container and the SLF4J libraries were put into the EAR/lib folder.
On the other hand, the modules of an EAR have only, direct, access to resources, that can be referenced from within the EAR.