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

Ubuntu终端编译带SQLite的Java控制台应用遇类未找到异常求助

解决ClassNotFoundException与Console.readPassword()的双重问题

看起来你碰到了两个关联的小麻烦:一是用javac/java命令在Ubuntu终端跑程序时,SQLite驱动找不到;二是IDEA内置终端没法用Console.readPassword()启动程序。我来一步步帮你搞定:

一、先解决核心的ClassNotFoundException

这个异常本质是JVM运行时找不到SQLite JDBC驱动的类文件。你在IDEA里用Scanner的版本能跑,是因为IDEA自动帮你把驱动jar包加到了运行类路径里,但手动用命令行编译运行时,你没把驱动jar包含进去。

手动编译运行的正确命令

假设你的SQLite驱动jar是sqlite-jdbc-xxx.jar(比如常见的sqlite-jdbc-3.45.2.0.jar),并且和你的Java源码在同一个目录下:

  1. 编译代码:

    javac -cp .:sqlite-jdbc-xxx.jar com/company/*.java
    

    解释:-cp是指定类路径的参数,.代表当前目录,:是Linux下的路径分隔符(Windows用;),后面跟着驱动jar的完整文件名,这样编译器才能找到org.sqlite.JDBC类。

  2. 运行程序:

    java -cp .:sqlite-jdbc-xxx.jar com.company.Main
    

    运行时同样要指定类路径,不然JVM还是找不到驱动。

更省心的方式:用依赖管理工具

如果不想每次手动敲类路径,建议用Maven或Gradle管理项目依赖:

  • 用Maven的话,在pom.xml里加这段依赖:
    <dependency>
        <groupId>org.xerial</groupId>
        <artifactId>sqlite-jdbc</artifactId>
        <version>3.45.2.0</version>
    </dependency>
    
    然后用mvn compile编译,mvn exec:java -Dexec.mainClass="com.company.Main"运行,它会自动帮你处理所有依赖的类路径。

二、搞定IDEA终端的Console.readPassword()问题

IDEA的内置终端默认没有关联到真正的系统控制台,导致System.console()会返回null,调用readPassword()就会报错。有两个解决办法:

方法1:修改IDEA运行配置

  • 打开Run/Debug Configurations,找到你的Main类对应的配置。
  • 在Configuration标签页里,勾选Emulate terminal in output console选项。
  • 重新运行程序,此时IDEA会模拟真实终端环境,Console.readPassword()就能正常工作了。

方法2:代码兼容两种环境

如果你需要同时支持终端和IDEA环境,可以在代码里做个判断,回退到Scanner输入:

import java.util.Arrays;
import java.util.Scanner;

// 在你的PasswordHelper类里修改输入逻辑
Console console = System.console();
char[] passwordChars;
if (console != null) {
    passwordChars = console.readPassword("Enter password: ");
} else {
    // 没有Console实例时用Scanner(适合IDEA等环境)
    Scanner scanner = new Scanner(System.in);
    System.out.print("Enter password: ");
    passwordChars = scanner.nextLine().toCharArray();
}
String password = new String(passwordChars);
// 记得清空密码数组,避免内存里残留明文密码
Arrays.fill(passwordChars, ' ');

三、额外提个小建议:避免SQL注入

你的writeToDB方法直接把密码拼接到SQL语句里,存在SQL注入风险。建议改用PreparedStatement,既安全又规范:

static void writeToDB(String password) throws SQLException {
    // 注意SQLite的表名/字段名不需要单引号包裹
    String query = "INSERT INTO " + tableName + " (hash) VALUES (?);";
    // 用try-with-resources自动关闭PreparedStatement
    try (PreparedStatement pstmt = connection.prepareStatement(query)) {
        pstmt.setString(1, password);
        pstmt.executeUpdate();
        System.out.println("Password was successfully added to DB");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:03:21