HTTPURLConnection Getoutputstream Hanging - java

I am writing a java code to send POST request to a URL but it is getting hanged on the line indicated by bold. I am running this on android emulator
URL url = new URL("htt
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
OutputStream urlc = connection.getOutputStream(); //line on which code is getting hanged
OutputStreamWriter writer = new OutputStreamWriter(urlc);
writer.write("message");
writer.close();
I am also able to run internet on emulator browser. That is I have checked that internet is working.

I had the same problem, my mistake was that I set too big timeout(120 seconds).
Bigger timeout makes the HttpUrlConnection to wait more time before consuming each line. When I decreased it to 20 seconds it worked much faster.
before the change - waiting time of 4-5 seconds
after the change - only 0.5-1.5 seconds.

See this is my one of the answer will help you and guide you on right direction.

I had the same problem. You have to enable billing of your application.
If billing is not enabled, the native (HttpURLConnection) in Java 8 environment won't work.
https://cloud.google.com/appengine/docs/standard/java/issue-requests
When your app runs in Java 8 using default behavior, you must enable your application for billing, or you will get the following exceptions:
java.net.UnknownHostException
java.net.SocketTimeoutException
java.io.IOException
The other option is to use the legancy urlfetch, however, then you will encounter additional problems, like this:
Got "DatastoreException: Request is missing required authentication credential" if using Objectify 6.0 and <url-stream-handler> at the same time

Related

How do I make a Java function that retries a URL connection every half second if the connection takes too long?

So I have a problem with a Java program I have. The program's basic functionality includes basically connecting to a web API for data. The function that does that is something like this:
public static Object getData(String sURL) throws IOException {
URL url = new URL(sURL);
URLConnection request = url.openConnection();
request.connect();
return request.getContent();
}
The code works fine as it is, but recently, after my house changed ISPs, I have found that sometimes the connections take an unreasonably long amount of time, something like 10 seconds or more in about 10% of attempts, while the other 90% takes only around 200ms. I have found it to be faster to ask my program to call the function again in a different thread than to wait for some of these connections to finally connect.
Therefore, I want to change the function so that if after 500ms, the connection did not establish, it would disconnect and a new connection would be attempted. How could I do this?
Somewhere online I read that HttpURLConnection might help, but I am not sure how.
URLConnection allows you to specify the connect and read timeout prior to calling connect():
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URLConnection.html#setConnectTimeout(int)
Sets a specified timeout value, in milliseconds, to be used when
opening a communications link to the resource referenced by this
URLConnection. If the timeout expires before the connection can be
established, a java.net.SocketTimeoutException is raised. A timeout of
zero is interpreted as an infinite timeout.
With 500ms timeout:
try {
URLConnection request = url.openConnection();
request.setConnectTimeout(500); // 500 ms
request.connect();
// on successful connection
} catch (SocketTimeoutException ex) {
// on request timeout
}
This you can pack into a loop, but I recommend limiting the number of attempts made.
Java's URLConnection doesn't have retry capabilities in Java 8 therefore the best way here to achieve this - use an appropriate standalone 3-party library such as Apache HttpClient.
This is by far the best standalone 3-party HTTP client with advanced capabilities as of 2020 and it's still maintained.
By default as of version 5.2.x Apache Http Client, Apache Http Client uses the default implementation of org.apache.http.client.HttpRequestRetryHandler, which retries 3 times, but you can use a custom implementation instead.
The configuration might look like this(full imports are for example's sake):
org.apache.http.client.HttpClient httpClient = org.apache.http.impl.client.HttpClients.custom()
.setRetryHandler(YourCustomImplOfTheRetryHandlerClass)
//other config
.build();
There is no way I can reproduce that problem using my ISP.
I suggest you dig deeper into the problem and find a better solution. Sending another request just doesn't seem good enough to me. Maybe try a different way to get the data and see if that works for you. Can't say for sure as I can't reproduce the problem.

How the URLConnection.connectionTimeout is handled?

Given the code:
HttpURLConnection huc = (HttpURLConnection) new URL( url ).openConnection();
huc.setConnectTimeout( 10000 );
huc.connect();
how exactly the connection timeout is processed? Some HTTP header gets set or what? Or the connection status is being checked in a loop for connectionTimeout time?
I tried to find it in the source code, but there is only the long connectionTimout field...
Think of it as:
Inside connect first a parallel timer is run for the the connection timeout.
If the timer ends before the actual connection is established (response received), then fail.
In reality on most platforms the operating system can be parametrised with a timeout and will handle it oneself - in the same manner.
Not having seen the java native code, but there are POSIX methods like setsocketopt with which to set timeouts. POSIX connect will give a timeout.
In java the timeout was a later much desired addition to utilize these available timeouts.

Java Can't Connect To PHP Web Service

Edit:
As I've just seen, it happens even with the simplest setup:
InputStream stream = new URL("http://xx.xx.xxx.xxx/GetAll.php").openStream();
Gives the same timeout error. I think I'm missing some basic configuration.
I used HTTPGet to connect to a PHP web service I have.
I saw it's deprecated so I've been trying to switch to the recommended HttpUrlConnection but with no success.
The HttpURLConnection does not seem to be able connect to the service, even though I can connect from my web browser without any problem.
My connection code:
URL myUrl = new URL("http://xx.xx.xxx.xxx/GetAll.php");
HttpURLConnection request = (HttpURLConnection)myUrl.openConnection();
request.setRequestProperty("Content-Type","text/xml;charset=UTF-8");
InputStream stream = request.getInputStream();
The GetAll.php file:
<?
require_once('MysqliDb.php'); //Helper class
$db = new MysqliDb();
//All closest events by date
$All = $db->query("SELECT * FROM Event;");
//Return in JSON
echo json_encode($All);
The result I am getting from the file:
[{"EventID":1,"StartTime":1300,"Duration":1,"EventDate":"2015-05-17","EventOrder":1,"Type":0,"Name":"\u05e2\u05d1\u05e8\u05d9\u05ea AND ENGLISH","Organiser":"Neta","Phone":"012345678","Location":"Loc","Description":"Desc"}]
Thank you,
Neta
I want to share my solution, as this has cost me hours of hair tearing.
As it turns out, "Timed out" exception has nothing to do with the code, it's a network connectivity issue. The phone I used to debug the app sometimes appears to be connected to Wifi even though it really isn't.
Anyway, if you have this exception, try checking your network connection.
Good luck!

HttpURLConnection slow to disconnect - Java / Android

I want to get the file size of a file on a remote connection without actually downloading the (large) file. I am using the "Content-Length" header of the file. The relevant code is:
URL obj = new URL(FILES_URL + fileName);
String contentLength = "";
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) obj.openConnection();
conn.setConnectTimeout(3000);
conn.setReadTimeout(3000);
contentLength = conn.getHeaderField("Content-Length");
int responseCode = conn.getResponseCode();
Log.d(TAG, "responseCode: " + responseCode);
} finally {
Log.d(TAG, "pre-disconnect");
if (conn!=null) conn.disconnect();
Log.d(TAG, "post-disconnect");
}
return contentLength;
The command "conn.disconnect();" sometimes seems to take forever. I have seen 23 seconds! Admittedly, this is connecting to a secondary local device which is running a web server, but the WiFi signal is strong, relatively fast, and I have never had any such problems using "curl" from my laptop. I do not have control over the web server I am connecting too.
The problem possibly is enhanced when making multiple similar connections to different files one after another, not sure. This is, however, creating entirely new HttpURLConnection's and not reusing the old one. Could reusing the connection help?
I never actually download the file or access the inputstream.
I could just not call disconnect, but I understand it is not recommended because resources would not be released. Is this not correct? I notice URLConnection doesn't have a disconnect. It is just suggested to close any streams you open.
This code is in an asynctask. I guess I could try moving the disconnect call itself to a further asynctask because I don't do anything afterwards. Not sure if that is even possible.
Do you have any suggestions? Should I try something other than HttpURLConnection to get the file size without downloading the file?
Thanks to EJP in the comments. Changing the request method to "HEAD" made the disconnect almost instantaneous:
conn.setRequestMethod("HEAD");
From what I have read, HttpURLConnection.disconnect() will skip through the entire response object if it hasn't been read. Therefore, for very large files, it will take a long time. Using the request method "HEAD" force the response body to be empty and solves the issue.
I suggest you to use either Volley or Okhttp for faster networking but depending on your requirement . Got through Comparison Of Volley And OkHttp and Retrofit and decide which library to use.
As suggestion if you putting this code inside AsyncTask then Read Dark Side of AsyncTask.

Processes locking on multicore machine

I recently started running my java program on my new multicore machine. I am suddenly seeing a problem which never occurred on my old single core Pentium. I suspect that the issue has to do with some sort of contention between my program and the various browsers I am running at the same time. When the processes get into this state, no amount of killing of processes seems to help (there's always some residual firefox or chrome process), so I end up restarting the machine. My program does a lot of opening and reading of URLs essentially using the following lines:
URL url = new URL( urlString );
URLConnection yc = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
........
while ((inputLine = in.readLine()) != null ) {...}
Every so often the URL my program tries to hit does not exist. In these cases, the call to create the BufferedReader eventually times out. I am going to modify the program to use a shorter time out, but I suspect that this in itself is not going to fix the problem.
Any suggestions would be appreciated.
I think the system change is a red herring. When you working with raw URL connection on the jdk there might be an issue. There is no in built retry mechanism and you will have to write all the code yourself. Try the HTTP client library from Apache. That should more or less solve any problem you face with URLConnection - http://hc.apache.org/httpclient-3.x/

Categories