Prevent Weblogic 12c from using system's slf4j

2019-01-16 13:09发布

问题:

We're building new systen using slf4j as logging facade. When deploying on newly Weblogic 12c, we found this error on console log:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/Oracle/Middleware2/modules/org.slf4j.jdk14_1.6.1.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [zip:/opt/Oracle/Middleware2/user_projects/domains/m3/servers/AdminServer/tmp/_WL_user/test/t030q4/war/WEB-INF/lib/slf4j-log4j12-1.6.4.jar!/org/slf4j/impl/StaticLoggerBinder.class]

after googling, we found that this is just a warning, slf4j will bind first found logger, which in this case is weblogic's system logger framework. Is there any way to make it bind to logging framework in our WAR file? Having <prefer-web-inf-classes> in weblogic.xml does not help

回答1:

The filtering should not be done on classes but on resources, because SLF4J looks for the StaticLoggerBinder.class as a resource and not as a class.

Include this in your weblogic-application.xml as well:

<wls:prefer-application-packages>
    <wls:package-name>org.slf4j.*</wls:package-name>
    <wls:package-name>org.apache.commons.*</wls:package-name>
</wls:prefer-application-packages>

<wls:prefer-application-resources>
    <wls:resource-name>org/slf4j/impl/StaticLoggerBinder.class</wls:resource-name>
</wls:prefer-application-resources>

and your logger will be used instead of the one inside the System ClassLoader.



回答2:

For WAR file you should use prefer-application-packages in weblogic.xml like described in this and this posts.

In your case it will be something like

<?xml version="1.0" encoding="UTF-8"?>
<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/ejb-jar_3_0.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
    <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>


回答3:

We were also having this issue and since we are required to configure the logging using Log4J this was an issue. However, using prefer-application-packages seems to work so far, i.e. putting a weblogic-application.xml file in the META-INF folder of the EAR with the following:

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-application xmlns="http://www.bea.com/ns/weblogic/90" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-application.xsd http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd" >
    <prefer-application-packages>
        <package-name>org.slf4j</package-name>
    </prefer-application-packages>
</weblogic-application>

(ok the specified xmlns is an old one but it works, you may update it if you want, I just took ours and removed the unrelated parts).

We still have the aforementioned warning but it uses Log4J as required. In fact, if you look at the URL specified on the next line in the logs (omitted here in the question), it says:

The warning emitted by SLF4J is just that, a warning. SLF4J will still bind with the first framework it finds on the class path.

So I guess it still uses the normal class-loading mechanism for loading org.slf4j.impl.StaticLoggerBinder, which we actually configured to prefer the one in our EAR (i.e. make it the first on the classpath).

Yet, the warning remains but it works. Fixing the warning would be good but probably not possible without altering WebLogic's provided libraries.



回答4:

I don't believe SLF4J provides a way to force its own version, since it's based on self-discovery in the classpath.

So, if you have administration rights on WebLogic, the simplest solution is to upgrade the SLF4J version of WebLogic to 1.6.4 by updating the file on WebLogic installation folder.

Otherwise, you can try to build an EAR instead of a WAR and follow the recommendations here, although I doubt it will work if prefer-web-inf-classes doesn't work in a WAR.