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


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

大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括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 代码

java 复制代码
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 复制代码
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 中添加:

xml 复制代码
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>

Gradle 也很简单:

groovy 复制代码
implementation 'mysql:mysql-connector-java:8.0.33'

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

2. 检查运行时 classpath

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

bash 复制代码
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:

xml 复制代码
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

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

yaml 复制代码
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,就能快速定位问题了。

相关推荐
Morpheon4 小时前
Intro to R Programming - Lesson 4 (Graphs)
开发语言·r语言
代码AI弗森4 小时前
使用 JavaScript 构建 RAG(检索增强生成)库:原理与实现
开发语言·javascript·ecmascript
CYRUS_STUDIO4 小时前
一步步带你移植 FART 到 Android 10,实现自动化脱壳
android·java·逆向
练习时长一年4 小时前
Spring代理的特点
java·前端·spring
CYRUS_STUDIO4 小时前
FART 主动调用组件深度解析:破解 ART 下函数抽取壳的终极武器
android·java·逆向
MisterZhang6665 小时前
Java使用apache.commons.math3的DBSCAN实现自动聚类
java·人工智能·机器学习·自然语言处理·nlp·聚类
Tipriest_5 小时前
C++ 中 ::(作用域解析运算符)的用途
开发语言·c++·作用域解析
Tipriest_6 小时前
求一个整数x的平方根到指定精度[C++][Python]
开发语言·c++·python
一只叫煤球的猫6 小时前
怎么这么多StringUtils——Apache、Spring、Hutool全面对比
java·后端·性能优化