Java Web项目出现NoSuchMethodError: MultivaluedMap.addAll问题求助
排查Jersey依赖版本不兼容导致的
NoSuchMethodError问题 我来帮你分析这个问题——你遇到的java.lang.NoSuchMethodError核心原因确实是编译时和运行时的JAX-RS/Jersey依赖版本不匹配,具体来说是运行时的MultivaluedMap类缺少编译时用到的addAll方法。结合你的pom.xml和操作尝试,我给你梳理下问题点和修复步骤:
问题场景与已尝试操作
场景说明
基于Java 1.8、Jersey开发动态Web应用,Maven管理依赖,开发环境为Eclipse Oxygen + Tomcat 9,运行时抛出以下栈跟踪:
java.lang.NoSuchMethodError: javax.ws.rs.core.MultivaluedMap.addAll(Ljava/lang/Object;[Ljava/lang/Object;)V at org.glassfish.jersey.client.ClientRequest.accept(ClientRequest.java:335) at org.glassfish.jersey.client.JerseyWebTarget.request(JerseyWebTarget.java:222) at org.glassfish.jersey.client.JerseyWebTarget.request(JerseyWebTarget.java:60) at com.simfinit.client.SimDcmClient.get(SimDcmClient.java:36) at com.simfinit.client.SimDcmClientTest.testGetList(SimDcmClientTest.java:19) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
已尝试操作
- 调整组件版本
- 删除
.m2/repository并执行Maven/Update Project刷新环境
但问题仍未解决。
问题分析(从你的pom.xml入手)
你的pom.xml存在几个关键的版本兼容问题:
- Jersey BOM未生效:你导入了
jersey-bom但没有定义${jersey.version}变量,导致BOM无法统一管理所有Jersey依赖的版本,很容易出现版本混乱。 - 显式引入的JAX-RS API版本与Jersey不兼容:你直接引入了
javax.ws.rs-api:2.1,但Jersey 2.26及以上版本才对应JAX-RS 2.1,旧版本Jersey只支持JAX-RS 2.0——而JAX-RS 2.0的MultivaluedMap并没有这个addAll重载方法。 - 客户端依赖缺失:错误出在客户端代码
SimDcmClient中,但你的pom里没有显式引入jersey-client依赖,可能导致依赖版本不全。
修复步骤及完整pom.xml示例
1. 定义Jersey版本并启用BOM统一管理
在pom.xml中添加<properties>块,指定兼容Java 8和JAX-RS 2.1的Jersey版本(比如2.29.1,这是Java 8支持的较新版本):
<properties> <jersey.version>2.29.1</jersey.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties>
2. 移除显式的JAX-RS API依赖
Jersey BOM已经包含了兼容版本的javax.ws.rs-api,显式引入会导致版本冲突,所以注释或删除该依赖。
3. 添加必要的Jersey客户端依赖
因为错误出在客户端代码,必须确保jersey-client被正确引入,且版本由BOM管理。
4. 清理并重新构建
- 执行
mvn clean install彻底清理并重新构建项目 - 在Eclipse中执行
Maven -> Update Project,勾选Force Update of Snapshots/Releases - 检查Tomcat部署目录下的
WEB-INF/lib,确保没有旧版本的JAX-RS/Jersey jar包(如果Tomcat自带了相关jar,需要删除Tomcat/lib下的冲突文件)
修复后的完整pom.xml示例
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.simfinit.resources</groupId> <artifactId>SimWebServiceDcm</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>SimWebServiceDcm</name> <!-- 统一管理版本属性 --> <properties> <jersey.version>2.29.1</jersey.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <build> <finalName>SimWebServiceDcm</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <inherited>true</inherited> <configuration> <source>${maven.compiler.source}</source> <target>${maven.compiler.target}</target> </configuration> </plugin> </plugins> </build> <dependencyManagement> <dependencies> <dependency> <groupId>org.glassfish.jersey</groupId> <artifactId>jersey-bom</artifactId> <version>${jersey.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 移除显式的JAX-RS API依赖,由BOM统一管理 --> <!-- <dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> <version>2.1</version> </dependency> --> <!-- Jersey Servlet容器依赖 --> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet-core</artifactId> <!-- 若无需Servlet 2.x兼容性,可替换为jersey-container-servlet --> <!-- <artifactId>jersey-container-servlet</artifactId> --> </dependency> <!-- Jersey客户端依赖(解决客户端代码的方法缺失问题) --> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-client</artifactId> </dependency> <!-- JUnit测试依赖 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project>
额外检查点
如果修复后仍有问题,检查Tomcat的lib目录是否存在javax.ws.rs-api或旧版本Jersey的jar包,如果有,直接删除这些文件——Tomcat自带的旧版本依赖会覆盖你的应用依赖,导致版本不匹配。
内容的提问来源于stack exchange,提问作者bluemonkey
相关产品推荐
相关产品推荐

