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

Eclipse运行正常但JAR包异常:Class.forName()未抛异常却跳至finally块

问题详情

程序在Eclipse环境运行完全正常,但打包成JAR文件执行时出现以下异常:

  • 执行Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver")后无可见异常抛出,直接跳转至finally块
  • 最终在con.close()(代码第449行)触发java.lang.NullPointerException
  • 测试输入错误驱动类名时,会正常抛出ClassNotFoundException,说明驱动类可被正确加载

运行输出对比

Eclipse运行输出

Finding class...
Getting connection for log population...
Got connection for log population...
In finally block...
Finished.

JAR运行输出

C:\me\myProgram>java -cp MyJar.jar;mssql-jdbc-12.4.0.jre11.jar com.me.myProgram.Main
Finding class...
In finally block...
Exception in thread "main" java.lang.NullPointerException
        at com.me.myProgram.logResults(Comparison.java:449)
        at com.me.myProgram.run(Comparison.java:547)
        at com.me.myProgram.Main.main(Main.java:13)

错误类名测试输出

D:\me\myProgram>java -cp MyJar.jar;mssql-jdbc-12.4.0.jre11.jar com.me.myProgram.Main
Finding class...
com.microsoft.sqlserver.jdbc.SQLServerDrive
java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDrive
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        ...

相关代码片段(第449行为con.close())

Connection con = null;
try {
    System.out.println("Finding class...");
    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
    System.out.println("Getting connection for log population...");
    con = DriverManager.getConnection(url, user, pass);
    System.out.println("Got connection for log population...");
    // 业务逻辑代码
} catch (Exception e) {
    // 原异常处理逻辑(未输出异常信息)
} finally {
    try {
        con.close(); // 第449行,触发NPE
    } catch (SQLException e) {
        e.printStackTrace();
    }
}
解决步骤

1. 修复异常捕获,暴露真实错误

问题根源是Class.forName或getConnection抛出了异常,但原catch块未输出任何异常信息,导致看起来像“无异常跳转”。Eclipse运行正常是因为连接参数(URL、用户名、密码)正确,而JAR运行时参数不符。

修改catch块,强制打印完整异常栈:

catch (Exception e) {
    e.printStackTrace(); // 或写入日志,确保异常信息被输出
}

执行JAR后即可看到真正的异常原因(比如URL格式错误、数据库拒绝连接、用户名密码无效等)。

2. 给finally块增加非空判断

无论连接是否成功创建,都要先检查con是否为null再调用close(),直接避免NPE:

finally {
    try {
        if (con != null) {
            con.close();
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

3. 验证JAR运行环境的连接参数

  • 检查JAR运行时的数据库URL、用户名、密码是否与Eclipse中一致
  • 若使用外部配置文件,确保文件路径正确或已打包进JAR
  • 确认数据库服务器允许JAR所在机器的IP访问
  • 核对SQL Server JDBC URL格式(示例:jdbc:sqlserver://localhost:1433;databaseName=testDB;encrypt=true;trustServerCertificate=true)

4. 可选:移除手动驱动加载

JDBC 4.0及以上版本会自动加载驱动类,可移除Class.forName调用,简化代码:

// 移除该行代码
// Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection(url, user, pass);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 03:33:12