Java 常见异常系列:ClassNotFoundException 类找不到

发布于:2025-08-31 ⋅ 阅读:(21) ⋅ 点赞:(0)

网罗开发 (小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


摘要

在日常开发中,我们经常会遇到各种各样的异常,其中 ClassNotFoundException 可能是最容易让人“抓狂”的一种。表面上它告诉我们类找不到,但实际上背后的原因往往是:依赖缺失、classpath 配置错误、或者加载方式有问题。本文会结合一个数据库驱动缺失的例子来展开,带大家一步步定位并解决这个异常。

引言

在 Java 世界里,所有的类都是通过类加载器(ClassLoader)去加载的。如果你写了一段代码调用某个类,但是运行环境中找不到这个类对应的 .class 文件,就会抛出 ClassNotFoundException
一个典型场景就是:连接数据库时,程序报错提示找不到 com.mysql.cj.jdbc.Driver,这往往是因为项目里没有正确引入 MySQL 的驱动包。

下面我们来复现这个问题,并通过实际的 Demo 来说明。

问题示例

Demo 代码

public class JdbcDemo {
    public static void main(String[] args) {
        try {
            // 尝试加载 MySQL 驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            System.out.println("驱动加载成功!");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

运行结果

如果此时项目里没有引入 MySQL 驱动依赖,那么运行时会报错:

java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:468)
    at JdbcDemo.main(JdbcDemo.java:6)

这就是典型的 类找不到异常

为什么会出现这个问题?

  • 缺少依赖:最常见的情况就是 JAR 包没引入,比如少了 mysql-connector-java。
  • classpath 配置错误:即使 JAR 包在硬盘上,但如果没加入运行时的 classpath,类加载器一样找不到。
  • 模块化/容器环境:在某些框架或容器中,可能需要额外配置 classpath,比如 Tomcat、Spring Boot 自定义类加载机制。

解决方案

1. 正确引入依赖

如果你用的是 Maven,可以在 pom.xml 中添加:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>

Gradle 也很简单:

implementation 'mysql:mysql-connector-java:8.0.33'

这样打包时,IDEA 会自动帮你把依赖下载并加到 classpath 里。

2. 检查运行时 classpath

如果你用的是 javac + java 命令运行,要确保驱动 jar 包在运行时加入 classpath:

javac JdbcDemo.java
java -cp .;mysql-connector-java-8.0.33.jar JdbcDemo

很多同学就是因为只写了 java JdbcDemo,导致驱动找不到。

3. Spring Boot 的正确姿势

如果你用的是 Spring Boot,那就更简单了,不要手动 Class.forName(),只需要在 pom.xml 里引入 starter:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

Spring Boot 会自动通过 SPI 机制加载驱动类,你只需要在 application.yml 里配置:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/testdb
    username: root
    password: 123456

然后正常运行就行了。

实际项目中的场景

  1. 微服务环境:如果你把服务打成 jar 部署,确保依赖没有被 provided 掉,打包时要在 fat jar 里包含驱动类。
  2. Docker 部署:如果镜像里只有你的代码而没有依赖 jar,也会报 ClassNotFoundException,需要确保镜像构建脚本 COPY 了完整依赖。
  3. Tomcat/外部容器:在 Tomcat 下需要把 jar 放到 WEB-INF/libTomcat/lib 目录里,否则容器的类加载器无法加载。

总结

ClassNotFoundException 看起来简单,其实背后有很多种可能。最常见的还是依赖没有引入,其次是运行时 classpath 配置错误。遇到这个异常时,不要慌,按照以下步骤排查:

  1. 确认代码中用到的类名是否正确。
  2. 确认项目依赖里有没有对应的 jar。
  3. 确认运行时 classpath 里能否找到对应类。
  4. 在 Spring Boot 或容器环境里,确认 starter/依赖配置正确。

掌握了这些套路,你下次再遇到 ClassNotFoundException,就能快速定位问题了。


网站公告

今日签到

点亮在社区的每一天
去签到