Search code examples
javajbosswildfly-10ojdbc

ClassA cannot be cast to ClassA : java.lang.ClassCastException


I have Ejb webservice project ,and other web projects ,which I am deploying through EAR on Wildfly 10.x server, the war project and the Ejb project require oracle.sql.OPAQUE for creating xml data through xdb jars, For oracle.sql.OPAQUE I have added ojdbc6 in the project build path and added it in the deployment descriptor as well, I have added ojdbc6 drivers in the wildfly module as well, for jdbc connections. On deploying the project, there are no errors, where as when running the page, I am getting oracle.sql.OPAQUE cannot be cast to oracle.sql.OPAQUE: java.lang.ClassCastException: oracle.sql.OPAQUE cannot be cast to oracle.sql.OPAQUE

it seems like the classloader has loaded the oracle.sql.OPAQUE twice and thus its a problem

  1. I have tried removing the ojdbc6 from the deployment descriptor, but then that throws noclassdeffounderror on the EAR deployment itself.
  2. if somebody could please tell me how do I resolve this classloader issue, on wildfly server side, it would be helpful.
  3. or to force it to use the class from particular side.

thanks alot, please provide any possible links, I would be grateful to you.

10:24:39,460 INFO  [icrCommon] (default task-8) ++++ QueryRequest queryXMLAccess() - ContextKey:256574422:190508:210142844 TypeId: 0 Channel: CAP
10:24:40,521 SEVERE [com.sun.xml.ws.server.sei.EndpointMethodHandler] (default task-8) oracle.sql.OPAQUE cannot be cast to oracle.sql.OPAQUE: java.lang.ClassCastException: oracle.sql.OPAQUE cannot be cast to oracle.sql.OPAQUE
    at com.att.icr.dataAccess.ICRDatabaseAccess.IcrActiveHistoryXMLQuery(ICRDatabaseAccess.java:2093)
    at com.att.icr.icrservices.datamapping.ICRDataAccess.queryXMLAccess(ICRDataAccess.java:1161)
    at com.att.icr.icrservices.ICRSoapHttpBindingImpl.queryICR(ICRSoapHttpBindingImpl.java:307)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

Solution

  • This issue relevant class loading issue in Wildfly. As you know Wildfly has a modular class loading structure. Each module has a own Classloader. It is not enough that the class types are the same. Must be the same in Classloaders. In JBoss doc:

    WildFly's class loading is based on modules that have to define explicit dependencies on other modules. Deployments in WildFly are also modules, and do not have access to classes that are defined in jars in the application server unless an explicit dependency on those classes is defined.

    You can create custom module and provide .ears load jar within this module. Create module.xml file in $JBOSS_HOME/modules/com/example/main/, Write the jar's name you want to load into module.xml.

    <module xmlns="urn:jboss:module:1.5" name="com.example">
    
    <resources>
        <resource-root path="sample.jar"/>
    </resources>
    

    Copy the jar to the path where module.xml is located.

    +-----com
         +-----example
               +-----main
                     module.xml
                     sample.jar
    

    Create deployment descriptior(jboss-deployment-structure.xml) in .ears and add your module to this files.

    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <deployment>
        <dependencies>
            <module name="com.example" export="true" />
        </dependencies>
    </deployment>
    </jboss-deployment-structure>
    

    So, Jar's classloaders are the same. You can look into this example and redhat doc.