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,就能快速定位问题了。

相关推荐
梵得儿SHI12 分钟前
Java 反射机制深度解析:从运行时 “解剖” 类的底层逻辑
java·开发语言·反射·反射机制·private·类成员·反射的三大核心功能
豆沙沙包?19 分钟前
2025年--Lc188--931. 下降路径最小和(多维动态规划,矩阵)--Java版
java·矩阵·动态规划
JAVA学习通28 分钟前
Spring AI 1.0 GA 深度解析:Java生态的AI革命已来
java·人工智能·spring·springai
虚行37 分钟前
Python学习入门
开发语言·python·学习
总有刁民想爱朕ha41 分钟前
Python自动化从入门到实战(23):Python打地鼠游戏开发
开发语言·python·游戏开发
曹牧42 分钟前
C#:函数默认参数
开发语言·c#
黄焖鸡能干四碗1 小时前
MES生产执行制造系统建设(Java+Mysql)
java·大数据·开发语言·信息可视化·需求分析
workflower1 小时前
跨链协同制造中的服务博弈与激励机制
开发语言·软件工程·制造·需求分析·个人开发·结对编程
liulilittle1 小时前
Y组合子剖析:C++ 中的递归魔法
开发语言·c++·编程语言·函数式编程·函数式·函数编程·y组合子
舒克日记1 小时前
基于springboot的民谣网站的设计与实现
java·spring boot·后端