news 2026/10/12 4:54:47

Java 启动报 NoClassDefFoundError: feign/Request$Options 排查:provided scope 被 dependencyManagement 继承

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 启动报 NoClassDefFoundError: feign/Request$Options 排查:provided scope 被 dependencyManagement 继承

老炮踩坑录 · F12 · 翻车现场系列· 番外篇
基于「基础企业档案」真实项目代码,复盘一次换 IDEA 版本引发的离奇启动失败
关键词:NoClassDefFoundError · provided scope · dependencyManagement · effective-pom

👋 欢迎阅读

🏠个人主页:知守观
📘我的专栏:老炮踩坑录
💻当前内容:Maven范围依赖

文章目录

    • 前言
    • 一开始判断错了方向
    • 本地仓库路径先搞错了
    • dependency:tree 定位到 scope
    • 很多人没踩过的点:BOM 连 scope 一起管
    • 为什么偏偏和 IDEA 版本有关
    • 修复
    • 第二个报错:feign-slf4j
    • 为什么容易被误导
    • 自查清单
    • 老炮点评

前言

今天这篇是番外篇,翻出的是另一个项目——基础企业档案,一个Spring Cloud微服务项目。

离职后整理旧硬盘,翻出以前做的另一个 项目,它是一个 Spring Cloud 微服务项目。想跑起来看一眼当年写的代码,顺手用机器上装着的两个 IDEA 版本各打开了一次。

诡异的事出现了。同一个仓库、同一份代码、同一个 JDK,一个版本启动正常,另一个版本直接报错:

java.lang.NoClassDefFoundError: feign/Request$Options at org.springframework.cloud.openfeign.FeignClientFactoryBean.<init>(FeignClientFactoryBean.java:106) ... Caused by: java.lang.ClassNotFoundException: feign.Request$Options

报错出现在 Spring 注册@FeignClient的阶段。FeignClientFactoryBean初始化时要 new 一个Request.Options,类却没有找到。

代码一个字没动,换个 IDE 就起不来。排查这种问题没有明确线索,一时不知道从哪里下手。

一开始判断错了方向

看到堆栈里的spring-cloud-openfeign-core-3.1.1,我第一反应是版本对不上。项目里手写的 openfeign 版本是2.2.3.RELEASE,运行时加载的却是 3.1.1,版本显然被上层依赖管理覆盖了。具体是父 POM 里哪一层 BOM 生效,当时没往上翻,先没有继续追查。

缺类就补类。我在子模块的 pom 里直接把 feign-core 加上:

<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-core</artifactId></dependency>

Reload,重启,报错一个字没变。

依赖写了,运行时却没有生效。到这里我意识到,问题不在"有没有声明依赖"。

本地仓库路径先搞错了

我习惯性去默认仓库找 openfeign 的目录:

dir"$env:USERPROFILE\.m2\repository\io\github\openfeign"

整个路径不存在。

可堆栈里明明有spring-cloud-openfeign-core-3.1.1.jar,JAR 不可能凭空出现。直到我跑了一次 mvn,日志里一行信息说明了原因——本地仓库路径早就被 settings.xml 改到了D:\Maven\repertory,~/.m2下并没有所需的依赖。

我一直在错误的仓库路径里查找。

dependency:tree 定位到 scope

换到正确的仓库路径,feign-core 的 JAR 确实存在。JAR 在、声明在、运行时就是没有,剩下的可能性只有 scope。

mvn dependency:tree"-Dincludes=io.github.openfeign:feign-core"

PowerShell 里这个参数不加引号会被解析坏,顺手提一下。输出:

[INFO] cn.linkkids:base-guidang-web:jar:0.0.1-SNAPSHOT [INFO] \- io.github.openfeign:feign-core:jar:11.8:provided

末尾两个字:provided。

很多人没踩过的点:BOM 连 scope 一起管

provided 的效果不用多讲,编译期在、运行期不在。问题是我从来没写过 provided,它从哪来的?

答案在 dependencyManagement 里。不少人对它的印象停留在"统一管版本号",实际上 version、scope、exclusions 都能在这里一起指定:

<dependencyManagement><dependencies><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-core</artifactId><version>11.8</version><scope>provided</scope></dependency></dependencies></dependencyManagement>

上面是示意,父 POM 的原文我离职后已经拉不到了。

子模块声明依赖时不写 scope,就继承管理条目里的 provided;自己显式写 scope,才能覆盖继承值。我后来查 effective-pom 验证,feign-core 的最终 scope 确实是 provided。

为什么这么设计,我只能推测:公司内部部署体系里,feign 相关 JAR 可能由统一的基础环境提供,业务包刻意不带。翻提交记录或许有答案,旧仓库权限已经没了,这部分无法确认。

为什么偏偏和 IDEA 版本有关

这一步的判断我没有直接证据,只能根据 IDEA 的配置项推断。

IDEA 的运行配置里有个开关:Add dependencies with "provided" scope to classpath。两个 IDEA 版本下,这个开关的默认状态、或者老配置迁移后的状态很可能不一样——一边把 provided 依赖带进了运行时 classpath,一边没有。旧环境已经不在我机器上,没法回头点开那个配置截图验证,所以这段只能给到"最可能的解释"。

能确认的事实只有一条:feign-core 被解析成 provided,这是 Maven 的解析结果,不随 IDE 变。

修复

在子模块显式声明 compile,覆盖继承的 provided:

<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-core</artifactId><scope>compile</scope></dependency>

再次执行 dependency:tree,确认 scope 已变更:

修改前: io.github.openfeign:feign-core:jar:11.8:provided 修改后: io.github.openfeign:feign-core:jar:11.8:compile

Reload Maven,这次FeignClientFactoryBean初始化没有再报错。

第二个报错:feign-slf4j

重启后应用继续启动,又报:

java.lang.NoClassDefFoundError: feign/slf4j/Slf4jLogger

feign-slf4j,一模一样的 provided。它和 feign-core 同属一个 dependencyManagement 条目,一批依赖都是这个 scope。

<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-slf4j</artifactId><scope>compile</scope></dependency>

修改完 feign-slf4j,我全量跑了一次 dependency:tree,把所有 provided 依赖过一遍,确认没有遗漏再重启。这次起来了。

为什么容易被误导

编译全程不报错,provided 本来就参与编译。IDEA 里跳转、补全、代码检查一切正常,只有跑起来的那一刻类没了。

更迷惑人的是它和环境绑定:本地 IDE 里启动失败,生产可能运行正常,两边对"谁来提供这些 JAR"的假设完全不同。反复检查业务代码也查不到原因,问题不在业务代码这一层。

排查这类问题,我现在固定用两个命令:

  • mvn dependency:tree看实际解析结果,-Dincludes=groupId:artifactId过滤,多模块工程里很有用;
  • mvn help:effective-pom看最终合并生效的 POM,父 POM、import 进来的 BOM 叠了多少层一目了然。怀疑配置被继承关系修改时,先看它。

自查清单

检查项怎么查危险信号
能编译、运行时 NoClassDefFoundErrordependency:tree 看该 JAR 的 scopeprovided 或 scope 与预期不符
怀疑版本/scope 被父 POM 改了help:effective-pom 里搜 artifactId生效值和你手写的不一致
本地仓库与预期不一致mvn -v确认 local repoIDEA 和命令行指向不同仓库
同一框架多个依赖接连报错全量 dependency:tree 扫 provided同组依赖成批出现,修一个不够

老炮点评

你写的 pom.xml,从来不是你一个人的 pom.xml。父 POM 往上还有父 POM,BOM 里还能 import BOM,Maven 真正执行的是所有层合并后的那一份。你在自己这层看到的配置,和 effective-pom 里的实际内容可能完全不同。

对隐式继承的配置保持警惕,比背熟多少条 scope 规则都管用。


下期预告:《多模块工程没 install,跑起来的代码是上周的》

改了 common 包的代码,web 模块跑起来行为没有任何变化,排查很久才想起来自己根本没 install。Maven reactor、SNAPSHOT 缓存、IDEA 的工作区解析,三套规则混在一起,又踩了一次坑。

下期聊聊怎么确认自己运行的到底是哪个版本的代码。

如果本文对你有帮助,欢迎:

👍 点赞 | ⭐ 收藏 | 👤 关注 | 💬 留言

我是老炮,Java 老兵,仍在一线。关注「Java老炮踩坑录」,看真实案例,少踩坑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/12 4:53:19

编译四大阶段

一.预编译阶段&#xff08;预处理&#xff0c;gcc -E main.cpp main.i&#xff09;输入&#xff1a;.cpp源码&#xff1b;输出&#xff1a;.i预处理后的文本文件&#xff0c;仍然是C/C源码文本&#xff0c;不是机器码。1.#define宏展开&#xff0c;删除#define定义例子&#xf…

作者头像 李华
网站建设 2026/10/12 4:52:17

AI日报制作全流程:从信息采集到知识体系构建的实操方法论

1. 一份AI日报的诞生逻辑每天早上八点前&#xff0c;我会把一份大约三千字的AI日报推送到几个内部群。这个习惯从2024年延续到现在&#xff0c;中间迭代过至少五个版本。很多人以为做日报就是"把新闻复制粘贴一下"&#xff0c;但真正做过的人知道&#xff0c;一份能让…

作者头像 李华
网站建设 2026/10/12 4:52:08

UE实战进阶:架构设计、性能调优与网络同步核心指南

1. 从“能跑”到“跑得好”&#xff1a;UE实战到底在解决什么问题很多人学UE&#xff0c;前期都卡在“能跑起来”这个阶段——蓝图连上了&#xff0c;角色能动了&#xff0c;UI弹出来了&#xff0c;就觉得差不多了。但真正进入项目实战&#xff0c;你会发现“能跑”和“跑得好”…

作者头像 李华
网站建设 2026/10/12 4:51:04

小白程序员必看:LLM推理延迟的“快慢”真相与优化秘籍

本文深入剖析了LLM推理延迟的复杂性&#xff0c;指出其包含Prefill和Decode两个阶段&#xff0c;分别受GPU算力和显存带宽限制。Prefill阶段决定首token生成速度&#xff08;TTFT&#xff09;&#xff0c;主要瓶颈是计算量&#xff1b;Decode阶段决定后续token生成间隔&#xf…

作者头像 李华
网站建设 2026/10/12 4:51:04

AI时代,这10类工作将越来越香,普通人如何避开内卷安稳立足?

文章指出&#xff0c;AI正逐渐取代简单重复性工作&#xff0c;如文案、数据录入、客服等&#xff0c;而需要人际交往、复杂问题解决、情感关怀和创新能力的工作将更加有价值。普通人应关注能“搞定人”的销售、能解决复杂问题的师傅、能照顾人情绪的服务者、能带团队的管理者以…

作者头像 李华
网站建设 2026/10/12 4:50:20

JavaWeb图书管理系统源码解析:Servlet+JSP+MySQL实战教程

简介&#xff1a;这是一份基于JavaWeb的图书馆管理系统完整项目源码&#xff0c;适合正在做课程设计、毕业设计或想系统梳理服务端开发流程的学习者。项目以MVC分层为核心&#xff0c;后端使用Servlet处理业务逻辑&#xff0c;JSP完成页面展示&#xff0c;通过JDBC操作MySQL数据…

作者头像 李华