JakartaEE Maven项目中JsonbBuilder报NoClassDefFoundError求助
JakartaEE Maven项目中JsonbBuilder的NoClassDefFoundError问题解决
问题描述
在JakartaEE Maven项目中使用Jsonb/JsonbBuilder时,出现运行时错误:NoClassDefFoundError: jakarta/json/bind/JsonbBuilder,已确认Maven依赖中包含相关类,但问题依旧。
错误堆栈
java.lang.RuntimeException: jakarta/json/bind/JsonbBuilder at org.apache.tomcat.websocket.pojo.PojoMessageHandlerBase.handlePojoMethodException(PojoMessageHandlerBase.java:119) at org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBase.onMessage(PojoMessageHandlerWholeBase.java:107) at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:415) at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageText(WsFrameServer.java:129) at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:515) at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:301) at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:133) at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:85) at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:183) at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:162) at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:157) at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:60) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:59) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:870) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1762) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: java.lang.NoClassDefFoundError: jakarta/json/bind/JsonbBuilder at com.example.websockets.WebChat.onMessage(WebChat.java:21) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) at java.base/java.lang.reflect.Method.invoke(Method.java:577) at org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBase.onMessage(PojoMessageHandlerWholeBase.java:105) ... 18 more Caused by: java.lang.ClassNotFoundException: jakarta.json.bind.JsonbBuilder at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1449) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1257) ... 22 more
POM配置
<?xml version="1.0" encoding="UTF-8"?> <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>websockets</artifactId> <version>1.0-SNAPSHOT</version> <name>websockets</name> <packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.target>18</maven.compiler.target> <maven.compiler.source>18</maven.compiler.source> </properties> <dependencies> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-api</artifactId> <version>9.1.0</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.3.2</version> </plugin> </plugins> </build> </project>
报错代码及导入
抛出错误的方法
@OnMessage public void onMessage(Session session, String text) { try(Jsonb jsonb = JsonbBuilder.create()) { Message message = jsonb.fromJson(text, Message.class); System.out.println("Message received: " + message); if(message.getType().equals("join")){ session.getUserProperties().put("name", message.getUserName()); session.getUserProperties().put("active", true); Message info = new Message(message.getUserName(), "join", message.getUserName() + " has joined the chat"); Message updateUserList = new Message(message.getUserName(), "users", getUserNames(session)); sendAll(session , info); sendAll(session , updateUserList); } else if(message.getType().equals("chat")){ sendAll(session, message); } }catch (Exception e){ throw new RuntimeException(e); } }
类导入声明
import jakarta.json.Json; import jakarta.json.bind.Jsonb; import jakarta.json.bind.JsonbBuilder; import jakarta.websocket.OnClose; import jakarta.websocket.OnError; import jakarta.websocket.OnMessage; import jakarta.websocket.Session; import jakarta.websocket.server.ServerEndpoint; import java.util.stream.Collectors;
问题原因
jakarta.jakartaee-api依赖的scope设为provided,意味着该依赖仅在编译阶段提供类定义,不会被打包到项目的war包中。而Tomcat这类Servlet容器本身并不包含Jakarta JSON Binding(JSON-B)的具体实现类,仅提供API是不够的,运行时需要对应的实现才能实例化JsonbBuilder。
解决办法
1. 添加JSON-B实现依赖(推荐)
在pom.xml的<dependencies>中添加Eclipse Yasson(Jakarta JSON Binding官方实现)的依赖,它会提供JsonbBuilder的具体实现:
<dependency> <groupId>org.eclipse.yasson</groupId> <artifactId>yasson</artifactId> <version>2.0.4</version> </dependency>
版本说明:Yasson 2.x系列与Jakarta EE 9.x兼容,可根据项目需求调整版本。
2. 验证并重新部署
执行mvn dependency:tree命令查看依赖树,确认Yasson已被正确引入。之后执行mvn clean package重新打包项目,部署到Tomcat即可解决运行时类找不到的问题。
不推荐的方式
如果将jakarta.jakartaee-api的scope从provided改为compile,会把API jar打包到项目,但这可能导致与容器自带的API类冲突,引发其他问题,因此不建议采用。
内容的提问来源于stack exchange,提问作者Adrianxu
相关产品推荐
相关产品推荐

