SLF4J - bindings are replaced by other applications on the same application server

My project is packaged as an EAR file containing the SLF4J API (1.7.5), as well as log libraries as its implementation ( logback-core 1.0.13 and logback-classic 1.0.13 ).

When I (used) deploy my project SLF4J LoggerFactory finds the login as a possible binding and uses the correct registrar (i.e. the log).

Now I have a resource connector ( activemq-rar-5.8.0.rar ) that is deployed in front of my own EAR file (since EAR files require RAR). Unfortunately, this RAR contains its own implementation of SLF4J ( slf4j-api-1.6.6.jar slf4j-log4j12-1.6.6.jar log4j-1.2.17.jar ). RAR files use the log4j implementation.

When I deploy my EAR file, the LoggerFactory inside my application code suddenly uses the org.slf4j.impl.Log4jLoggerAdapter implementation ( org.slf4j.impl.Log4jLoggerAdapter ) - although I expected the class path to be separate from the RAR.

This is not like what I am doing wrong (RAR should use log4j, my EAR should use logback)?


Update 1: It doesn't seem like I'm alone , but unfortunately there is no answer.


Update 2:

Accordingly, GlassFish loads the connector module in front of the EAR / WAR files (which are the latest libs downloads).


Update 3:

I managed to fix the "binding": if I put slf4j-api-1.7.5.jar and the log implementation ( logback-core-1.0.13.jar and logback-classic-1.0.13.jar ) in the domains/<myDomain>/lib folder domains/<myDomain>/lib in GlassFish, the login will be used as an implementation of logging (see Update 2 - "Common Classloader" appears before "Connector Classloader").

Unfortunately, my configuration files are no longer found, as they are inside the WAR / EAR, which will later be loaded by another class loader ("Archive Classloader").

So this is not a solution for me, since I would like to save the log configuration files in EAR / WAR (since each application uses a different configuration).


Yours faithfully

stupidSheep

+6
source share
1 answer

Finally, I realized an acceptable solution.

GlassFish loads the connector module before EAR / WAR, see "Update 2". By providing the SLF4J implementation BEFORE loading the connector module, my implemented SLF4J implementation is used.

To do this, I copied the following JARS to the domains/<myDomain>/lib directory (see "Update 3").

  • logback-core-1.0.13.jar
  • logback-classic-1.0.13.jar
  • slf4j-api-1.7.5.jar

Unfortunately, logback no longer found its own configuration file ( logback.xml ), which should be in the class path (as it is, since I packed it inside the JAR).

The solution is to manually configure logback. I did this using the following CDI maker:

 package com.example; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.joran.JoranConfigurator; import ch.qos.logback.core.joran.spi.JoranException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.PostConstruct; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; @ApplicationScoped public class LoggerProducer { @PostConstruct public void initialize() { // The following is logback specific. Unfortunately logback doesn't find its XML configuration // as the logback implementation gets loaded by a different ClassLoader than this code. // See http://docs.oracle.com/cd/E19226-01/820-7695/6niugesfp/index.html#indexterm-28 LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); JoranConfigurator joranConfigurator = new JoranConfigurator(); joranConfigurator.setContext(lc); lc.reset(); try { // The logback configuration is now being loaded from the classpath (by the "Archive Classloader") joranConfigurator.doConfigure(this.getClass().getClassLoader().getResource("logback.xml")); } catch (JoranException e) { e.printStackTrace(); } } @Produces @ApplicationLogger Logger createLogger(InjectionPoint injectionPoint) { return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass()); } } 

This will be the logback setting. Note that I used a special log code for this, so if you change the implementation of SLF4J, you must also change LoggerProducer .

I think logback cannot find its configuration file, since the "Common Classloader" does not have an EAR / WAR on the class path. But later, when the application loads, the "Archive Classloader" has logback.xml in its class path (as provided by the EAR / WAR file), so you can configure logback as soon as everything is in place.

Regards, stupidSheep

+1
source

Source: https://habr.com/ru/post/951296/


All Articles