1

I need to make SLF4J working inside the WebLogic application. According to Buttso [1] and Oracle [2], one need to copy files into domain/lib directory:

  • slf4j-api
  • slf4j-jdk14-1.6.0.jar

Then define the following handler in logging.property file:

 handlers = weblogic.logging.ServerLoggingHandler

and start WebLogic with following parameter attached.

-Djava.util.logging.config.file=C:\tmp\logging.properties

I understand why the property file must be defined globally. But I don't understand, why JARs must be copied into domain/lib directory of the WebLogic. I tries to leave them inside my WAR file, but it doesn't work.

Is there a way to retain the log libraries under the control of the application? Where is this limitation come from? It is possible to utilize the JDK14 logging infrastructure of the Weblogic directly from the application as:

java.util.logging.Logger LOGGER = java.util.logging.Logger.getLogger("my.logger.Name");
LOGGER.info("JDK14 Anonymous info");

It works as expected. The handler weblogic.logging.ServerLoggingHandler is able to successfully intercept the message and forward it into WSL log file. Why SLF4J bridge is not able to do the same?


[1] Using SLF4J with WebLogic Server Logging http://buttso.blogspot.com/2011/06/using-slf4j-with-weblogic-server.html

[2] How to Redirect SLF4J to the WebLogic Logging System? https://support.oracle.com/epmos/faces/DocumentDisplay?id=1507456.1 (Oracle subscription needed)

30thh
  • 10,861
  • 6
  • 32
  • 42

1 Answers1

1

SHOT DESCRIPTION:

It works perfectly with SLF4J packaged with the application. The important thing is that the API slf4j-api and the implementation slf4j-jdk14 must be loaded by the same classloader.

LONG DESCRIPTION:

By default the Weblogic classloader has a priority. If both libraries (slf4j-api and slf4j-jdk14) are located in domain/lib directory nothing can go wrong.

If slf4j-api is located in the application classpath but NOT in the Weblogic classpath, two things can happen:

  • SLF4J finds some wrong implementation packaged with the application. For example it could be a logback as mandatory dependency of some third party library. In this case the messages will be forwarded into the wrong implementation and they won't reach the WebLogic logging infrastructure.

  • SLF4J finds some implementation inside the WebLogic classpath. In this case the application will be most probably fail to be deployed because of ClassCastException.

As I said, it is possible to have all the SLF4J logging libraries inside the application. For example it is needed, if the WebLogic server is a shared instance and not under your control. Two things are needed to be done:

  • Ensure that only a single SLF4J implementation is packaged with the application. In our case it is slf4j-jdk14. Do maven clean to be sure, all the leftovers from previous tries are removed from WAR file!

  • Enforce the usage of the application classloader for loading the SLF4J library. It is done by WEB-INF/weblogic.xml like this:

    <wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.9/weblogic-web-app.xsd">
        <wls:weblogic-version>14.1.1.0</wls:weblogic-version>
        <wls:context-root>test-oauth</wls:context-root>
        <wls:container-descriptor>
            <wls:prefer-application-packages>
                <wls:package-name>org.slf4j.*</wls:package-name>
            </wls:prefer-application-packages>
        </wls:container-descriptor>
    </wls:weblogic-web-app>
    

Here is a useful example how to find out, which classloader was responsible for a given class or instance.

Which classloader loaded a class of the provided instance

30thh
  • 10,861
  • 6
  • 32
  • 42