You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从WebSphere迁移到OpenLiberty时Oracle XSU插入数据遇ClassCastException

问题描述

我们正将遗留应用从IBM WebSphere迁移至OpenLiberty,部分功能依赖Oracle XSU执行数据库操作。已通过java.sql.Connection.unwrap()获取到Oracle专属连接,但调用XSU的insertXML()时触发以下错误:

oracle.xml.sql.OracleXMLSQLException:
com.ibm.ws.rsadapter.jdbc.v42.WSJdbc42PreparedStatement cannot be cast to oracle.jdbc.OraclePreparedStatement

相关配置与代码

server.xml配置

<library id="jdbcLib">
        <fileset dir="C:\Users\uC260112\.m2\repository\com\oracle\ojdbc6\11.2.0.1.0"/>
</library>

<dataSource id="gcmsXAWIPDS" jndiName="jdbc/gcmsXAWIPDS" type="javax.sql.XADataSource">
        <jdbcDriver javax.sql.XADataSource="oracle.jdbc.xa.client.OracleXADataSource" libraryRef="jdbcLib"/>
        <properties.oracle URL="jdbc:oracle:thin:@c588cwegcmd03.int.xxxx.com:1521/xxxxx.int.xxxxx.com" password="xxxxxx" user="xxxxxx"/>
        <connectionManager maxPoolSize="100" minPoolSize="1"/>
</dataSource>

<enterpriseApplication id="xxxxx" location="xxxxx-1.0.ear" name="xxxxx">
        <classloader commonLibraryRef="jdbcLib"/>
</enterpriseApplication>

获取Oracle连接的代码

conId = myXAPool.obtainConnection(null, null);
Connection connection = myXAPool.getConnection(conId);

OracleConnection oracleConnection = connection.unwrap(OracleConnection.class); 

XSU插入数据的代码

OracleXMLSave sav = null;

try {
    sav = getNewOracleXMLSave(oracleConnection, tableName);
    sav.setRowTag(rowDelimiter);
    sav.setDateFormat("dd/MM/yyyy HH:mm:ss");

    sav.insertXML(xsuXml); // 异常触发点
} catch (Exception ex) {
    // 异常处理
}
解决方案

这个问题的核心是OpenLiberty的JDBC代理机制仍在包装PreparedStatement对象,导致XSU无法将其转换为Oracle专属的OraclePreparedStatement。可以通过以下步骤解决:

  1. 禁用PreparedStatement缓存与包装
    修改server.xml中的数据源配置,添加两个关键配置:

    • 在<properties.oracle>中加入wrapPreparedStatements="false",禁用Oracle驱动自身的语句包装
    • 在<connectionManager>中设置prepareStatementCacheSize="0",关闭OpenLiberty的PreparedStatement缓存(避免代理包装)

    修改后的数据源配置如下:

    <dataSource id="gcmsXAWIPDS" jndiName="jdbc/gcmsXAWIPDS" type="javax.sql.XADataSource">
            <jdbcDriver javax.sql.XADataSource="oracle.jdbc.xa.client.OracleXADataSource" libraryRef="jdbcLib"/>
            <properties.oracle URL="jdbc:oracle:thin:@c588cwegcmd03.int.xxxx.com:1521/xxxxx.int.xxxxx.com" 
                               password="xxxxxx" 
                               user="xxxxxx"
                               wrapPreparedStatements="false"/>
            <connectionManager maxPoolSize="100" minPoolSize="1" prepareStatementCacheSize="0"/>
    </dataSource>
    
  2. 验证unwrap后的连接有效性
    在代码中打印oracleConnection的类名,确认已拿到Oracle原生连接而非OpenLiberty代理:

    System.out.println("OracleConnection class: " + oracleConnection.getClass().getName());
    

    正常输出应为oracle.jdbc.driver.T4CConnection或Oracle 11g对应的原生连接类,而非以com.ibm.ws.rsadapter开头的代理类。

  3. 确保XSU与JDBC版本兼容
    检查Oracle XSU的版本是否与ojdbc6(11.2.0.1.0)匹配,建议使用Oracle 11gR2版本的XSU包,避免版本不兼容导致的类型转换问题。

  4. 检查XSU实例创建逻辑
    确认getNewOracleXMLSave方法是通过传入的OracleConnection创建XSU实例,例如使用标准构造函数:

    private OracleXMLSave getNewOracleXMLSave(OracleConnection conn, String tableName) throws SQLException {
        return new OracleXMLSaveImpl(conn, tableName);
    }
    

    避免在方法内部重新获取连接,导致使用未unwrap的代理连接。

内容的提问来源于stack exchange,提问作者israelsm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:46:08