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

使用jdeprscan扫描Spring Boot项目时频繁出现“找不到类”错误的疑问

JDK8→JDK17 + Spring Boot 2→3升级:jdeprscan扫描问题解答

场景背景

我有一个基于JDK8和Spring Boot 2.6.8的Java REST API,计划升级至JDK17和Spring Boot 3.x。尝试用jdeprscan扫描项目JAR来定位需要更新的类:

jdeprscan target\myapplication.jar

最初使用Spring Boot Maven插件生成的JAR时,出现大量cannot find class错误,例如:

error: cannot find class org/slf4j/LoggerFactory

改用maven-assembly-plugin生成包含所有依赖的胖JAR后,扫描输出了不少有用的废弃类提示(比如org/apache/logging/log4j/util/LoaderUtil uses deprecated class ...),但仍存在部分找不到类的错误,例如error: cannot find class javax/servlet/FilterChain。


问题1:jdeprscan是否确实需要针对包含所有依赖类的JAR,而非spring-boot-maven-plugin生成的JAR?

  • 是的,这是由两类JAR的结构差异和jdeprscan的扫描逻辑决定的:
    • Spring Boot Maven插件生成的是可执行JAR,依赖包被嵌套在BOOT-INF/lib目录下,并非直接合并到主JAR的类路径中。
    • jdeprscan仅会扫描指定JAR文件本身的类,不支持递归扫描JAR内部嵌套的其他依赖JAR,因此无法读取BOOT-INF/lib里的类,必然报找不到类的错误。
    • maven-assembly-plugin生成的胖JAR将所有依赖类合并到同一个JAR文件中,jdeprscan可以直接遍历到所有类,从而输出有效的废弃类检测结果。

问题2:为何能通过java -jar正常运行的JAR,jdeprscan仍会提示“cannot find class ...”错误?

  • 核心原因是运行时类加载机制和jdeprscan的扫描机制完全不同:
    1. 运行时:Spring Boot自带专属类加载器(LaunchedURLClassLoader),会主动识别并加载BOOT-INF/lib下的所有依赖JAR,因此运行时能找到所有需要的类。
    2. 扫描时:jdeprscan遵循标准JAR的类路径规则,没有Spring Boot的特殊类加载逻辑,既无法识别Spring Boot JAR的结构,也不会读取嵌套的依赖JAR。
  • 即使是胖JAR仍出现找不到类的情况,可能的原因包括:
    • 部分依赖是provided scope(例如javax.servlet相关依赖,在Spring Boot中默认标记为provided,不会打包进胖JAR)。
    • JDK17的模块化特性:原javax.servlet包已被迁移至jakarta.servlet,jdeprscan在当前JDK类路径中找不到旧的javax.servlet类。
    • 某些类是通过SPI、反射等方式动态加载的,未被打包进胖JAR。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 12:27:54