I am making an a call to a proxy server and providing the wrong credentials on purpose. However the IOE exception is not being thrown. Instead an internal error with the message that "you should not be here".
Any idea why an IOE is not begin thrown just like the java docs? I created a brand new project just to be sure my other program wasn't causing any issues.
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
public class socketTesting {
public static void main(String[] args) {
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("<proxyServer>", 8080));
Socket sock = new Socket(proxy);
try
{
sock.connect(new InetSocketAddress("<endpoint server>",443));
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
}
If the proxy creds are correct, the connection works without any issues.
Related
My project aims at reading log messages directly from /dev/log UNIX domain socket in Java. Currently I am using junixsocket. Below is a sample code of client that reads from a unix socket.
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.newsclub.net.unix.AFUNIXSocket;
import org.newsclub.net.unix.AFUNIXSocketAddress;
import org.newsclub.net.unix.AFUNIXSocketException;
public class SimpleTestClient {
public static void main(String[] args) throws IOException {
final File socketFile = new File("/dev/log");
AFUNIXSocket sock = AFUNIXSocket.newInstance();
try {
sock.connect(new AFUNIXSocketAddress(socketFile));
} catch (AFUNIXSocketException e) {
System.out.println("Cannot connect to server. Have you started it?\n");
System.out.flush();
throw e;
}
System.out.println("Connected");
InputStream is = sock.getInputStream();
byte[] buf = new byte[8192];
int read = is.read(buf);
System.out.println("Server says: " + new String(buf, 0, read));
is.close();
sock.close();
System.out.println("End of communication.");
}
}
The above mentioned code is unable to connect to /dev/log. It throws an exception:
Cannot connect to server. Have you started it?
Exception in thread "main" org.newsclub.net.unix.AFUNIXSocketException: Protocol wrong type for socket (socket: /dev/log)
at org.newsclub.net.unix.NativeUnixSocket.connect(Native Method)
at org.newsclub.net.unix.AFUNIXSocketImpl.connect(AFUNIXSocketImpl.java:125)
at org.newsclub.net.unix.AFUNIXSocket.connect(AFUNIXSocket.java:97)
at org.newsclub.net.unix.AFUNIXSocket.connect(AFUNIXSocket.java:87)
at SimpleTestClient.main(SimpleTestClient.java:40)
I am unable to figure out how to solve this problem. Any help would be appreciable.
Since you cannot connect to an existing server socket as mentioned in the log traces, then you haven't bound one one the mentioned file, so try creating an AF_UNIX server socket then connect to it.
It could be done in a separate class:
public class DevLogServer {
public static void main(String[] args) throws IOException {
final File socketFile = new File("/dev/log");
AFUNIXServerSocket server = AFUNIXServerSocket.newInstance();
try {
server.bind(new AFUNIXSocketAddress(socketFile));
} catch (Exception e) {
throw e;
}
}
}
Edit as per #Ankit comment:
You may also need to make sure the syslod daemon is stopped by runnig below command in a terminal window:
sudo service syslog stop
You may alternatively need to grand write permission to the /dev directory.
In our application we need to check if certain ports of certain host are available for communication. At stage of this check we do not proceed with real communication - we need just to check if ports are open. As many ports has to be checked at once we originally used NIO approach (Selector + SocketChannel classes):
package test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class TestNIO {
public static void main(final String... params) {
final List<String> portsToCheck = Arrays.asList(new String[] {"443", "5989"});
final List<String> openPorts = new ArrayList<String>();
final String host = "<SOME_IP>";
final int timeout = 5000;
Selector selector = null;
if (!portsToCheck.isEmpty()) {
try {
selector = Selector.open();
for (final String port : portsToCheck) {
final SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress(host, Integer.valueOf(port)));
channel.register(selector, SelectionKey.OP_CONNECT);
}
final int readyChannels = selector.select(timeout);
if (readyChannels != 0) {
final Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()) {
final SelectionKey selKey = it.next();
try {
if (selKey.isValid() && selKey.isConnectable()) {
final SocketChannel channel = (SocketChannel) selKey.channel();
try {
if (channel.finishConnect()) {
openPorts.add(String.valueOf(channel.socket().getPort()));
}
} catch (final IOException ex) {
ex.printStackTrace();
} finally {
channel.close();
}
}
} catch (final Exception ex) {
ex.printStackTrace();
} finally {
selKey.cancel();
}
it.remove();
}
}
} catch (final IOException ex) {
ex.printStackTrace();
} finally {
try {
if (selector != null && selector.isOpen()) {
selector.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
System.out.print("Open ports: " + openPorts.toString());
}
}
}
}
This approach worked successfully for years at let's say hundreds of customers till at one of our customer this approach leaded to a problem. Namely, connections from client (where this check is running, it's Windows Server 2012 R2) to server (it's ESXi) at just one of SSL-ports stay established and never closed till restart of the server. This happens just with one of SSL-ports (standard 443), for example with another SSL-port - 5989 (it's HTTPS CIM server) this does not happen. Looks like this is because of some configuration on Windows side: 1. Happens just with one of several HTTPS ports; 2. Happens with any ESXi servers connected to this Windows client; 3. Does not happen with another Windows client connected to the same ESXi servers. Problem is that customer does not wish very much to cooperate with us finding the root cause and we have to guess it ourselves. We used another classic approach to check SSL-ports which works fine even in this problematic system. Here it is:
package test;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
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 TestHttpUrlConnection {
public static void main(final String... params) {
final List<String> portsToCheck = Arrays.asList(new String[] {"443", "5989"});
final List<String> openPorts = new ArrayList<String>();
final String host = "<SOME_IP>";
final int timeout = 5000;
if (!portsToCheck.isEmpty()) {
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
});
for (final String port : portsToCheck) {
HttpsURLConnection connection = null;
OutputStreamWriter out = null;
try {
connection = (HttpsURLConnection) new URL(
"https://" + host + ":" + Integer.valueOf(port)).openConnection();
connection.setDoOutput(true);
connection.setConnectTimeout(timeout);
final OutputStream os = connection.getOutputStream();
out = new OutputStreamWriter(os, "UTF8");
out.close();
openPorts.add(port);
} catch(final IOException ex) {
ex.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (final IOException ex) {
ex.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
}
System.out.print("Open ports: " + openPorts.toString());
}
}
private static void trustAllHttpsCertificates() {
try {
final TrustManager[] trustAllCerts = new TrustManager[1];
trustAllCerts[0] = new TrustAllManager();
final SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (final Exception ex) {
ex.printStackTrace();
}
}
private static class TrustAllManager implements X509TrustManager {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkServerTrusted(final X509Certificate[] certs, final String authType) throws CertificateException {
// Empty
}
public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
// Empty
}
}
}
But customer wants us to tell him the reason why one approach works and another does not. Can anyone help?
UPDATE
I've found out that on that problematic system even following code leads to a situation that each connection stays ESTABLISHED and not released back to system. This is not NIO and explicit close() on socket invoked:
Socket sock = new Socket();
SocketAddress serverSocketAddress = new InetSocketAddress(host, port);
try {
sock.connect(serverSocketAddress, timeout);
if (sock.isConnected()) {
openPorts.add(port);
}
} catch (IOException e) {
ex.printStackTrace();
} finally {
if (sock != null) {
try {
sock.close();
} catch (IOException e) {
ex.printStackTrace();
}
}
}
Setting keepAlive to false does not change the situation.
UPDATE 2
Problem repeated also on nonSSL-port (135, it's Hyper-V virtualization). And what confuses me most is that after restart of guest OS with which connections were established and and after stopping software which opened these connections, they are still marked as established on client machine. I consider there is really something wrong with the system itself (and has nothing to do with our Java code), but what exactly is wrong...
UPDATE 3
The problem was caused by TrendMicro's Anti-Virus software "Virus Buster". It prevented connections to be closed normally.
Registered channels aren't completely closed until the next select() call. This is documented somewhere which I can never find when I look for it.
NB your trustAllCertificates() method does nothing useful except implement a radical insecurity, and calling it once per open socket that shouldn't be open at all appears to be completely pointless.
The problem was caused by TrendMicro's Anti-Virus software "Virus Buster". It prevented connections to be closed normally.
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'm building a middleware, where I need to constantly read what is happening in my device, so I build this class:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
/**
*
* #author Valter
*/
public class Middleware {
public static void main(String args[]) {
try {
// ip and port where is my device
Socket socket = new Socket("192.168.1.4", 2001);
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
// i need send this parameter to my device
dataOutputStream.writeUTF("}Rv!");
String answer = dataInputStream.readUTF();
System.out.println("Answer:"+answer);
dataInputStream.close();
dataOutputStream.close();
socket.close();
} catch (UnknownHostException ex) {
System.out.println("UNKNOW HOST EXCEPTION");
} catch (IOException ex) {
System.out.println(" IOEXCEPTION");
System.out.println(ex.getMessage());
}
}
}
Output:
IOEXCEPTION Connection reset
What's wrong with my class?
I don't know if this is what is causing your problem, but you are not flushing the output stream before attempting to read a response from the input stream. Try:
dataOutputStream.writeUTF("}Rv!");
dataOutputStream.flush();
Does your device really understand the output of writeUTF()?and produce the correct input for readUTF()? Check the Javadoc. I don't think it likely.
'Connection reset' usually means you have written to a connection that was already closed by the other end, which is already an application protocol error, and it may indicate prior application protocol errors.
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