I tried to run this piece of code without an internet connection, expecting and IOException to trigger:
import java.net.*;
import java.io.*;
public class API_connect {
public static void main(String[] args) {
try {
URL API = new URL("http://api.football-data.org");
URLConnection API_connection = API.openConnection();
}
catch(MalformedURLException exception) {
System.out.print(exception);
}
catch(IOException exception) {
System.out.print(exception);
System.out.print("is something going on here?");
}
}
}
And well... To my surprise nothing was printed, and I can't figure out why. Wouldn't a lack of internet connection be the main reason why an IOException is thrown here?
openConnection() does not actually try to connect:
It should be noted that a URLConnection instance does not establish the actual network connection on creation. This will happen only when calling URLConnection.connect().
Try calling connect() on it.
Alternatively, you could try the following:
new URL(...).openStream().read();
That would actually try to read 1 byte from that url and would fail.
Related
So I'm writing two ServerSockets. One that listens for HTTP requests on port 8085 and saves the byte input into a static LinkedList, and a second that listens on port 8086 and returns all the results in the static LinkedList.
The issue is that when saving the data from ServerSocket:8085 to the LinkedList, the thread hangs and I'm not sure why.
This is the main Listener class:
import java.net.ServerSocket;
import java.nio.charset.Charset;
import java.util.*;
public class Listener {
public static LinkedList<byte[]> Calls = new LinkedList<>();
public static void main(String[] args) {
Thread callback = new Thread(new ThreadListener());
callback.start();
while (true) {
try (var listener = new ServerSocket(8086)) {
System.out.println("Listening on 8086...");
try (var client = listener.accept()) {
StringBuffer response = new StringBuffer();
response.append("HTTP/1.1 200 OK\r\n\r\n");
Iterator<byte[]> iterator = Calls.iterator();
while (iterator.hasNext()) {
response.append(new String(iterator.next(), Charset.forName("UTF-8")) + "\r\n");
iterator.remove();
}
client.getOutputStream().write(response.toString().getBytes("UTF-8"));
client.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
This is the ThreadListener class:
import java.io.IOException;
import java.net.ServerSocket;
import java.util.Date;
public class ThreadListener implements Runnable {
#Override
public void run() {
while (true) {
try (var listener = new ServerSocket(8085)) {
System.out.println("Listening on 8085...");
try (var socket = listener.accept()) {
if (!socket.getInetAddress().getHostAddress().equals("127.0.0.1")) {
System.out.println("Not localhost");
} else {
System.out.println("Its us!");
}
Listener.Calls.add(socket.getInputStream().readAllBytes());
System.out.println("Result collected");
Date today = new Date();
String httpResponse = "HTTP/1.1 200 OK\r\n\r\n" + today;
socket.getOutputStream().write(httpResponse.getBytes("UTF-8"));
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
As for my test, I tried calling 127.0.0.1:8085, and I get an ERR_CONNECTION_RESET, and all I have in the console is the following:
Listening on 8085...
Listening on 8086...
Its us!
Process finished with exit code -1 (I killed the app after 2 mins)
The fact that the "Its us!" message got printed, but the "Results collected!" right after the LinkedList.add didn't is what leads me to assume the LinkedList.add is the one hanging the thread.
Regards
EDIT: No one is calling to 8085 (or 8086), I'm doing it manually on my browser. I solved the Syncronization issue by creating a method to call instead of calling the LinkedList.add directly:
public static synchronized void addElementsToList(byte[] bytes) {
Calls.add(bytes);
}
This does work, but calling the 8085 socket gives the connection reset every time.
Your test mechanism of using a browser to create the request is probably also not helping here, as the InputStream.readAllBytes()
blocks until all remaining bytes have been read and end of stream is detected, or an exception is thrown. This method does not close the input stream.
From the documentation. Specifically, the browser is keeping the connection open, because it's expecting some response. Your server is trying to read everything from the connection until the connection is closed. Catch 22 (aka deadlock).
Try making the connection to localhost:8085 using telnet and closing the connection from the client end.
telnet 127.0.0.1 8085
^D
where ^D is literally the [CTRL] and [D] keys (eg: logout)
A LinkedList is not synchornized, as highlighted in the documentation.
You can either handle synchronisation manually, use a synchronised list, or a concurrent list. Probably some other methods too, but for now, just keep it simple.
public static LinkedList<byte[]> Calls = Collections.synchronizedList(new LinkedList<>());
// or
public static LinkedList<byte[]> Calls = new CopyOnWriteArrayList<>();
I am writing a program to output a website's HTML code. I have tested it on some sites such as https://www.stackoverflow.com and it works. However, when I tried running the program with https://www.science.energy.gov, it doesn't work and throws an IOException. If I change the https to http and run it with http://www.science.energy.gov, the program runs but does not print anything. I am not sure why the HTML code for the http website is not displaying.
Below is the relevant code for the HTML extraction program:
import java.net.*;
import java.io.*;
public class URLReader {
public static void main(String[] args) throws Exception {
URL url;
InputStream is = null;
DataInputStream dis;
String line;
try {
url = new URL("https://science.energy.gov/");
is = url.openStream(); // throws an IOException
dis = new DataInputStream(new BufferedInputStream(is));
while ((line = dis.readLine()) != null) {
System.out.println(line);
}
} catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
is.close();
} catch (IOException ioe) {
// nothing to see here
}
}
}
}
That's because when you send a request in http for http://science.energy.gov/ it redirects automatically to https, which means the site will reload. And your program is not capable of handling redirect requests. So it just stops. No output no error.
Now about the SSLHandshakeException. The error explains it self, unable to find valid certification path to requested target. Which means your java keystore doesn't have ssl certificate for service you are trying to connect. So you need to obtain the public certificate from the server you're trying to connect to. Read this answer for more information.
Also read,
How to solve javax.net.ssl.SSLHandshakeException Error?
javax.net.ssl.SSLHandshakeException
I am trying to use java.net.HttpURLConnection to make a simple HTTP GET call and am running into something I can't 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's input stream is NULL");
else
System.out.println("con's 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 error. No exceptions get thrown, it doesn't exit unexpectedly, and it doesn't hang or timeout...it just dies.
It seems to be dying when I check con.getInputStream() for being null or not. But that still doesn't explain why it just dies quietly without any indication of error. Any ideas? I''m willing to admit that I could have created the HttpURLConnection incorrectly, but still, there should be more indication of what is killing my program...Thanks in advance!
Your code shouldn't be compiling since this line:
System.out.println("Returning...")
has a missing semi-colon. With that said, I would imagine any runs of the application you're using are using an old execution and don't have the new code you probably wrote.
If that's not the case then you've pasted your code incorrectly (somehow) and I would venture a guess that you missed other aspects that we need to see? If you've edited the code in some way for StackOverflow would you mind sharing the original?
Additionally, I would recommend against catching Throwable unless you have good reason to. Its typically bad practice to mask application errors as such.
It seems to be dying when I check con.getInputStream() for being null or not.
Well I find that hard to believe.
On the face of it:
testing a reference to see if it is null cannot terminate your program
the con.getInputStream() can either throw an exception or return
if does return it shouldn't return null ... 'cos the API doesn't allow it ... and you would see a message
if an exception was thrown you would see the Error: ... message
My conclusion is that a either different thread is causing the application to exit, or the application is not exiting at all.
The only other explanation I can think of is that your edit / compile / deploy / run procedure is not working, and the code that is actually being run doesn't match the code you are showing use.
I suggest that you attempt to create a SSCCE for this so that other people can reproduce it and figure out what is actually happening.
same Problem here. I traced my code and it gets stuck at con.getInputStream() forever.
To reproduce the Problem run the code example below. (put your correct URL)
A) Start any HTTPS Server on another Host
B) Start the Client Code
C) Shutdown HTTPS Server
D) Start HTTPS Server again
-> Stuck at con.getInputStream()
While restarting the HTTPS Server it seems like some deadlock in the client occurs.
FYI I am using the bundle org.apache.felix.http.jetty as HTTP(S)-Server with a 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 welcome.
Fixed it.
con.setReadTimeout(1000)
obviously the HTTP Server accepts a connection, but is unable to fulfill the request when you connect in the wrong moment while server is starting. setReadTimeout causes the thread to throw an SocketTimeoutException.
Hope this helps someone else to solve the Problem...
As this Problem may also occur while using RESTlet with the internal connector, here is the solution for RESTlet. You have to take care of a hostnameVerifier and an SSLContextFactory by 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
org.restlet.ext.ssl
org.restlet.ext.net
org.restlet.ext.httpclient
are in your classpath.
Best Regards
I am trying to create a thread to simply send the text to client. However, if you copy this code to IDE, you will see that there is a red underline under client.getOutputStream(). I do not know what is wrong here. The IDE says "Unhandled exception type IOException". Could anybody tell me?
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class ServerStudentThread extends Thread {
Socket client;
public ServerStudentThread(Socket x) {
client = x;
}
public void run() {
// create object to send information to client
PrintWriter out = new PrintWriter(client.getOutputStream(),true);
out.println("Student name: ");//send text to client;
}
}
For reference, here is the code that calls the thread.
import java.io.*;
import java.net.*;
import java.util.*;
public class Server2 {
public static void main(String args[]) throws Exception {
int PORT = 5555; // Open port 5555
//open socket to listen
ServerSocket server = new ServerSocket(PORT);
Socket client = null;
while (true) {
System.out.println("Waiting for client...");
// open client socket to accept connection
client = server.accept();
System.out.println(client.getInetAddress()+" contacted ");
System.out.println("Creating thread to serve request");
ServerStudentThread student = new ServerStudentThread(client);
student.start();
}
}
}
It's probably that getOutputStream() can throw an exception and you're not catching it, try putting a try / catch (IOException e) around the block of code.
public void run() {
try {
// create object to send information to client
PrintWriter out = new PrintWriter(client.getOutputStream(),true);
out.println("Student name: ");//send text to client;
} catch (IOException e) {
throw new RuntimeException("It all went horribly wrong!", e);
}
}
So you need to add a try/catch block to handle the I/O exception.
Read the section on Exceptions from the Java tutorial.
From the javadoc:
public OutputStream getOutputStream() throws IOException
IOException is a checked exception. You need to use a try/catch block to handle that possibility.
Kalla,
You need to either put the line in between try/catch block or declare run to throw IOException
Simple stuff, I am learning URLs/Networking in my class and I am trying to display something on a webpage. Later I am going to connect it to a MySQL DB... anyway here is my program:
import java.net.*; import java.io.*;
public class asp {
public static URLConnection
connection;
public static void main(String[] args) {
try {
System.out.println("Hello World!"); // Display the string.
try {
URLConnection connection = new URL("post.php?players").openConnection();
}catch(MalformedURLException rex) {}
InputStream response =
connection.getInputStream();
System.out.println(response);
}catch(IOException ex) {}
} }
It compiles fine... but when I run it I get:
Hello World!
Exception in thread "main" java.lang.NullPointerException
at asp.main(asp.java:17)
Line 17: InputStream response = connection.getInputStream();
Thanks,
Dan
You have a malformed URL, but you wouldn't know because you swallowed its exception!
URL("post.php?players")
This URL is not complete, it misses the host (maybe localhost for you?), and the protocol part, say http so to avoid the malformed URL exception you have to provide the full URL including the protocol
new URL("http://www.somewhere-dan.com/post.php?players")
Use the Sun tutorials on URLConnection first. That snippet is at least known to work, if you substitute the URL in that example with a valid URL you should have a working piece of code.
It's because your URL is not valid. You need to put the full address to the page you are trying to open a connection to. You are catching the malformedurlexception but that means that there is no "connection" object at that point. You have an extra closed bracket after the first catch block it appears as well. You should put the line that you are getting the null pointer for and the system.out.println above the catch blocks
import java.net.*; import java.io.*;
public class asp {
public static URLConnection connection;
public static void main(String[] args) {
try {
System.out.println("Hello World!"); // Display the string.
try {
URLConnection connection = new URL("http://localhost/post.php?players").openConnection();
InputStream response = connection.getInputStream();
System.out.println(response);
}catch(MalformedURLException rex) {
System.out.println("Oops my url isn't right");
}catch(IOException ex) {}
}
}