I'm using java.net.http.HttpClient.newHttpClient() under Java 19 (Temurin) and perform sendAsync(...) requests from different treads on the same instance. I assume this is ok, as the javadoc states:
Once built, an HttpClient is immutable...
However, some requests fail with:
java.io.IOException: HTTP/1.1 header parser received no bytes
The weird thing is, it depends on the speed of my requests:
Requests every 5 seconds: 30% failure
Requests every 3 seconds: 0% failure
I've written a test for it:
private final HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://..."))
.setHeader("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofByteArray("[]".getBytes()))
.build();
#ParameterizedTest
#ValueSource(ints = {3, 5})
void httpClientTest(int intervalSeconds) throws Exception {
HttpClient httpClient = HttpClient.newHttpClient();
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
}
I've already tried the following:
Doing the same with curl on the command line. No requests fail whatever interval I try. So it's probably not a problem with the server.
Running the tests multiple times in parallel. Still the 5-second-intervals fail (then multiple times in parallel). So it's probably not a problem with the server.
Creating an HttpClient.newHttpClient() for every request. No requests fail whatever interval. So it's probably not a problem with the server but with an internal state of the HttpClient (although it claims to be immutable?).
Do you have an idea what I could do, without needing to create a new HttpClient for every request?
Here is the answer for the record: the java.net.HttpClient has a long default HTTP/1.1 keepAlive time, which is longer than what usual servers are configured with. This often results in the server closing idle HTTP/1.1 connections before the client does. If the server closes the connection at about the same time than the client tries to reuse it, some IOException might get raised.
If such exceptions are observed too frequently applications should consider adapting the default keepAlive time in the client to some value shorter than what the servers it connects to are using.
A default value for the HttpClient HTTP/1.1 keepAlive time can be specified on the command line with: -Djdk.httpclient.keepalive.timeout=duration-in-seconds
So for instance - if a server is configured with a keepAlive time of 5s, you could consider supplying -Djdk.httpclient.keepalive.timeout=3 or -Djdk.httpclient.keepalive.timeout=4 on the client's java command line.
I have a grails 3 application using the grails.plugins.rest.client plugin to make calls to another API.The api performs some actions and responds in 40 to 50 seconds. The grails application timeout and returns a server error in 30 seconds. How can I change the timeout to wait for a response 60 seconds. My code is as follows:
import grails.plugins.rest.client.RestBuilder
import grails.plugins.rest.client.RestResponse
private RestBuilder rest = new RestBuilder()
RestResponse resp = rest.post(url) {
header 'Accept', "application/json"
json(data)
}
// more code
If you want to increase the socket timeout the grails rest client supports two options.
connectionTimeout
readTimeout
These options are to be set on the RestBuilder when it is instantiated. You cannot change this for request
types which is a shame.
To set them, you can use the below format. But bear in mind that it requires a change to the code and rebuilding the war file.
private RestBuilder rest = new RestBuilder(readTimeout: 180000, proxy: Proxy.NO_PROXY)
180000 = 180 seconds = 3 mins readTimeout
You can also set the connectionTimeout here, but most likely you will be limited by the connectiontimeOut property on the servlet container like Tomcat or CDN like cloudfront or cloudflare.
If you are also using tomcat, you may need to increase the async timeout like in the below example in directive. Hope this helps others looking to solve the same problem.
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
asyncTimeout="60000"
redirectPort="8443" />
How to know exactly what URL does the 3rd-party application-server try to access while sending message to a client-device via the GCM-server?
In "SendAllMessagesServlet.java"
(which can be found # android-sdks\extras\google\gcm\samples\gcm-demo-server\src\com\google\android\gcm\demo\server\SendAllMessagesServlet.java)
.....
// Error 500 ( Connection timed out) at the following line
Result result = sender.send(message, registrationId, 5);
.....
3rd-party app-server - Tomcat v7.0
The URL is in the Constants.java file as GCM_SEND_ENDPOINT
in the android\gcm\gcm-server libray
public static final String GCM_SEND_ENDPOINT =
"https://android.googleapis.com/gcm/send";
The error 500 is due to proxy settings.
Thank You
I am working on a web-project. I have created one Http Url Connection. But for that, I have to test the code for time-out InterruptedIOException, that will execute on time-out, but even after setting time-out time as 1msec, my case is executed successfully.
How can I make delay from SOAPUI, so that I can have time-out successfull?
If you want to test how a client will react to a timeout, create a mockservice in SoapUI, and have it execute an OnRequest script prior to returning the (usually pre-determined) response. The script can be as simple as:
sleep(60000)
This would give you a 60-second delay before responding.
Select your response in the tree.
Then at the bottom in "MockResponse Properties" look for:
If you need to simulate a timeout thrown from an HTTP connectivity,
then better use the script
mockRequest.getHttpResponse().sendError(408)
This will generate an html response as well. You may set any HTTP code status you desire.
You may put it in "OnRequest Script", or in the "Script" of an existing Mock Response.
Use HTTP STatus property of Response Message set the value to 408
I have been struggling with the following error the last couple of
days can you please help!
I generated my server and client code using the wsdl2java tool from a
wsdl 2.0 file.
When invoking the webservice I am getting the following error:
org.apache.axis2.AxisFault: The endpoint reference (EPR) for the
Operation not found is
/axis2/services/MyService/authentication/?username=Denise345&password=xxxxx
and the WSA Action = null
My service is displayed on the axis2 webpage with all available methods.
Here is the output from TcpMon
==============
Listen Port: 8090
Target Host: 127.0.0.1
Target Port: 8080
==== Request ====
GET /axis2/services/MyService/authentication/?username=Denise345&password=xxxxx
HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
SOAPAction: ""
User-Agent: Axis2
Host: 127.0.0.1:8090
==== Response ====
HTTP/1.1 500 Internal Server Error
Server: Apache-Coyote/1.1
Content-Type: application/xml;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 12 May 2011 15:53:20 GMT
Connection: close
12b
<soapenv:Reason xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Text xml:lang="en-US">The endpoint reference (EPR) for the
Operation not found is
/axis2/services/MyService/authentication/?username=Denise345&password=xxxxx
and the WSA Action = null</soapenv:Text></soapenv:Reason>
0
==============
I am using:
axis2-1.5.4
Tomcat 7.0.8
wsdl 2.0 file
Please help!
In my case it was caused by a wrong Content-Type in the HTTP POST. Setting it to text/xml solved the problem.
Try adding ?wsdl to the string.
As described by Eran Chinthaka at http://wso2.com/library/176/
If Axis2 engine cannot find a service and an operation for a message,
it immediately fails, sending a fault to the sender. If service not
found - "Service Not found EPR is " If
service found but not an operation- "Operation Not found EPR is and WSA Action = "
In your case the service is found but the operation not. The Axis2 engine uses SOAPAction in order to figure out the requested operation and, in your example, the SOAPAction is missing, therefore I would try to define the SOAPAction header
It happens because the source WSDL in each operation has not defined the SOAPAction value.
e.g.
<soap12:operation soapAction="" style="document"/>
His is important for axis server.
If you have created the service on netbeans or another, don't forget to set the value action on the tag #WebMethod
e.g. #WebMethod(action = "hello", operationName = "hello")
This will create the SOAPAction value by itself.
Action is null means that no Action in given SOAP Message (Request XML). You must set Action before SOAP call:
java.net.URL endpoint = new URL("<URL>"); //sets URL
MimeHeaders headers = message.getMimeHeaders(); // getting MIME Header
headers.addHeader("SOAPAction", "<SOAP Action>"); //add Action To Header
SOAPMessage response = soapConnection.call(<SOAPMessage>, endpoint); //then Call
soapConnection.close(); // then Close the connection
I had this same problem using curl to send a soap request. Solved it by adding "content-type: text/xml" to the http header.
I hope this helps someone.
This error is coming because while calling the service, it is not getting the WSDL file of your service.
Just check whether WSDL file of your service is there--> run server and from browser run axis 2 apps on local host and check the deployed services and click on your service, then it shows WSDL file of your service.....or check the service path in your client file.
I hope it may help you to resolve the problem.
This can be solved by disabling validation
<proxy>
<!-- . . . -->
<parameter name="disableOperationValidation">true</parameter>
</proxy>
Late answer but:
I see you do a GET - should be a POST ?
try removing the extra '/' after the operation name (authentication) when invoking through the client
/axis2/services/MyService/authentication?username=Denise345&password=xxxxx
It seems don't find wsdl file..
I've solved adding wsdlLocation parameter at javax.jws.WebService annotation
By removing cache wsdl-* files in /tmp folder, my problem was solved
see https://www.drupal.org/node/1132926#comment-6283348
be careful about permission to delete
I'm in ubuntu os
On Websphere Application Server, in the same situation, it helped deleting the Temp folders while the server was stopped.
I ran into the situation when the package of the service changed.
Open WSDL file and find:
<soap:operation soapAction="[actionNameIsHere]" style="document"/>
Add to the requests header [request send to service]:
'soapAction' : '[actionNameIsHere]'
This work for me.
For devs. using node-soap [ https://github.com/vpulim/node-soap ] - example:
var soap = require('soap');
var options = {
...your options...
forceSoap12Headers: true
}
soap.createClient(
wsdl, options,
function(err, client) {
if(err) {
return callBack(err, result);
}
client.addHttpHeader('soapAction', '[actionNameIsHere]');
...your code - request send...
});
I got this error because the SOAP request I was sending to the server was malformed and had an empty Body
In this case the error message from the server is misleading and can be solved changing the request content, without changing anything about operations, URLs, WSDL, etc