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

如何在可执行JAR内部连接内嵌的Apache Derby数据库JAR包

解决方案

核心原因

你硬编码的src/main/resources/dbs.jar是开发阶段的本地文件系统路径,可执行JAR打包完成后,dbs.jar是嵌套在JAR内部的类路径资源,不属于文件系统上的独立文件,而Derby默认的jar:协议仅支持读取文件系统中独立存在的JAR包,无法直接识别嵌套JAR的内部资源路径。


方案1:运行时解压数据库JAR到临时目录(兼容性最强,支持读写)

这是最稳妥的实现方式,不需要依赖特殊类加载器,同时支持对数据库的读写操作:

  1. 首先将嵌套在内部的dbs.jar资源读取后写入到系统临时目录
  2. 用临时目录下dbs.jar的绝对路径构造JDBC连接字符串

示例代码:

public static void queryDatabase() throws IOException {
    // 读取classpath下的dbs.jar资源,注意替换为你实际的类名
    InputStream dbJarIn = YourClassName.class.getResourceAsStream("/dbs.jar");
    if (dbJarIn == null) {
        throw new IOException("未找到内嵌的数据库JAR资源");
    }
    // 创建临时文件
    File tempDbJar = File.createTempFile("dbs", ".jar");
    tempDbJar.deleteOnExit(); // JVM退出时自动删除临时文件
    // 写入临时文件
    try (FileOutputStream out = new FileOutputStream(tempDbJar)) {
        byte[] buffer = new byte[1024];
        int len;
        while ((len = dbJarIn.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
    } finally {
        dbJarIn.close();
    }
    // 构造正确的连接字符串
    String connectionUrl = String.format("jdbc:derby:jar:(%s)employees", tempDbJar.getAbsolutePath());
    try (Connection conn = DriverManager.getConnection(connectionUrl)) {
        RowSetFactory factory = RowSetProvider.newFactory();
        CachedRowSet cachedRowSet = factory.createCachedRowSet();
        cachedRowSet.setCommand("select id,salary,filingStatus from employees");
        cachedRowSet.execute(conn);

        while (cachedRowSet.next()) {
            System.out.print(cachedRowSet.getString("id") + " ");
            System.out.print(cachedRowSet.getFloat("salary") + " ");
            System.out.println(cachedRowSet.getString("filingStatus"));
        }
    } catch (SQLException exception) {
        exception.printStackTrace();
    }
}

方案2:使用Derby的classpath协议(仅支持只读场景)

如果你的数据库仅用于查询不需要写入,可以直接用Derby内置的classpath路径前缀,不需要写具体JAR路径,Derby会自动在整个类路径中查找数据库:

// 直接使用classpath前缀,employees是数据库名
String connectionUrl = "jdbc:derby:classpath:employees";

这个方案的前提是dbs.jar被正确包含在可执行JAR的类路径中,Maven打包后resources下的文件默认都会放到类路径根目录,符合要求。


IDE运行正常的原因说明

IDE运行时会将src/main/resources目录作为文件系统目录直接加入类路径,此时dbs.jar是独立存在的磁盘文件,所以硬编码的路径可以正常识别,打包后资源被嵌套进JAR,路径就失效了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:36:06