I am getting the below exception trying to make a get request using a Jersey Client. If I post requestPath into my browser, I get the expected Json response.
Result when I visit requestPath from my browser:
{ "application":[
], "error":0 }
Client client = Client.create();
client.addFilter(new ClientFilter() {
#Override
public ClientResponse handle(ClientRequest request) throws ClientHandlerException {
request.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, "application/json");
return getNext().handle(request);
}
});
WebResource webResource = client.resource(requestPath)
ClientResponse response = webResource
.accept("application/json")
.get(ClientResponse.class);
String responseStr = response.getEntity(String.class);
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.18.1</version>
</dependency>
java.lang.IllegalArgumentException: Error parsing media type 'application/json; charset=UTF-8"'
at com.sun.jersey.core.impl.provider.header.MediaTypeProvider.fromString(MediaTypeProvider.java:79)
at com.sun.jersey.core.impl.provider.header.MediaTypeProvider.fromString(MediaTypeProvider.java:53)
at javax.ws.rs.core.MediaType.valueOf(MediaType.java:119)
at com.sun.jersey.api.client.ClientResponse.getType(ClientResponse.java:695)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:612)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:586)
at MyTest.test(MyTest.java:31)
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 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.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
Caused by: java.text.ParseException: Unbalanced quoted string
at com.sun.jersey.core.header.reader.HttpHeaderReaderImpl.processQuotedString(HttpHeaderReaderImpl.java:313)
at com.sun.jersey.core.header.reader.HttpHeaderReaderImpl.process(HttpHeaderReaderImpl.java:243)
at com.sun.jersey.core.header.reader.HttpHeaderReaderImpl.next(HttpHeaderReaderImpl.java:184)
at com.sun.jersey.core.header.reader.HttpHeaderReader.nextSeparator(HttpHeaderReader.java:112)
at com.sun.jersey.core.header.reader.HttpHeaderReader.readParameters(HttpHeaderReader.java:239)
at com.sun.jersey.core.impl.provider.header.MediaTypeProvider.valueOf(MediaTypeProvider.java:97)
at com.sun.jersey.core.impl.provider.header.MediaTypeProvider.fromString(MediaTypeProvider.java:77)
... 28 more
The Content-Type header, which server returns, is broken:
java.lang.IllegalArgumentException: Error parsing media type 'application/json; charset=UTF-8"'
...
Caused by: java.text.ParseException: Unbalanced quoted string
(note dangling ")
you can workaround this like described here: How to override response header in jersey client
UPDATE
I've setup a small test as follows:
Launched a small "fake" HTTP server on the command line, which returns the broken "Content-Type" header
while true
do
cat<<EOF | nc -l 8080
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8"
Hello
EOF
done
Tried to access it with Jersey Client, as follows:
Client client = Client.create();
WebResource resource = client.resource("http://localhost:8080");
String response = resource.accept("application/json").get(String.class);
System.out.println(response);
That resulted in an Exception, looking pretty much one you have:
Exception in thread "main" java.lang.IllegalArgumentException: Error parsing media type 'application/json; charset=UTF-8"\r\n'
at com.sun.jersey.core.impl.provider.header.MediaTypeProvider.fromString(MediaTypeProvider.java:79)
at com.sun.jersey.core.impl.provider.header.MediaTypeProvider.fromString(MediaTypeProvider.java:53)
at javax.ws.rs.core.MediaType.valueOf(MediaType.java:119)
...
Caused by: java.text.ParseException: Unbalanced quoted string
at com.sun.jersey.core.header.reader.HttpHeaderReaderImpl.processQuotedString(HttpHeaderReaderImpl.java:263)
at com.sun.jersey.core.header.reader.HttpHeaderReaderImpl.process(HttpHeaderReaderImpl.java:192)
...
Now, I've added a filter to override the response "Content-Type":
client.addFilter(new ClientFilter() {
#Override
public ClientResponse handle(ClientRequest request) throws ClientHandlerException {
ClientResponse response = getNext().handle(request);
response.getHeaders().put(HttpHeaders.CONTENT_TYPE, Arrays.asList(MediaType.APPLICATION_JSON));
return response;
}
});
and then re-run the test and voila:
Hello
Related
I am currently trying to create expectations and get them verified by mockServer (can be found here).
I've read their documentation several times now but I can't find out why the verifcation of my expectation fails.
This is my code
#Rule
public MockServerRule mockServerRule = new MockServerRule(this, 9000);
private MockServerClient mockServer;
#Test
public void testVerification() {
mockServer.when(
HttpRequest.request()
.withMethod("POST")
.withPath("/validate")
.withHeader("\"Content-type\", \"application/json\"")
.withBody("{username: 'foo', password: 'bar'}"))
.respond(
HttpResponse.response()
.withStatusCode(401)
.withHeaders(
new Header("Content-Type", "application/json; charset=utf-8"),
new Header("Cache-Control", "public, max-age=86400"))
.withBody("{ message: 'incorrect username and password combination' }")
.withDelay(TimeUnit.SECONDS,1)
);
mockServer.verify(HttpRequest.request().withMethod("POST")
.withPath("/validate")
.withBody("{username: 'foo', password: 'bar'}"),
VerificationTimes.exactly(1));
}
When trying to verify, I always get the error
java.lang.AssertionError: Request not found exactly once, expected:<{
"method" : "POST",
"path" : "/validate",
"body" : "{username: 'foo', password: 'bar'}"}> but was:<>
at org.mockserver.client.server.MockServerClient.verify(MockServerClient.java:267)
at it.HttpTest.testVerification(HttpTest.java:61)
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 org.mockserver.junit.MockServerRule$1.evaluate(MockServerRule.java:107)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
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:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Well, you forgot to send a request to your mock server. You only mocked its behaviour and then you check if the server has been called, but you missed the call.
Try it with something like this:
public int callValidateUrl() throws IOException {
URL url = new URL("http://localhost:9000/validate");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
con.setDoOutput(true);
String jsonInputString = "{username: 'foo', password: 'bar'}";
try (OutputStream os = con.getOutputStream()) {
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
return con.getResponseCode();
}
If you are using Spring, RestTemplate is easier to use.
I want to create a Stub for an API and want to verify API call and response returned by the server. for that i have implemented WireMock example :
import org.junit.Rule;
import org.junit.Test;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
public class MockTestDemo {
private static final int WIREMOCK_PORT = 8080;
#Rule
public WireMockRule wireMockRule = new WireMockRule(WIREMOCK_PORT);
#Test
public void exampleTest() {
stubFor(get(urlEqualTo("/login")).withHeader("Accept", equalTo("application/json"))
.willReturn(aResponse().withStatus(200).withBody("Login Success")
.withStatusMessage("Everything was just fine!"))
.willReturn(okJson("{ \"message\": \"Hello\" }")));
verify(getRequestedFor(urlPathEqualTo("http://localhost:8080/login"))
.withHeader("Content-Type",equalTo("application/json"))); }
}
But getting below error :
com.github.tomakehurst.wiremock.client.VerificationException: Expected at least one request matching: {
"urlPath" : "localhosturl/login",
"method" : "GET",
"headers" : {
"Content-Type" : {
"equalTo" : "application/json"
}
}
}
Requests received: [ ]
at com.github.tomakehurst.wiremock.client.WireMock.verificationExceptionForNearMisses(WireMock.java:545)
at com.github.tomakehurst.wiremock.client.WireMock.verifyThat(WireMock.java:532)
at com.github.tomakehurst.wiremock.client.WireMock.verifyThat(WireMock.java:511)
at com.github.tomakehurst.wiremock.client.WireMock.verify(WireMock.java:549)
at com.wiremock.test.MockTestDemo.exampleTest(MockTestDemo.java:23)
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 com.github.tomakehurst.wiremock.junit.WireMockRule$1.evaluate(WireMockRule.java:73)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
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)
If I comment verify part then test executed successfully also i have verified the same using postman by calling http://localhost:8080/login and it returning response successfully ?
Is any thing I'm missing here ?
In your code you are stubbing out a response and then verifying that a request has been made for that stub. You are not however making a call to the endpoint and so the test is failing.
You need to invoke the endpoint before verifying that it is called.
If you use Apache Commons HttpClient, you could write your test as:
#Test
public void exampleTest() throws Exception {
stubFor(get(urlEqualTo("/login")).withHeader("Accept", equalTo("application/json"))
.willReturn(aResponse().withStatus(200).withBody("Login Success")
.withStatusMessage("Everything was just fine!"))
.willReturn(okJson("{ \"message\": \"Hello\" }")));
String url = "http://localhost:8080/login";
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
request.addHeader("Content-Type", "application/json");
request.addHeader("Accept", "application/json");
HttpResponse response = client.execute(request);
verify(getRequestedFor(urlPathEqualTo("/login"))
.withHeader("Content-Type", equalTo("application/json")));
}
Kindly, recommend using a class rule annotation/field (#ClassRule) for JUnit 4 (in those cases, where config could be reused on multiple unit tests).
#Rule could cause unexpected behaviors on async or http requests contexts, when stubs aren't registered yet.
Versions: 2.21.0 -> ... -> 2.31.0.
Note: In my particular case, had multiple tests reusing config and all the requests where executed correctly (debugging & checking mocked responses deserialized onto in-memory DTOs).
Then:
// ... WIREMOCK_PORT
#ClassRule
public static final WireMockClassRule WIRE_MOCK_RULE = new WireMockClassRule(WIREMOCK_PORT); // public
Also, recommend verifying mocked request was made to WireMock registered stubs.
Steps:
Create stub: WIRE_MOCK_RULE.stubFor(get(urlPathMatching(...))) // get, post, ...
Hit mocked endpoint with a Http client
Verify stub was invoked: verify(getRequestedFor(urlPathMatching(...)))
//{get, post, ...}RequestedFor(...) API methods for a particular HTTP request
verify(getRequestedFor(urlPathMatching("a-url-pattern"))); //urlEqualTo, ...
I have postman body as attached in the image
I am trying to call restTemplate as follows.
String body= "client_id=admin-cli&username=abc&password=root&grant_type=password";
HttpHeaders headers = new HttpHeaders();
headers.setCacheControl("no-cache");
headers.set("content-type", "application/x-www-form-urlencoded");
HttpEntity<String> request = new HttpEntity<String>(body, headers);
ResponseEntity<String> response = new RestTemplate().postForEntity(url, request, String.class);
But seems like body should not be simple string (with "&" in between values, as I am doing now). Any leads how to parse the body for the shown string in image?
Here goes the stack trace:
java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/exc/InvalidDefinitionException
at org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter.<init>(AllEncompassingFormHttpMessageConverter.java:74)
at org.springframework.web.client.RestTemplate.<init>(RestTemplate.java:179)
at io.opensaber.registry.authorization.AuthorizationFilterTest.test_valid_token(AuthorizationFilterTest.java:74)
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 org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
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.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:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 27 more
P.S. I found the issue and resolved. It was related to version incompatibility of jackson dependency.
You can put the params into the HttpEntity as a Map. See example below.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setCacheControl("no-cache");
MultiValueMap<String, String> params= new LinkedMultiValueMap<>();
params.add("client_id", "admin-cli");
params.add("username", "abc");
params.add("password", "root");
params.add("grant_type", "password");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
I tried to create SOAP client to communicate with server. Everything runs smoothly with C# but on Java I still get some exceptions.
Our company is behind proxy. SOAP service is behind basic authentication.
Small behind story:
I generated code with Java generate schema with JAX_WS from wsdl
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.9-b130926.1035
* Generated source version: 2.2
*/
#WebServiceClient(name = "ServiceWs", targetNamespace = "http://www.web.org/Schema/Klient/Service", wsdlLocation = "https://app.web.org/KlientWS/ServiceWs.wsdl")
public class ServiceWs
extends Service {
public ServiceWs(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
super(wsdlLocation, serviceName, features);
}
...
}
And with implementation authentication and cookies of some kind:
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
System.setProperty("java.net.useSystemProxies", "true");
System.setProperty("proxySet", "true");
System.setProperty("proxyHost", localProxyHost);
System.setProperty("proxyPort", localProxyPort);
System.setProperty("proxyUser", localProxyUser);
System.setProperty("proxyPassword", localProxyPassword);
String prot = getRequestingProtocol().toLowerCase();
// Requesting protocol
System.setProperty(prot + ".proxyHost", localProxyHost);
System.setProperty(prot + ".proxyPort", localProxyPort);
System.setProperty(prot + ".proxyUser", localProxyUser);
System.setProperty(prot + ".proxyPassword", localProxyPassword);
// if (getRequestorType() == RequestorType.PROXY) {
// if (getRequestingHost().toLowerCase().equals(localProxyHost.toLowerCase())) {
// if (Integer.parseInt(localProxyPort) == getRequestingPort()) {
// // Seems to be OK.
// return new PasswordAuthentication(localProxyUser, localProxyPassword.toCharArray());
// }
// }
// } else
if (getRequestorType() == RequestorType.SERVER) {
return new PasswordAuthentication(username, password.toCharArray());
}
return null;
}
});
And implementation of client
ServiceWs client;
try {
URL url = new URL(endpointAddress);
client = new ServiceWs(url);
} catch (IOException e) {
client = new ServiceWs();
}
And it just fails there with ProtocolException with too many redirections while connecting to wsdl file.
shorter version
org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
Caused by: java.net.ProtocolException: Server redirected too many times (20)
longer verison
javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.jaxws.ServiceImpl.initialize(ServiceImpl.java:163)
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:129)
at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:82)
at javax.xml.ws.Service.<init>(Service.java:77)
at xx.company.project.service.ws.ServiceWs.<init>(ServiceWs.java:45)
at xx.company.project.service.UploadWebService.fillService(UploadWebService.java:159)
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 org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
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.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
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:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:87)
at org.apache.cxf.jaxws.ServiceImpl.initializePorts(ServiceImpl.java:218)
at org.apache.cxf.jaxws.ServiceImpl.initialize(ServiceImpl.java:161)
... 35 more
Caused by: javax.wsdl.WSDLException: WSDLException: faultCode=PARSER_ERROR: Problem parsing 'https://app.web.org/KlientWS/ServiceWs.wsdl'.: java.net.ProtocolException: Server redirected too many times (20)
at com.ibm.wsdl.xml.WSDLReaderImpl.getDocument(WSDLReaderImpl.java:2198)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(WSDLReaderImpl.java:2390)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(WSDLReaderImpl.java:2422)
at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:265)
at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:164)
at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:85)
... 37 more
Caused by: java.net.ProtocolException: Server redirected too many times (20)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1884)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.getDocument(WSDLReaderImpl.java:2188)
... 42 more
I know authentication details are correct and web address is correct, as I can connect to the wsdl file manually.
The problem was, as #beat suggested in the proxy settings. I have not set the NTLM properly, as our proxy user is in different domain.
The code to be set was System.setProperty("http.auth.ntlm.domain", domain); and after setting this everything started to work as intended.
More to be seen in J2SE Proxy Authentication.
private void createAuthentication(String localProxyHost, String localProxyPort,
String localProxyUser, String localProxyPassword, String domain,
String username, String password) {
if (!prepared) {
System.setProperty("java.net.useSystemProxies", "true");
System.setProperty("http.auth.ntlm.domain", domain);
System.setProperty("proxyHost", localProxyHost);
System.setProperty("proxyPort", localProxyPort);
System.setProperty("proxyUser", localProxyUser);
System.setProperty("proxyPassword", localProxyPassword);
prepared = true;
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password.toCharArray());
}
});
}
}
As requested by Polostor, I try to write an answer. NTLMv2 Proxies are authenticating the user, and if not sucessful redirect you.
As I had a lot of issues with different proxies at different sites, I do recommend using proxy-vole. This will do an automatic setup of your proxies based on the platform settings.
I have rest service(PUT) which I intend to unit test it. I am using RestEasy for the Rest calls.
Here is my Resource :
#Path("/my_person")
public class MyResource {
private MyDAO myDao;
#Inject
public MyResource(MyDao myDao) {
this.myDao = myDao;
}
#PUT
#Timed
#Path("purchase_number/{purchaseNumber}/amount/{amount}/number_of_items")
#Produces(MediaType.APPLICATION_JSON)
public Response getItems(#PathParam("purchaseNumber") String purchaseNumber,
#PathParam("amount") String amount) {
return Response.ok(String.format("{\"items\": %d}", myDao.getItems(purchaseNumber, amount))).build();
}
}
The myDao.getItems returns an integer.
My Test class is as follows :
#RunWith(MockitoJUnitRunner.class)
public class MyResourceTest {
#Mock
private MyDao myDao;
#InjectMock
private MyResource myResource;
private TJWSEmbeddedJaxrsServer server;
private ResteasyClient resteasyClient;
#Before
public void startServer() throws IOException {
resteasyClient = new ResteasyClientBuilder().build();
server = new TJWSEmbeddedJaxrsServer();
server.setPort(PORT);
server.setBindAddress("localhost");
server.getDeployment().getResources().add(myResource);
server.start();
}
#After
public void stopServer() {
if (server != null) {
server.stop();
server = null;
}
}
#Test
public void testWhenValidInputGiven() {
String purchaseNumber = "A57697DF";
String amount = "340";
when(myDao.getItems(purchaseNumber, amount)).thenReturn(10);
Response response = resteasyClient.target("http://localhost:9980/my_person/purchase_number/{purchaseNumber}/amount/{amount}/number_of_items").request().buildPut(Entity.entity("{}", MediaType.APPLICATION_JSON))).invoke();
String text = response.getEntity().toString();
assertEquals(200, resp.getStatus());
assertEquals("{\"items\": 10}", text);
}
}
I get the following error at String text = response.getEntity().toString() since the entity object is null. So does it mean that it didn't create the request at all?
java.lang.NullPointerException
at resources.MyResourceTest.testWhenValidInputGiven(MyResourceTest.java:126)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
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.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:427)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:376)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179)
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
at org.jboss.resteasy.plugins.server.tjws.TJWSServletDispatcher.service(TJWSServletDispatcher.java:40)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at Acme.Serve.Serve$ServeConnection.runServlet(Serve.java:2331)
at Acme.Serve.Serve$ServeConnection.parseRequest(Serve.java:2285)
at Acme.Serve.Serve$ServeConnection.run(Serve.java:2057)
at Acme.Utils$ThreadPool$PooledThread.run(Utils.java:1402)
at java.lang.Thread.run(Thread.java:745)
Have you tried to put / in front of you method path #Path("/purchase_number/{purchaseNumber}/amount/{amount}/number_of_items")
i think the framework misunderstood your path and expect my_personpurchase_number/.
Check your status code on response to see if actually get 200 back or a 404.
The solution to this problem was that I was using
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
instead of
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<version>3.0.10.Final</version>
</dependency>
both had the class javax.ws.rs.core.Response.