java - SLF4J - Bindings are overwritten by other applications on the same application server -
a project of mine packed ear file contains slf4j api (1.7.5) logback libraries implementation (logback-core 1.0.13 , logback-classic 1.0.13).
when (used to) deploy project slf4j's loggerfactory finds logback possible binding , correct logger (i.e. logback) used.
now have resource connector (activemq-rar-5.8.0.rar) deployed before own ear file (as ear files requires rar). unfortunately rar contains own slf4j implementation (slf4j-api-1.6.6.jar slf4j-log4j12-1.6.6.jar log4j-1.2.17.jar). rar files uses log4j implementation.
when deploy ear file loggerfactory inside application's code uses log4j implementation (org.slf4j.impl.log4jloggeradapter) - though expected classpath separated rar.
this doesn't seem case - doing wrong (the rar should use log4j, ear should use logback)?
update 1: it doesn't if alone, unfortunately answer missing..
update 2:
according this table, glassfish loads connector module before ear/war libs (which last libs loaded).
update 3:
i managed fix "binding": if put slf4j-api-1.7.5.jar , logback implementation (logback-core-1.0.13.jar , logback-classic-1.0.13.jar) inside domains/<mydomain>/lib folder in glassfish, logback used logging implementation (see update 2 - "common classloader" comes before "connector classloader").
unfortunately configuration files aren't found anymore inside war/ear - loaded later different classloader ("archive classloader").
so not solution me keep logback configuration files inside ear/war (as every application uses different configuration).
kind regards
stupidsheep
i figured out acceptable solution.
glassfish loads connector module before ear/war, see "update 2". providing slf4j implementation before connector module being loaded, provided slf4j implementation used.
to i've copied following jars directory domains/<mydomain>/lib (see "update 3").
logback-core-1.0.13.jarlogback-classic-1.0.13.jarslf4j-api-1.7.5.jar
unfortunately logback didn't find own configuration file (logback.xml) anymore, must on classpath (which is, packed inside jar).
the solution manually configure logback. i've done using following cdi producer:
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() { // following logback specific. unfortunately logback doesn't find xml configuration // logback implementation gets loaded different classloader 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 { // logback configuration being loaded classpath (by "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 configure logback. please note i've used logback specific code that, if change slf4j implementation must change loggerproducer well.
i think logback doesn't find configuration file "common classloader" doesn't have ear/war on classpath. later, when application loaded, "archive classloader" has logback.xml on classpath (as it's provided ear/war file), it's possible configure logback once in place.
regards stupidsheep
Comments
Post a Comment