Search code examples
websphereclassloaderwebsphere-libertyserver.xml

javax.activation.DataHandler conflicts in Websphere Liberty 8.5.5.9


So, this is my saga from previous question here: javax.mail.NoSuchProviderException: when using Liberty 8.5.5.9 with Apache Commons Email 1.4 Where I've had have conflicts between Apache Commons Email and Websphere Liberty Feature JavaMail 1.5 feature which I've solved by defining that App's jars loading first by using <classloader delegation="parentLast" />.

Everything worked fine until I've started to implement fileupload, by using jax-rs 2.0 as described in this tutorial Configuring a resource to receive multipart/form-data parts from an HTML form submission in JAX-RS 2.0

When my code reaches the following line: stream = dataHandler.getInputStream(); stream is type of InputStream i.e. I'm trying to do something with DataHandler object it throws an exception:

[ERROR   ] Error occurred during error handling, give up!
loader constraint violation: loader (instance of com/ibm/ws/classloading/internal/ParentLastClassLoader) previously initiated loading for a different type with name "javax/activation/DataHandler"
[ERROR   ] SRVE0777E: Exception thrown by application class 'org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage:116'
java.lang.RuntimeException: org.apache.cxf.interceptor.Fault: loader constraint violation: loader (instance of com/ibm/ws/classloading/internal/ParentLastClassLoader) previously initiated loading for a different type with name "javax/activation/DataHandler"
    at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:116)
    at [internal classes]
Caused by: org.apache.cxf.interceptor.Fault: loader constraint violation: loader (instance of com/ibm/ws/classloading/internal/ParentLastClassLoader) previously initiated loading for a different type with name "javax/activation/DataHandler"
    at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:163)
    ... 1 more
Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of com/ibm/ws/classloading/internal/ParentLastClassLoader) previously initiated loading for a different type with name "javax/activation/DataHandler"
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
    at com.ibm.ws.classloading.internal.AppClassLoader.definePackageAndClass(AppClassLoader.java:327)
    at [internal classes]
    at ****.EventsAPI.handleUploadedEventForm(EventsAPI.java:174)
    at ****.EventsAPI.postFormData(EventsAPI.java:114)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:636)
    ... 1 more

And indeed there's DataHandler object as part of Apache Commons Email and DataHandler in IBM's implementation of IAttachment see javadoc, and they are conflicting.

So, how can it be resolved? Can it be resolved through configuration? Writing custom classloader isn't acceptable solution.

Update: It isn't clear from my question but now I have two stages, one when I'm using <classloader delegation="parentLast" /> my mailing work but fileupload doesn't work and without <classloader delegation="parentLast" /> my mailing doesn't work but fileuploading work. When I deploy my app on WAS Liberty 8.5.5.7 or 8.5.5.8 it works fine, the problem exists only from 8.5.5.9


Solution

  • Actually I've find workaround to this issue.

    First of all I've changed scope to <scope>provided</scope> of all included dependencies which has my library. Once again, I used my library which to send emails, which depend itself on:

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-email</artifactId>
            <version>1.4</version>
            <scope>provided</scope>
        </dependency>
    
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
            <scope>provided</scope>
        </dependency>
    

    So my parent application was required to supply all required dependencies, common-emails and commons-io. commons-io I've added through the parent's pom.xml regarding commons-email I've installed feature javaMail-1.5 explicitly which already has this library. Also I've removed: <classloader delegation="parentLast" />

    The only one question remained unanswered why did it conflict before? If anybody will provide more detailed explanation it'll be great.