Weblogic 10.3.5: <prefer-web-inf-classes> in weblogic.xml not working VS. server classpath JAR files

8bitjunkie picture 8bitjunkie · Apr 7, 2014 · Viewed 20.9k times · Source

Weblogic version: 10.3.5

JSF version (interfaces, impl) : Mojarra 2.0.3

I have a JSF EAR application which is made up of a WAR file and a JAR file.

The WAR file contains the following two Maven dependencies:

 <dependency>
        <groupId>javax.faces</groupId>
        <artifactId>jsf-api</artifactId>
        <version>2.0.3</version>
    </dependency>

    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-impl</artifactId>
        <version>2.0.3</version>
    </dependency>

When running, the following code snippet correctly reports the current in-service version of Mojarra as v2.0.3:

public void getMojarraVersion() {
    Package p = FacesContext.class.getPackage();
    System.out.println("Mojarra version: " + p.getImplementationTitle() + " " + p.getImplementationVersion());
}

The weblogic startup log, however reports that a different, far older version provided by the container, is used when the application is started:

INFO: Initializing Sun's JavaServer Faces implementation (1.2_03-b04-FCS) for context '/myApp'

This is despite the following weblogic.xml configuration, deployed alongside the WAR file's web.xml file in WEB-INF, which inverts the classloader:

<?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-web-inf-classes>true</wls:prefer-web-inf-classes>
     </wls:container-descriptor>
</wls:weblogic-web-app>

After a couple of days of digging, I discovered the following two JAR Files are being included in the server classpath:

${WEBLOGIC_HOME}/wlserver_10.3/server/lib/consoleapp/webapp/WEB-INF/lib/jsf-api.jar

${WEBLOGIC_HOME}/wlserver_10.3/server/lib/consoleapp/webapp/WEB-INF/lib/jsf-impl.jar

These files are provided by a vanilla install of Weblogic 10.3.5.

Temporarily removing these two JAR files and restarting the server caused the log to start reporting that the new version is in use:

INFO: Initializing Mojarra 2.0.3 for context '/myApp'

The above evidence therefore demonstrates that Weblogic configuration to subvert the classloader hierarchy does not work for any resources that are provided by the server classpath (i.e. ${WEBLOGIC_HOME}/wlserver_10.3/server/lib) when an application is loaded.

As an interesting aside, I can delete the weblogic.xml file and I find that:

  1. The wrong version of the dependency continues to be reported in the startup log.
  2. The correct version of the dependency continues to be used at runtime.

Answer

Xloon picture Xloon · Aug 31, 2016

Sometime <wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes> can't specify the lib. You need to use: <wls:prefer-application-packages> and <wls:prefer-application-resources>. Below is an example (remove wls: for old weblogic version):

<wls:container-descriptor>
    <wls:prefer-application-packages>
        <wls:package-name>META-INF/services/javax.xml.bind.JAXBContext</wls:package-name>
        <wls:package-name>com.google.common.*</wls:package-name>
        <wls:package-name>org.slf4j.*</wls:package-name>
        <wls:package-name>org.apache.logging.log4j.*</wls:package-name>
    </wls:prefer-application-packages>
    <wls:prefer-application-resources>
        <wls:resource-name>META-INF/services/javax.xml.bind.JAXBContext</wls:resource-name>
        <wls:resource-name>com.google.common.*</wls:resource-name>
        <wls:resource-name>org.slf4j.*</wls:resource-name>
        <wls:resource-name>org.apache.logging.log4j.*</wls:resource-name>
    </wls:prefer-application-resources>
</wls:container-descriptor>

On top of weblogic.xml use 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_2_5.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.2/weblogic-web-app.xsd">