Java HttpURLConnection mysteriously dies

I try to use java.net.HttpURLConnection to make a simple HTTP GET call, and I run something that I cannot explain:

 public String makeGETCall(HttpURLConnection con) { try { System.out.println("About to make the request..."); if(con == null) System.out.println("con is NULL"); else { System.out.println("con is NOT null"); if(con.getInputStream() == null) System.out.println("con input stream is NULL"); else System.out.println("con input stream is NOT null"); } } catch(Throwable t) { System.out.println("Error: " + t.getMessage()); } System.out.println("Returning...") return "DUMMY DATA"; } 

When I run this, I get the following console output:

 About to make the request... con is NOT null 

And then the program terminates without errors. No exceptions are thrown, it does not come out unexpectedly, and it does not freeze or linger ... it just dies.

It seems to die when I check con.getInputStream() for null or not. But this still does not explain why he simply dies quietly, without any signs of error. Any ideas? I agree to admit that I could have created the HttpURLConnection incorrectly, but there should still be more indications that it kills my program ... Thanks in advance!

+4
source share
4 answers

It seems to die when I check con.getInputStream() for whether it is zero or not.

Well, it's hard for me to believe.

At first sight:

  • check the link to see if it is null your program is not completed

  • con.getInputStream() can either throw an exception or return

  • if it returns, it should not return null ... ', because the API does not allow this ... and you will see a message

  • If an exception occurs, you will see the Error: ... message Error: ...

My conclusion is that either another thread causes the application to exit, or the application does not exit at all.

The only other explanation that I can think of is that your editing / compiling / deploying / launching procedure does not work, and the executable code does not match the code you are using.

I suggest you create SSCCE for this, so that other people can play it and find out what is really happening.

0
source

Your code should not be compiled from this line:

  System.out.println("Returning...") 

has a missing semicolon. With that said, I would suggest that any runs of your application use the old execution and do not have new code, which you probably wrote.

If this is not the case, you have incorrectly inserted your code (in some way), and I risk assuming that you have missed other aspects that we need to see? If you somehow edited the code for StackOverflow, could you share the original?

In addition, I would recommend against Throwable fishing if you have no good reason. Its typically bad practice to mask application errors as such.

+1
source

same problem here. I traced my code and got stuck in con.getInputStream () forever. To reproduce the problem, follow the code example below. (enter the correct URL)

A) Start any HTTPS server on another host

B) Run the client code

C) Shutting down the HTTPS server

D) Start the HTTPS server again

-> Stuck in con.getInputStream ()

During the restart of the HTTPS server, it seems that there is some kind of deadlock in the client. FYI I am using the org.apache.felix.http.jetty package as an HTTP (S) -Server with the Restlet servlet attached.

 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; public class TestHTTPS{ public static void main(String[] args) throws InterruptedException { new TestHTTPS().activate(); } private void activate() throws InterruptedException{ TrustManager[] insecureTrustManager = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } }; try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, insecureTrustManager, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (KeyManagementException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); String https_url = "https://192.168.xx.xx:8443"; URL url; try { url = new URL(https_url); while(true) { HttpsURLConnection con = (HttpsURLConnection)url.openConnection(); con.setConnectTimeout(1000); print_content(con); Thread.sleep(100); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void print_content(HttpsURLConnection con){ if(con!=null){ try { System.out.println("****** Content of the URL ********"); BufferedReader br = new BufferedReader( new InputStreamReader(con.getInputStream())); String input; while ((input = br.readLine()) != null){ System.out.println(input); } br.close(); } catch (IOException e) { e.printStackTrace(); } } } 

Any recommendations are appreciated.

0
source

Fixed.

 con.setReadTimeout(1000) 

Obviously, the HTTP server accepts the connection, but cannot complete the request when you connect at the wrong time during server startup. setReadTimeout causes the thread to throw a SocketTimeoutException.

Hope this helps someone else solve the problem ...

How this problem can occur when using RESTlet with an internal connector, here is a solution for RESTlet. You must take care of hostnameVerifier and SSLContextFactory yourself:

 context = new Context(); context.getParameters().add("readTimeout", Integer.toString(1000)); context.getAttributes().put("sslContextFactory", new YourSslContextFactory()); context.getAttributes().put("hostnameVerifier", new YourHostnameVerifier()); client = new Client(context, Protocol.HTTPS); 

Make sure that

 org.restlet.ext.ssl org.restlet.ext.net org.restlet.ext.httpclient 

are on your way to classes.

Best wishes

0
source

All Articles