尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

解决IntelliJ IDEA中Spring Boot项目JDK 13+的-noverify废弃警告

解决IntelliJ IDEA中Spring Boot项目JDK 13+的-noverify废弃警告 1. 问题现象与初步诊断如果你在用 IntelliJ IDEA 运行或调试 Spring Boot 项目时突然在控制台看到一行醒目的红色警告内容大概是Java HotSpot(TM) 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.心里肯定会“咯噔”一下。这个提示虽然不会立刻导致程序崩溃但它像一个黄色的警示灯告诉你项目的运行环境存在一些不匹配或过时的配置。作为一名常年与 IDEA 和 Spring Boot 打交道的开发者我几乎在每个新版本 JDK 升级的过渡期都会遇到类似问题。它本质上不是代码错误而是 JVM 启动参数与当前使用的 JDK 版本不兼容的信号。今天我们就来彻底拆解这个“爆红”警告从根因分析到解决方案让你不仅知其然更知其所以然。简单来说这个警告的核心矛盾点在于你的 Spring Boot 项目或其依赖的某个库试图使用一个已经被新版本 JDK 标记为“废弃”并即将“移除”的 JVM 参数。最常见的“罪魁祸首”就是-noverify或-Xverify:none。在 JDK 13 之前这两个参数常用于关闭字节码验证器以换取应用程序尤其是使用某些动态字节码生成技术的框架如 Spring、Hibernate的启动速度。但从 JDK 13 开始Oracle 正式弃用了它们并在后续版本中逐步推进移除计划。因此当你使用 JDK 13 及以上版本比如现在主流的 JDK 17、JDK 21运行一个仍携带这些旧参数的 Spring Boot 应用时JVM 就会友好地但用刺眼的红色提醒你“喂你用的这个参数我不推荐用了未来可能直接不让用了”所以这个问题适合所有使用 IntelliJ IDEA 进行 Java/Spring Boot 开发的开发者无论是刚入门的新手还是正在升级技术栈的老手。解决它不仅是消除一个碍眼的警告更是确保你的开发环境符合现代 JDK 标准避免未来兼容性风险的必要步骤。2. 警告根源深度剖析为什么是-noverify要彻底解决必须先理解根源。让我们深入 JVM 的字节码验证机制。2.1 字节码验证器与启动性能的博弈Java 程序运行在 JVM 上.class文件中的字节码需要被验证其合法性和安全性防止恶意代码破坏 JVM 稳定性。这个过程由“字节码验证器”完成。然而严格的验证会消耗时间对于大型应用特别是大量使用反射、动态代理、字节码增强AOP的 Spring Boot 应用验证阶段可能显著拖慢启动速度。为了优化启动体验历史上引入了-noverify和-Xverify:none这两个 JVM 参数。它们的作用是告诉 JVM“跳过字节码验证这一步我信任这些字节码是安全的。” 这在开发阶段尤其是需要频繁重启应用的场景下能带来可感知的启动速度提升。2.2 JDK 13 的变革与弃用原因那么为什么从 JDK 13 开始要弃用它们呢这背后是 Java 平台安全性和模块化演进的大趋势。安全模型强化随着 Java 应用场景越来越复杂尤其是在云原生和微服务架构下安全性被提到前所未有的高度。完全关闭字节码验证相当于解除了一道重要的安全防线与平台整体安全加固的方向背道而驰。模块化系统JPMS的影响Java 9 引入了模块化系统。模块化带来了更严格的封装和依赖管理其内置的访问控制机制与传统的字节码验证有部分功能重叠。在某些场景下绕过验证可能与模块化的安全约束产生冲突。启动性能的替代优化JVM 团队并没有忽视启动性能的需求。他们通过其他方式持续优化例如 CDSClass Data Sharing、AOTAhead-of-Time Compilation等特性旨在不牺牲安全性的前提下提升启动速度。因此-noverify这种“一刀切”的粗暴优化方式就显得不合时宜了。因此这个警告是 JVM 给你的一个明确信号是时候放弃这种旧的、有安全隐患的优化手段拥抱更现代、更安全的启动方式了。2.3 参数是如何被传递的在 Spring Boot 项目中这个废弃参数通常通过以下几种途径被引入IDEA 运行配置你可能在项目早期手动编辑过运行配置在VM options中添加了-noverify。Maven/Gradle 插件配置Spring Boot Maven 插件或 Gradle 插件在旧版本中可能默认或通过某些配置添加了这些参数。第三方依赖或工具某些旧的库或代码生成工具如 Lombok 的旧版本、某些 AOP 工具在其启动脚本或配置中可能硬编码了这些参数。环境变量或全局配置系统环境变量JAVA_TOOL_OPTIONS或JDK_JAVA_OPTIONS中可能包含它影响了所有 Java 进程。注意很多时候开发者自己并没有显式配置过-noverify但它可能被“继承”或“默认启用”了。尤其是在从旧项目迁移或使用某些网络上的“优化配置”脚本时容易中招。3. 多维度排查与解决方案实战知道了原因我们来动手解决。请按照以下步骤系统性排查通常能快速定位并解决问题。3.1 第一步检查并清理 IDEA 运行配置这是最直接、最常见的源头。在 IDEA 中找到你的 Spring Boot 主类带有SpringBootApplication注解的类或对应的Application类。在主类上右键选择Run ‘YourApplication.main()‘或Debug ‘YourApplication.main()‘先运行一次。这会在 IDEA 顶部生成一个运行配置标签。点击运行配置标签旁边的下拉箭头选择Edit Configurations...。在弹出的窗口中左侧列表中找到你刚才运行的配置通常与你的应用同名。在右侧的配置面板中找到Modify options下拉菜单确保Add VM options是勾选状态。如果未勾选请勾选它。此时下方会出现VM options输入框。仔细检查这个输入框里的内容。如果发现-noverify或-Xverify:none请直接删除它们。如果框内还有其他你需要的 JVM 参数如-Xmx,-Dspring.profiles.active等请保留它们只删除有问题的参数。点击Apply然后点击OK。重新运行你的应用观察控制台警告是否消失。实操心得有时候一个项目会有多个运行配置比如用于测试的、用于不同环境的。务必检查所有相关的运行配置特别是那些你很久没使用但可能被默认激活的配置。一个快速的方法是在Edit Configurations窗口的左侧浏览所有类型为Application的配置逐一检查。3.2 第二步检查构建工具插件配置如果清理了 IDEA 配置后警告依旧那么问题可能埋藏在项目的构建脚本中。对于 Maven 项目 (pom.xml) 检查spring-boot-maven-plugin的配置。build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId configuration !-- 重点检查jvmArguments参数 -- jvmArguments-Xmx512m -noverify/jvmArguments !-- 错误的示例 -- !-- 或者检查agents -- agents agent-noverify/agent /agents /configuration /plugin /plugins /build如果发现jvmArguments或agents中包含-noverify请将其移除。移除后应该是jvmArguments-Xmx512m/jvmArguments !-- 移除了 -noverify -- !-- 或者直接删除整个 jvmArguments 行如果只有这一个参数的话 --对于 Gradle 项目 (build.gradle或build.gradle.kts) 检查bootRun任务的配置。bootRun { jvmArgs [-noverify, -Xmx512m] // 错误的示例 }或tasks.withTypeBootRun { jvmArgs listOf(-noverify, -Xmx512m) // 错误的示例 }同样将-noverify从参数列表中删除。重要提示在修改构建脚本后必须重新导入项目或重新加载 Gradle/Maven 项目以确保 IDEA 使用最新的配置。在 IDEA 中对 Maven 项目可以点击右侧 Maven 工具栏的刷新按钮对 Gradle 项目可以点击右侧 Gradle 工具栏的刷新按钮。3.3 第三步排查环境变量与全局配置有时候“锅”不在项目本身而在你的操作系统环境。检查系统环境变量Windows在“系统属性” - “高级” - “环境变量”中检查JAVA_TOOL_OPTIONS和JDK_JAVA_OPTIONS这两个用户变量和系统变量。macOS/Linux在终端中执行echo $JAVA_TOOL_OPTIONS和echo $JDK_JAVA_OPTIONS。 如果这些变量中包含-noverify你需要决定是否删除。请注意修改这些变量会影响所有 Java 程序请谨慎操作。对于开发机通常建议清理这些过时的全局配置。检查 IDEA 的全局 VM 选项打开 IDEA进入File-Settings(Windows/Linux) 或IntelliJ IDEA-Preferences(macOS)。导航到Build, Execution, Deployment-Build Tools-Maven-Runner(对于 Maven 项目) 或Build, Execution, Deployment-Build Tools-Gradle-Runner(对于 Gradle 项目)。查看VM Options字段是否被全局设置。如果这里有-noverify将其移除。3.4 第四步升级依赖与插件版本如果上述步骤都做了问题仍然存在可能是某个第三方依赖在“作祟”。一些旧的库特别是那些涉及字节码操作的如旧版本的 ASM、CGLIB、ByteBuddy 或某些 APT 工具可能会在背后传递这些参数。升级 Spring Boot 相关插件确保你使用的spring-boot-maven-plugin或org.springframework.bootGradle 插件是最新稳定版。新版本通常已经移除了对废弃参数的使用。检查并升级其他可疑依赖在pom.xml或build.gradle中检查是否有明显过时的、与字节码处理相关的依赖。可以使用mvn dependency:tree或gradle dependencies命令查看依赖树寻找线索。特别关注 LombokLombok 是一个常见的“嫌疑犯”。确保你使用的是较新版本的 Lombok例如 1.18.30 及以上并且 IDEA 中安装的 Lombok 插件也是最新的。旧版 Lombok 可能与新 JDK 存在兼容性问题。排查技巧一个比较取巧的方法是在 IDEA 的运行配置中VM options里暂时加上-XX:ShowVMOptions -XX:PrintCommandLineFlags。再次运行应用控制台会打印出所有最终生效的 JVM 参数及其来源。你可以仔细查看输出看-noverify是从哪一行参数中带出来的这能帮你精准定位源头。4. 替代方案与最佳实践告别-noverify之后移除了-noverify你可能会担心启动速度变慢。实际上对于现代 JDK17和 Spring Boot 2.7/3.x启动性能已经得到了极大优化。以下是一些更安全、更现代的加速启动方案4.1 使用 JDK 的现代特性类数据共享 (CDS)JDK 12 引入了应用程序类数据共享 (AppCDS)可以显著减少大型应用的启动时间。Spring Boot 从 2.3 版本开始提供了对创建和使用 AppCDS 存档的原生支持。你可以通过构建工具插件来启用它。提前编译 (AOT)Spring Boot 3 和 Spring Framework 6 加强了对 GraalVM 原生镜像的支持通过 AOT 编译将应用编译成本地可执行文件彻底消除 JVM 启动开销。这虽然主要针对生产环境但代表了未来的方向。4.2 优化 Spring Boot 应用本身延迟初始化在 Spring Boot 2.2 及以上版本可以在application.properties中设置spring.main.lazy-initializationtrue。这会让 Spring 容器延迟创建 Bean直到首次被请求时可以大幅加快启动速度但可能会对第一个请求的响应时间有轻微影响。这是一个非常有效的、安全的替代-noverify的方案特别适合开发阶段。排除不必要的自动配置使用SpringBootApplication(exclude {SomeAutoConfiguration.class})来排除你确定用不到的自动配置类。精简依赖定期使用mvn dependency:analyze检查未使用的依赖保持pom.xml整洁。4.3 配置 IDEA 优化开发体验使用“更新”动作而非“重启”在开发过程中利用 Spring Boot DevTools 和 IDEA 的“更新”功能快捷键 CtrlF10 / CmdF10 on Mac只重新加载变更的类而不是重启整个 JVM这比任何启动参数优化都直接有效。调整 JVM 堆大小为开发环境配置合理的初始堆 (-Xms) 和最大堆 (-Xmx) 大小避免频繁的堆扩容。例如-Xms256m -Xmx1024m。5. 常见问题与疑难排查实录在实际操作中你可能会遇到一些变体或复杂情况。这里记录几个我踩过的坑和解决方案。5.1 警告变体关于illegal reflective access等其他警告有时移除-noverify后你可能会看到关于“非法反射访问”的警告。这是另一个问题但与 JDK 版本升级也紧密相关。它是因为某些库如旧版本的 Hibernate、Spring 等使用了 JDK 内部 API而这些 API 在 JDK 9 模块化后不再被允许随意访问。解决方案升级库版本这是根本方法确保所有主要依赖Spring Boot, Hibernate, Jackson 等都升级到与你的 JDK 版本兼容的较新版本。添加 JVM 参数临时方案如果暂时无法升级可以添加--add-opens或--add-exports参数来显式打开模块。但这不是长久之计应尽快安排依赖升级。--add-opens java.base/java.langALL-UNNAMED --add-opens java.base/java.utilALL-UNNAMED注意这需要根据具体警告信息来添加切勿盲目添加所有。5.2 多模块项目中的配置继承在多模块的 Maven 或 Gradle 项目中父模块的插件配置可能会被子模块继承。如果你在父pom.xml的插件管理里配置了废弃的 JVM 参数那么所有子模块都会受到影响。排查方法仔细检查父项目的pom.xml中pluginManagement部分和build部分确保没有全局配置-noverify。同样在 Gradle 的多项目构建中检查根项目的build.gradle中是否有被所有子项目应用的allprojects或subprojects配置块。5.3 使用了特定版本的 JDK如 Zulu JDK、Amazon Corretto这些发行版 JDK 通常与 Oracle OpenJDK 行为一致。警告的出现和处理方式完全相同。但请确保你 IDEA 中“Project Structure”里设置的 JDK 版本与你运行配置使用的 JDK 版本一致。有时 IDEA 运行配置会默认使用系统环境变量JAVA_HOME指向的 JDK而项目模块使用的是另一个 JDK版本不一致也可能引发奇怪的问题。检查路径File-Project Structure-Project-SDK以及Modules-Dependencies-Module SDK。确保它们指向同一个正确的、版本符合要求的 JDK。5.4 问题排查速查表问题现象可能原因优先检查点解决方案控制台红字提示-noverify deprecated运行配置包含废弃参数IDEA Run/Debug Configuration 中的 VM options删除-noverify或-Xverify:none清理运行配置后警告仍在构建脚本中插件配置了参数Mavenpom.xml中的spring-boot-maven-plugin或 Gradlebuild.gradle中的bootRun移除构建脚本中的废弃参数并重新导入项目警告在多个项目中出现系统环境变量或IDEA全局配置系统变量JAVA_TOOL_OPTIONS, IDEA全局Maven/Gradle Runner设置清理环境变量和全局设置中的废弃参数升级JDK后出现警告依赖库或插件版本过旧Spring Boot、Maven插件、Lombok等依赖版本升级相关依赖到与当前JDK兼容的新版本警告伴随其他反射警告依赖库使用了JDK内部API根据警告信息定位具体模块和包升级库版本或临时添加--add-opens参数最后我的个人体会是面对这类环境配置警告最好的态度就是“零容忍”。立即解决它而不是忽略它。这不仅能保持开发环境的整洁更能迫使你跟上 JDK 和生态发展的步伐避免技术债的累积。每次 JDK 升级都是一次检查和优化项目配置的好机会。现在就去你的 IDEA 里检查一下和那个烦人的红色警告说再见吧。
返回列表