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

Java代码中添加多JDBC驱动Jar包解决KO16MSWIN949字符集错误

解决JDBC连接Oracle时KO16MSWIN949编码不支持问题(代码加载多Jar包)

问题核心

使用ojdbc11.jar连接Oracle数据库时,抛出Unsupported character set (add orai18n.jar to classpath): KO16MSWIN949错误,需通过代码动态加载ojdbc11.jar和orai18n.jar两个Jar包,无需在IDE中配置依赖。

解决方案

通过调整代码实现多Jar包动态加载,核心修改点如下:

  1. 允许ConnectionDescription存储多个Jar包路径
  2. 让类加载器同时加载ojdbc11.jar和orai18n.jar
  3. 更新Jar路径配置,加入orai18n.jar的路径

修改后的完整代码

DBConnInfo.java

public class DBConnInfo {

    public ConnectionDescription getConnectionDescription() {
        ConnectionDescription connectionDesc = new ConnectionDescription();

        connectionDesc.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
        connectionDesc.setUser("docker");
        connectionDesc.setPassword("docker");
        // 同时配置ojdbc11.jar和orai18n.jar的本地路径
        connectionDesc.setDriverJarPaths(List.of(
            "/Users/elvis/JDBC/Oracle/ojdbc8-full/ojdbc11.jar",
            "/Users/elvis/JDBC/Oracle/ojdbc8-full/orai18n.jar"
        ));
        connectionDesc.setDriverClassName("oracle.jdbc.OracleDriver");

        return connectionDesc;
    }

    public void executeSampleQuery(Connection conn) {
        try {
            Statement statement = conn.createStatement();
            
            ResultSet rs = null;
            
            String sql = "SELECT UU.USERNAME \n" 
                    + "FROM USER_USERS UU";
            
            rs = statement.executeQuery(sql);
            
            if(rs.next()) {
                System.out.println(rs.getString("USERNAME"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

ConnectionDescription.java

import java.util.List;
import java.util.Properties;

public class ConnectionDescription {

    private String url;
    private String user;
    private String password;
    private List<String> driverJarPaths; // 修改为集合类型,支持多个Jar路径
    private String driverClassName;

    public ConnectionDescription() {
    }

    public String getUrl() {
        return this.url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUser() {
        return this.user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public List<String> getDriverJarPaths() {
        return this.driverJarPaths;
    }

    public void setDriverJarPaths(List<String> driverJarPaths) {
        this.driverJarPaths = driverJarPaths;
    }

    public String getDriverClassName() {
        return this.driverClassName;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public Properties getConnectionProperties() {
        Properties prop = new Properties();

        prop.setProperty("user", this.user);
        prop.setProperty("password", this.password);

        return prop;
    }

    @Override
    public String toString() {
        return "ConnectionDescription [url=" + url + ", user=" + user + ", password=" + password + ", driverJarPaths="
                + driverJarPaths + ", driverClassName=" + driverClassName + "]";
    }
}

修改后的getDriver()方法

private Driver getDriver(ConnectionDescription desc)
            throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
        // 用所有Jar路径拼接生成唯一标识,避免重复加载
        String jarPathsKey = String.join(";", desc.getDriverJarPaths());
        DriverId driverId = new DriverId(jarPathsKey, desc.getDriverClassName());
        Driver driver = this.DRIVERS.get(driverId);

        if (driver == null) {
            ClassLoader parent = this.getClass().getClassLoader();
            // 将多个Jar路径转换为URL数组供类加载器使用
            URL[] jarUrls = desc.getDriverJarPaths().stream()
                    .map(path -> {
                        try {
                            return new URL("file:" + path);
                        } catch (MalformedURLException e) {
                            throw new RuntimeException(e);
                        }
                    })
                    .toArray(URL[]::new);
            ClassLoader classLoader = URLClassLoader.newInstance(jarUrls, parent);
            @SuppressWarnings("unchecked")
            Class<Driver> driverClass = (Class<Driver>) classLoader.loadClass(desc.getDriverClassName());

            driver = driverClass.newInstance();

            this.DRIVERS.put(driverId, driver);
        }
        return driver;
    }

关键说明

  • URLClassLoader支持传入多个Jar包的URL数组,加载Oracle驱动时会同时读取orai18n.jar中的字符集支持类,解决编码不兼容问题。
  • 需保证orai18n.jar与ojdbc11.jar版本匹配,建议使用同一Oracle JDBC驱动包中的配套文件。
  • DriverId的标识逻辑需覆盖多Jar组合场景,确保不同Jar组合不会被重复加载或错误复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:15:37