LinkageError: when resolving interface method "com.hazelcast.core.IMap.getLocalMapStats()Lcom/hazelcast/monitor/LocalMapStats;"

Viewed 303

The exception we are getting in the log is as below. It is a maven project

Caused by: java.lang.LinkageError: loader constraint violation: when resolving interface method "com.hazelcast.core.IMap.getLocalMapStats()Lcom/hazelcast/monitor/LocalMapStats;" the class loader (instance of <bootloader>) of the current class, java/lang/Object, and the class loader (instance of weblogic/utils/classloaders/ChangeAwareClassLoader) for the method's defining class, com/hazelcast/core/IMap, have different Class objects for the type com/hazelcast/monitor/LocalMapStats used in the signature
at java.lang.invoke.MethodHandleNatives.resolve(Native Method) ~[?:1.8.0_141]
at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:975) ~[?:1.8.0_141]
at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1000) ~[?:1.8.0_141]
at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1386) ~[?:1.8.0_141]
at java.lang.invoke.MethodHandles$Lookup.findVirtual(MethodHandles.java:861) ~[?:1.8.0_141]
at io.micrometer.core.instrument.binder.cache.HazelcastIMapAdapter.resolveIMapMethod(HazelcastIMapAdapter.java:202) ~[micrometer-core-1.5.7.jar:1.5.7]
at io.micrometer.core.instrument.binder.cache.HazelcastIMapAdapter.<clinit>(HazelcastIMapAdapter.java:39) ~[micrometer-core-1.5.7.jar:1.5.7]

We are using Hazelcast 3.12.9 and many other dependencies in our project. I do understand that java.lang.LinkageError happens when there are 2 or more versions found for the class. As per above message it seems there are 2 versions of com.hazelcast.monitor.LocalMapStats is getting loaded. The questions that are not answered are

  1. How to find the jar which are having 2 versions of com.hazelcast.monitor.LocalMapStats class?
  2. Is there any role of loaders and <weblogic/utils/classloaders/ChangeAwareClassLoader> in this error?
  3. There is another way to define to give priority to web application jar compared to weblogic jars by specifying prefer-web-inf-classes = false (more details https://docs.oracle.com/cd/E12840_01/wls/docs103/webapp/weblogic_xml.html#wp1067857)
3 Answers

Well that's a tough situation. I would use jar to extract the classes and then a grep and awk script to seek dups. Something like this:

jar -xvf ../hazelcast-all-3.12.9.jar 
grep -R com.hazelcast.monitor.LocalMapStats * | awk '{print $3}'

You might want to remove all Hazelcast jars and clean your .m2 or what ever repo cache you have. Then add hazelcast-all and see if the issue is resolved.

Two different class versions of LocalMapStats are available hence the issue while loading the class. To avoid this we can set prefer application resources

<weblogic-application>  
    <prefer-application-resources>       
        <resource-name>com/hazelcast/map/LocalMapStats.class</resource-name>
    </prefer-application-resources>
</weblogic-application>

On Oracle support i found an article 1316723.1 which says that we should not use wls:prefer-web-inf-classes in your weblogic.xml. This is an old practice and we should use filtering classloader in weblogic-applicaton.xml.

However my problem is still not resolved. It looks like some version compatibility issue between micrometer-core-1.5.7.jar and com.hazelcast-3.12.9. Micrometer needs Hazlecast with version 4.X. But somehow my project is loading hazelcast 3.12.9.

Related