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:
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">