Nasty Class loader issue: “java.lang.LinkageError: loader constraint violation: loader previously initiated loading for a different type…”

Background

First a bit of background, I am working as part of a team responsible for building a bespoke content management system for educational uses and the back end uses the following technologies:

  • Java Tomcat 7.0 server
  • Rest Easy 3.0.6.Final
  • ElasticSearch 1.0.1
  • Google Guice 3.0 for dependency injection
  • Eclipse Kepler Build 20130919-0819
  • Counterclockwise (Clojure plugin For Eclipse) 0.20.0 & 0.24.1.STABLE001 – This becomes important later even though I am not using it really.

The problem

Now to describe the problem. For some reason after integrating ElasticSearch with our project a nasty error as seen below started happening (and breaking the whole site at runtime when running within eclipse):

SEVERE: Servlet.service() for servlet [jsp] in context with path [/rutherford-server] threw exception [Filter execution threw an exception] with root cause
java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/catalina/loader/WebappClassLoader) previously initiated loading for a different type with name "javax/servlet/http/HttpSession"

This problem seemed to refer at a random place in our code in the stack trace. This random place had previously worked (and is totally unrelated to the Elastic Search stuff I was working on) in my case it occurred in a User Manager class that deals with sessions (hence the reference to HttpSession). The elastic search stuff didn’t have anything to do with the user manager or even use the HttpSession class as far as I was aware but seemed to trigger the error when the code for the elasticsearch java api was inserted.

Investigating

A really useful explanation of how class loaders work can be found in Frank Kieviet’s blog; it certainly helped me understand the strange behaviour i.e. random things breaking that are totally unrelated to the change being made.

As mentioned in Frank Kieviet’s blog, this type of error is extremely difficult to debug and it appears that it is related to the sequence in which classes are loaded into the jvm.

My approach, after initially (and wrongly)  blaming Google Guice and ElasticSearch, eventually lead me to investigate what was actually asking for another version of the HttpSession class. In order to do this I added the following to my run configuration for the tomcat server within the eclipse run configuration.

-verbose:class

clojureBugRunConf

Demonstrating the additional debug parameter to use

 

Naturally, this caused a huge torrent of information to be spewed out of the console screen; so much so that I had to make the console buffer set to unlimited size to preserve all of the information.

After some targeted searching of the output I found the following two lines (in different areas of the output):

  1. [Loaded javax.servlet.http.HttpSession from file:/C:/Program%20Files/Apache%20Software%20Foundation/Tomcat%207.0/lib/servlet-api.jar]
  2. [Loaded javax.servlet.http.HttpSession from file:/C:/eclipse/plugins/ccw.core_0.20.0.STABLE001/lib/servlet-api.jar]

Strange I hear you all say. Why would there be an eclipse plugin displayed in the console of my tomcat run environment. Well that is what I thought too. After some more investigation the offending plugin is Counter Clockwise, a cojure plugin for eclipse.

Conclusion

After uninstalling the clojure plugin everything was fine again; elastic search and the user manager worked like a dream. I did try updating from Clojure plugin version 0.20.0 to 0.24.1 but everything still broke.

I have a few outstanding questions like:

  • Why are my eclipse plugins interfering with my tomcat environment running in eclipse (I thought it would run in a different JVM)?
  • Why is clojure running all the time anyway (I wasn’t even using the plugin for anything I was doing at the time)?
  • Shouldn’t the tomcat instance running within eclipse be sandboxed from plugins etc.

Note: I will try and come up with a simple example that breaks consistently and post it here but in the mean time if anyone is interested I can set you up with a copy of the code base at the point we were having the errors.

, , , ,

  1. #1 by Laurent Petit on 6 November 2014 - 22:43

    Hello,

    I’m the developer of Counterclockwise, and found your blog post while trying to fix the exact same problem for Counterclockwise, but maybe in the reverse order :-).

    Anyway, I would be very interested if you can indeed provide a reproducible example with instructions, because it is a very annoying problem. I hate when Counterclockwise doesn’t act as a good citizen. Maybe it is exposing too many things, maybe that’s something else, I’d like to know.

    Cheers

  2. #2 by Steve on 7 November 2014 - 14:15

    Hi Laurent,

    I will have a go at creating a minimal example for you when I have a few minutes but I suspect it is just due to the unfortunate combination of libraries and plugins that I was using.

    I shall e-mail you if I come up with something. Let me know if you fix it as I would like to start using it again; it’s a great plugin.

    Thanks,

    Steve

  3. #3 by Laurent Petit on 7 November 2014 - 20:28

    Hi Steve,

    Yeah, I would definitely try to fix it. Because everytime I was facing such issue in the past, after having banged my head against the wall for of few hours, I gain more insight into how things should work in combination, and the result is a more stable product.

    I really hope you’ll be able to find the time to do the bug report.

    Please note that I don’t receive notifications when comments are added to this post, so I may not necessarily be able to answer again, if I unexpectedly close or loose sight of the page in my browser 😉

  4. #4 by Shailendra on 16 July 2015 - 11:43

    Thanks. I was into linkage error in my osgi bundle and this solved it. Now I am stuck where getting IJavaProject reference always null from IProject (this one is proper). Let me know if any of you can help. http://stackoverflow.com/questions/31451860/org-eclipse-jdt-core-javacores-create-method-always-returning-null

  5. #5 by MESSAI on 7 September 2015 - 17:03

    hi all,

    The solution is to create the elastcisearch client like this :

    Settings settings = ImmutableSettings.settingsBuilder()
    .put(“path.plugins”, “fakeDirectory:\\”)
    .build();

    TransportClient client = new TransportClient(settings);

    I put a fake directory because ElasticSearch use it when it start to load all eclipse plugins but i d’ont know why !! (see org.elasticsearch.plugins.PluginsService class)

    Kheireddine MESSAI
    Thanks

  6. #6 by Steve on 7 September 2015 - 17:09

    That is insane… Thanks for pointing that out. I will try your fix.

Leave a Reply

Your email address will not be published. Required fields are marked *