Using Guava in Weblogic and NoSuchMethodError
Recently I was working on a prototype, servlet based web application, using Google Guava https://code.google.com/p/guava-libraries/ cache library. And used weblogic 12c to host and test the application. During the application context initialization, it stoped and displayed following error.
Caused by: java.lang.NoSuchMethodError: com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor() Lcom/google/common/util/concurrent/ListeningExecutorService
Why now? It ran without error in JBoss 7. Did I accidently changed any code, libraries, or maven build. So I checked the code again and I couldn't find any issues. Why it was failing? after some googling I figured that weblogic was loading a different version of the same class. To figure which library/class was loaded, I used below code:
System.out.println(MoreExecutors.class.getProtectionDomain().getCodeSource().getLocation()); //And it printed different library name which was part of weblogic feature jar file. //
Ok, so even when I packed the latest library in war(lib folder), weblogic was loading its own class since it was part of the system library.
How to override it for my application? After reading the documentation about the class loading order of weblogic, I created the weblogic.xml to use the latest package as shown below:
<?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:weblogic-version>12.1.1</wls:weblogic-version> <wls:context-root>/</wls:context-root> <wls:container-descriptor> <wls:prefer-application-packages> <wls:package-name>com.google.common.*</wls:package-name> </wls:prefer-application-packages> </wls:container-descriptor> </wls:weblogic-web-app>
And updated the maven to include the weblogic.xml in the build and deployed again.
Yes, it ran without error by loading the latest library from the webapp.
Since the weblogic threw the error I was able to find that it was loading an old class instead of packaged jar class. What happens when it loads an old class which doesn't throw error? it becomes a serious issue by executing old logic.