Today I had to POC a Jersey REST application deployed on a Websphere Application Server 6.1.
At first I had the now classic Hibernate / Jersey exception related to asm dependency :
The thing is :
At first I had the now classic Hibernate / Jersey exception related to asm dependency :
[13/12/12 14:36:32:296 CET] 00000033 ServletWrappe E SRVE0100E: Exception init() non intercept?e par le servlet ServletContainer : java.lang.NoSuchMethodError: org/objectweb/asm/ClassReader.accept(Lorg/objectweb/asm/ClassVisitor;I)V at com.sun.jersey.server.impl.container.config.AnnotatedClassScanner.analyzeClassFile(AnnotatedClassScanner.java:322) at com.sun.jersey.server.impl.container.config.AnnotatedClassScanner.indexDir(AnnotatedClassScanner.java:271) .... ...
The thing is :
- Hibernate is loading cglib, which in turns loads asm with an old version
- Jersey needs asm with a newer version, and both version aren't compatibles because of changes in packages.
Solution (that's not from me, it's well documented on the network) :
- Exclude cglib, asm and asm-attr when declaring hibernate maven dependency (if you're using maven of course)
- Explicitely declare a dependecy to cglib-nodep. This cglib repackaged artefact includes cglib AND asm, with altered package definition not to conflict with jersey asm version.
So your poms should by now look like this :
cglib cglib-nodep 2.1_3 org.hibernate hibernate asm asm asm asm-attrs cglib cglib com.sun.jersey jersey-server 1.1.4.1
So now hibernate is using is own version of asm, and Jersey the 3.11 required version.
So why do I keep getting this error ?
After a few hours struggling with my favorite deployment manager, which I thought was the cause of the issue, I realized that the loaded ClassVisitor class was coming from WAS internal plugins.
After setting a breakpoint and inspecting the classloader, I saw that the class was loaded from this jar :
C:/Program Files/IBM/SDP70/runtimes/base_ v61/plugins/com.ibm.wsfp.main_ 6.1.0.jar
So what's left to us ?
C:/Program Files/IBM/SDP70/runtimes/base_
So what's left to us ?
- Solution #1 : Delete this jar :-) - Works, but not optimal !
- Solution #2 : There must be a Websphere setting related to the classloader (PARENT_FIRST vs PARENT_LAST ?), but I can't get it to work (I get exceptions in the was console whenever I try to change those settings).
Anyhow, if anybody knows how to tell Websphere to pick up my jar instead of its jar, please let me know ! Any help would be greatly appreciated.
Hi,
ReplyDeleteYou can try deploying your application with the detailed options through admin console.
On the first page you will see an option which reads something like set option for reloading interval, check this option and provide a value in the text box.
The jars that are required by your application, save it as a shared library and then provide this shared library reference to the concerned module.
Once the deployment is complete, navigate to the application and open the class loading and update detection hyperlink, from here you can choose the option of PARENT_LAST.
I hope this helps you.
Cheers
Vivek Mittal
Hi Vevek
ReplyDeleteThanks a lot for your answer. I'm not working on this topic anymore, so won't have time to try your solution. Antway, in the end, it looks like the bad jar was loaded by my IDE / application server connector, so I didn't have any problem in production.
Thanks anyway.