Java EE7部署GraphQL服务遇NoSuchMethodError问题求助
NoSuchMethodError: javax.json.stream.JsonGenerator.writeKey的解决方案 问题重现
- 运行环境:Java EE7服务器
- 测试命令:
curl -X POST -H "Content-Type: application/json" -d '{"query": "query { hello }"}' http://localhost:8080/deneme2-web/graphql/graphql - 触发异常:
完整堆栈示例:java.lang.NoSuchMethodError: javax.json.stream.JsonGenerator.writeKey(Ljava/lang/String;)Ljavax/json/stream/JsonGenerator;java.lang.NoSuchMethodError: javax.json.stream.JsonGenerator.writeKey(Ljava/lang/String;)Ljavax/json/stream/JsonGenerator;
at graphql.servlet.AbstractGraphQLHttpServlet.lambda$writeGraphQLResponse$1(AbstractGraphQLHttpServlet.java:287)
at javax.json.stream.JsonGenerator.write(JsonGenerator.java:179)
at graphql.servlet.AbstractGraphQLHttpServlet.writeGraphQLResponse(AbstractGraphQLHttpServlet.java:285)
at graphql.servlet.AbstractGraphQLHttpServlet.handleRequest(AbstractGraphQLHttpServlet.java:186)
at graphql.servlet.AbstractGraphQLHttpServlet.doPost(AbstractGraphQLHttpServlet.java:145)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:688)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:615)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:818)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1623)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
问题根源
Java EE7规范集成的是JSON-P 1.0(JSR 353),该版本中JsonGenerator.writeKey(String)方法的返回值为void;而你使用的GraphQL依赖库依赖的是**JSON-P 1.1+**版本,该版本将此方法修改为返回JsonGenerator以支持链式调用,导致运行时JVM找不到匹配的方法签名,抛出NoSuchMethodError。
解决方案
1. 调整依赖版本,适配Java EE7
修改项目pom.xml,强制引入Java EE7兼容的JSON-P 1.0依赖,并排除GraphQL库传递的高版本JSON-P依赖:
<!-- Java EE7 API依赖 --> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> <!-- 强制引入JSON-P 1.0,与Java EE7兼容 --> <dependency> <groupId>javax.json</groupId> <artifactId>javax.json-api</artifactId> <version>1.0</version> <scope>provided</scope> </dependency> <!-- 引入GraphQL Servlet,排除传递的高版本JSON-P依赖 --> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java-servlet</artifactId> <version>6.1.3</version> <!-- 该版本适配Java EE7 --> <exclusions> <exclusion> <groupId>javax.json</groupId> <artifactId>javax.json-api</artifactId> </exclusion> </exclusions> </dependency> <!-- 其他GraphQL核心依赖,确保版本适配Java EE7 --> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java</artifactId> <version>11.0</version> </dependency>
2. 验证修复
- 重新执行
mvn clean package构建项目 - 重新部署到Java EE7服务器
- 再次运行原curl测试命令,确认服务正常返回结果
内容的提问来源于stack exchange,提问作者Ebuzer Taha KANAT

