Spring Boot 3.1.0集成Snakeyaml 2.0遇NoSuchMethodError问题求助
为了使用无漏洞的Snakeyaml 2.0版本,我将Spring Boot从2.7.12升级至3.1.0,同步升级了Gradle与Java版本。但运行应用时出现如下错误,提示Snakeyaml 2.0不兼容,请问该如何解决?
16:38:31.540 [main] ERROR org.springframework.boot.SpringApplication - Application run failed java.lang.NoSuchMethodError: org.yaml.snakeyaml.representer.Representer: method 'void <init>()' not found at org.springframework.boot.env.OriginTrackedYamlLoader.createYaml(OriginTrackedYamlLoader.java:74) at org.springframework.boot.env.OriginTrackedYamlLoader.createYaml(OriginTrackedYamlLoader.java:69) at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:164) at org.springframework.boot.env.OriginTrackedYamlLoader.load(OriginTrackedYamlLoader.java:82) at org.springframework.boot.env.YamlPropertySourceLoader.load(YamlPropertySourceLoader.java:50) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.loadDocuments(ConfigFileApplicationListener.java:632) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:534) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.loadForFileExtension(ConfigFileApplicationListener.java:501) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:471) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.lambda$null$7(ConfigFileApplicationListener.java:450) at java.base/java.lang.Iterable.forEach(Iterable.java:75) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.lambda$load$8(ConfigFileApplicationListener.java:450) at java.base/java.lang.Iterable.forEach(Iterable.java:75) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:447) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.lambda$load$0(ConfigFileApplicationListener.java:350) at org.springframework.boot.context.config.FilteredPropertySource.apply(FilteredPropertySource.java:54) at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:338) at org.springframework.boot.context.config.ConfigFileApplicationListener.addPropertySources(ConfigFileApplicationListener.java:229) at org.springframework.boot.context.config.ConfigFileApplicationListener.postProcessEnvironment(ConfigFileApplicationListener.java:213) at org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEnvironmentPreparedEvent(ConfigFileApplicationListener.java:203) at org.springframework.boot.context.config.ConfigFileApplicationListener.onApplicationEvent(ConfigFileApplicationListener.java:191) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:80) at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53) at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345) at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140) at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:212) at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:117) at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:74) at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:80) at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53) at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345) at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) at rf.dom.billing.ap.Application.main(Application.java:24)
这个错误根源是SnakeYAML 2.0移除了Representer的无参构造函数,而Spring Boot 3.1.0内置的SnakeYAML版本(1.33)还依赖这个构造函数,手动升级到2.0后出现API不兼容。可以通过以下几种方式解决:
方法1:使用Spring Boot默认维护的SnakeYAML版本
Spring Boot 3.1.x默认依赖的SnakeYAML 1.33已经修复了已知安全漏洞,完全不需要手动升级到2.0。直接移除Gradle中手动指定的SnakeYAML依赖,让Spring Boot的依赖管理自动处理即可:dependencies { // 移除这行手动指定的依赖 // implementation 'org.yaml:snakeyaml:2.0' // 其他项目依赖... }方法2:升级到兼容SnakeYAML 2.0的Spring Boot版本
Spring Boot 3.2.0及以上版本已经适配了SnakeYAML 2.0。如果一定要用SnakeYAML 2.0,直接把Spring Boot升级到3.2.x版本即可,无需额外配置。方法3:自定义YAML加载器(不推荐)
如果既无法升级Spring Boot又必须用SnakeYAML 2.0,只能自定义YamlPropertySourceLoader替换Spring Boot默认实现,手动创建带参数的Representer实例。但这种方式需要修改Spring Boot内部逻辑,维护成本极高,不建议采用。
内容的提问来源于stack exchange,提问作者Eljah

