类无法转换为类:java.lang.ClassCastException

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

我有 Ejb web 服务项目和其他 web 项目,我正在通过 EAR 在 Wildfly 10.x 服务器上进行部署, war 项目和 Ejb 项目需要 oracle.sql.OPAQUE 通过 xdb jar 创建 xml 数据, 对于 oracle.sql.OPAQUE 我在项目构建路径中添加了 ojdbc6 并将其添加到部署描述符中, 我还在 wildfly 模块中添加了 ojdbc6 个驱动程序,用于 jdbc 连接。 在部署项目时,没有错误,当 运行 页面时,我得到 oracle.sql.OPAQUE cannot be cast to oracle.sql.OPAQUE: java.lang.ClassCastException: oracle.sql.OPAQUE cannot be cast to oracle.sql.OPAQUE

似乎 classloader 已经加载了 oracle.sql.OPAQUE 两次,因此这是一个问题

  1. 我尝试从部署描述符中删除 ojdbc6,但是 然后在 EAR 部署本身上抛出 noclassdefounderror。
  2. 如果有人可以告诉我如何解决这个 classloader 问题, 在 Wildfly 服务器端,这会有所帮助。
  3. 或者强制它从特定的一侧使用 class。

非常感谢,请提供任何可能的链接,我将不胜感激。

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)

此问题与 Wildfly 中的 class 加载问题相关。如您所知,Wildfly 具有模块化 class 加载结构。每个模块都有自己的类加载器。 class 类型相同是不够的。在类加载器中必须相同。在 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.

您可以创建自定义模块并在此模块中提供 .ears 加载 jar。在$JBOSS_HOME/modules/com/example/main/中创建module.xml文件,将你要加载的jar名称写入 module.xml.

<module xmlns="urn:jboss:module:1.5" name="com.example">

<resources>
    <resource-root path="sample.jar"/>
</resources>

复制jar到module.xml所在路径

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

在 .ears 中创建部署描述符 (jboss-deployment-structure.xml) 并将您的模块添加到此文件中。

<?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>

因此,Jar 的 classloader 是相同的。你可以看看 this example and redhat doc.