constraint jdk 11 upgrade Jahia 8

java.lang.LinkageError: loader constraint violation for class - Error after updating my custom module and Jahia to a newer JDK

Question

I am migrating my Jahia to a newer JDK 11 version. I had to update some dependencies and plugins in my custom module to get libraries versions compatible with JDK 11.

After resolving the compilation once I execute my module I am getting this error in distinct places. Here is one example:

Handler processing failed; 
 nested exception is java.lang.LinkageError: 
  loader constraint violation for class org.apache.cxf.jaxb.attachment.JAXBAttachmentMarshaller: 
   when selecting overriding method 'java.lang.String org.apache.cxf.jaxb.attachment.JAXBAttachmentMarshaller.addSwaRefAttachment(javax.activation.DataHandler)' 
   the class loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5 @2105ecf of the selected method's type org.apache.cxf.jaxb.attachment.JAXBAttachmentMarshaller, 
   and the class loader org.apache.catalina.loader.ParallelWebappClassLoader @fb9c7aa for its super type javax.xml.bind.attachment.AttachmentMarshaller have different Class objects 
   for the type javax.activation.DataHandler used in the signature 
   (org.apache.cxf.jaxb.attachment.JAXBAttachmentMarshaller is in unnamed module of loader org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5 @2105ecf, 
    parent loader java.net.URLClassLoader @395a63a8; 
   javax.xml.bind.attachment.AttachmentMarshaller is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @fb9c7aa, 
    parent loader java.net.URLClassLoader @5387f9e0
   ). 

How do I fix that?

How can I find out which libraries are also loading this class in the class loader?

Answer

This error might happen when your module provide classes that are already provided by Jahia default class loader.

One easy way to find out which libraries already embed this class is to grep the class path in <WEB_APP_DIR>/WEB-INF/lib

Taking the description as an example, the overriding method is not matching the signature for javax.activation.DataHandler:

have different Class objects 
   for the type javax.activation.DataHandler used in the signature

So if we perform a grep in the library directory of your web application:

$ grep "javax.activation.DataHandler" *.jar

Binary file activation-1.1.1.jar matches
Binary file javax.activation-api-1.2.0.jar matches

These two libraries are already loading javax.activation.DataHandler in the class loader, so a simple way to fix this error is declaring these libraries as dependencies in your custom module and setting a provided scope:

<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>javax.activation-api</artifactId>
    <version>1.2.0</version>
    <scope>provided</scope>
</dependency>

You might also do the same search in digital-factory-data/modules folder to check for indirect loads of the same class.