classnotfoundexception 的本质是 jvm 运行时按全限定名查找 .class 文件失败,因类路径或模块路径中缺失该类;需严格核对类名大小写与包结构、确认依赖在运行时真实存在且 scope 正确、验证 classpath 实际生效,并注意 jdk 模块化限制。

ClassNotFoundException 的本质是 JVM 运行时按全限定名去找一个 .class 文件,却没在类路径(classpath)或模块路径中找到它。它不发生在编译阶段,所以代码能正常编译通过,但一执行 Class.forName()、反序列化或框架自动加载时就崩。
核对类名和包结构是否严丝合缝
Java 对大小写、拼写、斜杠方向极度敏感。比如 com.oykq.pagehelper.PageInterceptor 和 com.oykq.pagehelper.pageinterceptor 是两个完全不同的类;少一个字母(PageIntercepto)、多一个空格、用错下划线,都会失败。
- 打开对应 Java 文件,确认 package 声明与磁盘路径完全一致(如 package com.oykq.pagehelper; → 必须放在 src/main/java/com/oykq/pagehelper/ 下)
- 在 IDE 中按 Ctrl+Click(IntelliJ)或 F3(Eclipse)尝试跳转该类,跳不过去说明编译期已不可见,问题更前置
- 使用 Class.forName("com.oykq.pagehelper.PageInterceptor") 时,必须写全限定名,不能省略包名
确认依赖真正在运行时可用
编译通过 ≠ 运行时有这个类。Maven 的
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 执行 mvn dependency:tree -Dincludes=pagehelper 查看 PageHelper 是否被正确引入,有没有被其他依赖排除或版本覆盖
- 检查 pom.xml 中依赖的 scope:javax.servlet-api 设为 provided 合理,但 spring-context、pagehelper 等核心依赖必须是默认 compile
- 打包后解压 JAR/WAR,进 BOOT-INF/lib(Spring Boot)或 WEB-INF/lib(传统 Web),用 jar -tf xxx.jar | grep PageInterceptor 确认 class 文件确实存在
验证类路径是否真实生效
IDE、命令行、启动脚本、应用服务器各自维护一套类路径,很容易“你以为它在,其实它不在”。
- 运行时显式指定:java -cp "lib/*:." com.example.Main(Linux/macOS)或 java -cp "lib\*;." com.example.Main(Windows)
- 在代码里加一句 System.out.println(System.getProperty("java.class.path"));,直接看 JVM 当前看到的完整 classpath 列表
- Tomcat 部署时,第三方 JAR 必须放 WEB-INF/lib(应用级)或 $CATALINA_HOME/lib(全局级),不能扔项目根目录或 src 下
留意 JDK 模块系统带来的变化
JDK 9+ 引入模块系统后,即使 JAR 在 classpath 里,如果没在 module-info.java 中声明 requires,或者没用 --add-modules 显式开启,某些类也可能加载失败。
- 若项目用了模块化(有 module-info.java),检查是否声明了对目标类所在模块的依赖
- 启动时可临时加上 --add-modules ALL-SYSTEM 测试是否为模块限制导致
- Spring Boot 2.6+ 默认禁用 javax.* 包,若用到旧版 JDBC 驱动等,需额外配置或降级兼容
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










