Any thoughts on this issue would be appreciated.
I am accessing a Play Framework server's REST API with a Jersey 2.24.1 client. Generally I can access most API endpoints (GET, POST, PUT) fine (or seemingly so):
Response response = ClientBuilder.newClient().target("https://api.myserver.com")
.path("/getEndpointPath")
.request()
.header(HttpHeaders.AUTHORIZATION, "encoded auth string")
.get();
However, calls to DELETE methods will throw an exception when using HTTPS but will not fail exceptionally if the url is changed to use HTTP:
Response response = ClientBuilder.newClient().target("https://api.myserver.com")
.path("/deleteEndpointPath")
.request()
.header(HttpHeaders.AUTHORIZATION, "encoded auth string")
.delete();
The stack trace:
javax.ws.rs.ProcessingException: java.lang.IllegalArgumentException: protocol = https host = null
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:261)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:411)
at org.glassfish.jersey.client.JerseyInvocation$Builder.delete(JerseyInvocation.java:360)
at com.signifyd.integrationTest.v2api.HttpsTest.troubleshootDelete(HttpsTest.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
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 com.intellij.junit4.JUnit4TestRunnerUtil$IgnoreIgnoredTestJUnit4ClassRunner.runChild(JUnit4TestRunnerUtil.java:365)
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.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: protocol = https host = null
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1455)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
at sun.net.www.protocol.http.HttpURLConnection.getHeaderField(HttpURLConnection.java:2979)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:489)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:399)
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:252)
... 36 more
Caused by: java.lang.IllegalArgumentException: protocol = https host = null
at sun.net.spi.DefaultProxySelector.select(DefaultProxySelector.java:176)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1099)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:999)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177)
at sun.net.www.protocol.http.HttpURLConnection.followRedirect0(HttpURLConnection.java:2662)
at sun.net.www.protocol.http.HttpURLConnection.followRedirect(HttpURLConnection.java:2584)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1770)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
... 40 more
Also, I can access these endpoints via HTTPS using Postman, so it appears that the endpoints are not completely broken.
Any idea how this can happen?
Additional Information
The request header looks like:
INFO: 1 * Sending client request on thread main
1 > DELETE https://api.myserver.com/deleteEndpointPath
1 > Authorization: Basic THSAHASDFJalkasdlgjisadjkladfsk09A==:
I had this issue and it was a simple mistake, leaving it here in case it helps anyone else. In the code below I had omitted @PathVariable (value = "id"). Now that it's included the below works.
@DeleteMapping("/deletePosition/{id}")
public ResponseEntity<?> deletePositionById(@PathVariable (value = "id") Long positionId) {
return positionService.deletePositionById(positionId);
}