使用Jersey客户端发送PATCH请求时遇JDK17反射访问错误如何解决?
Jersey客户端JDK17下发送PATCH请求报错解决方案
问题描述
我尝试用Jersey客户端发送PATCH请求,代码如下:
WebTarget target = client.target(url); client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND,true); Response response = target .request(MediaType.APPLICATION_JSON_PATCH_JSON) .header("Authorization", "Bearer " + token) .method("PATCH", Entity.json(JSONUtils.convertToJSON(List.of(startStopPayload))));
但收到如下错误:
jakarta.ws.rs.ProcessingException: Unable to make field private final sun.net.www.protocol.https.DelegateHttpsURLConnection sun.net.www.protocol.https.HttpsURLConnectionImpl.delegate accessible: module java.base does not "opens sun.net.www.protocol.https" to unnamed module @47f37ef1 at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:309) at org.glassfish.jersey.client.JerseyInvocation.lambda$invoke$0(JerseyInvocation.java:662) at org.glassfish.jersey.client.JerseyInvocation.call(JerseyInvocation.java:697) at org.glassfish.jersey.client.JerseyInvocation.lambda$runInScope$3(JerseyInvocation.java:691) at org.glassfish.jersey.internal.Errors.process(Errors.java:292) at org.glassfish.jersey.internal.Errors.process(Errors.java:274) at org.glassfish.jersey.internal.Errors.process(Errors.java:205) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:390) at org.glassfish.jersey.client.JerseyInvocation.runInScope(JerseyInvocation.java:691) at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:661) at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:439) at com.oracle.blockchain.opcp.restserver.client.k8s.K8sBlockchainPlatformInstanceClient.stopInstance(K8sBlockchainPlatformInstanceClient.java:183) at com.oracle.blockchain.opcp.restserver.client.k8s.K8sBlockchainPlatformInstanceClient$Proxy$_$$_WeldClientProxy.stopInstance(Unknown Source) at com.oracle.blockchain.opcp.restserver.manager.BPServiceManager.stopBlockchainPlatform(BPServiceManager.java:749) at com.oracle.blockchain.opcp.restserver.manager.BPServiceManager$Proxy$_$$_WeldSubclass.stopBlockchainPlatform(Unknown Source) at com.oracle.blockchain.opcp.restserver.manager.BPServiceManager$Proxy$_$$_WeldClientProxy.stopBlockchainPlatform(Unknown Source) at com.oracle.blockchain.opcp.restserver.resources.BlockchainPlatformResource.stopBlockchainPlatform(BlockchainPlatformResource.java:393) at com.oracle.blockchain.opcp.restserver.resources.BlockchainPlatformResource$Proxy$_$$_WeldClientProxy.stopBlockchainPlatform(Unknown Source) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:134) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:177) at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:81) at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:478) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:400) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81) at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) at org.glassfish.jersey.internal.Errors.process(Errors.java:292) at org.glassfish.jersey.internal.Errors.process(Errors.java:274) at org.glassfish.jersey.internal.Errors.process(Errors.java:244) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265) at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234) at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684) at io.helidon.webserver.jersey.JerseySupport$JerseyHandler.lambda$doAccept$4(JerseySupport.java:334) at io.helidon.common.context.Contexts.runInContext(Contexts.java:117) at io.helidon.common.context.ContextAwareExecutorImpl.lambda$wrap$7(ContextAwareExecutorImpl.java:154) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:833)
我已经尝试添加client.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND,true);,当前使用JDK17,请问该如何解决这个错误?
解决方案
1. 升级Jersey版本到兼容JDK17的版本
旧版本Jersey的HttpUrlConnector在JDK17的模块系统下,会通过反射访问JDK内部类,而JDK17收紧了模块访问权限导致报错。升级到Jersey 3.1.0及以上版本,该版本已修复JDK17兼容性问题,无需依赖反射处理PATCH请求。
2. 替换HTTP连接器
如果暂时无法升级Jersey,可以替换默认的HttpUrlConnector为兼容JDK17的Apache HttpClient连接器:
- 添加Apache HttpClient依赖(以Maven为例):
<dependency> <groupId>org.glassfish.jersey.connectors</groupId> <artifactId>jersey-apache-connector</artifactId> <version>你的Jersey版本</version> </dependency> - 创建客户端时指定使用Apache连接器:
该连接器发送PATCH请求时,无需设置ClientConfig config = new ClientConfig(); config.connectorProvider(new ApacheConnectorProvider()); Client client = ClientBuilder.newClient(config);SET_METHOD_WORKAROUND,也不会触发反射访问JDK内部类的问题。
3. 临时JVM参数(不推荐)
如果以上方案无法实施,可通过JVM参数临时开放模块访问权限,但会破坏JDK封装性,仅作应急使用:
--add-opens java.base/sun.net.www.protocol.https=ALL-UNNAMED
内容的提问来源于stack exchange,提问作者Mehul
相关产品推荐
相关产品推荐

