Solved

Socket input stream behaviour regular application vs Tomcat/Axis2 (only in newer versions of Java!?)

Posted on 2013-06-18
12
380 Views
Last Modified: 2013-06-24
I have a Axis2 web application which opens a raw socket to a 3rd party service. In the past this webapp has worked flawlessly.

I've recently (last couple of months) updated my JRE and this webapp no longer functions correctly.

In code we connect to a service over a raw socket and create a reader and writer for the input/output streams of the socket.

socket = new Socket("localhost", 8000);
socket.setTcpNoDelay(true);
socket.setSoTimeout(3000000);

output = new BufferedOutputStream(socket.getOutputStream());
writer = new PrintWriter(output, true);
input = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

Open in new window


(I didn't write this code so don't ask ;))

The process is that a command string is written to the socket using 'writer.print(command + "\r\n")' and then we read a response using input.read() to build up a string buffer (we'd expect a response of "200 OK")...

As I said, this works when deployed as an aar under Axis2/Tomcat with older builds of Java (pre 1.6u37?) and it works when using the code directly from a main method in a test application. I've also connected to the 3rd party service using Putty and manually typed the commands and seen the responses come back there too.

Under newer versions of Java the call to input.read() immediately returns -1 indicating that the stream has reached its end instead of giving us any kind of response.

I'm starting to pull my hair out now. Does anyone know what may be going on?

(Even though there are no exceptions thrown I've tried using the catalina.policy file to grant all permissions to the webapp but it didn't have any effect...)
0
Comment
Question by:Cheney
  • 6
  • 5
12 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 39256482
Is there any ssl involved?
0
 
LVL 2

Author Comment

by:Cheney
ID: 39256562
No. The webapp has a plain HTTP front end (Axis2 POJO) with a raw socket backend. There's no form of security or authentication.
0
 
LVL 2

Author Comment

by:Cheney
ID: 39256672
FYI I'm using Tomcat 7 and Axis2 v1.6.2.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 39256818
OK. Please post full method for connection
0
 
LVL 35

Expert Comment

by:mccarl
ID: 39256819
Can you show the rest of the code? The code that is doing the writing and subsequent reading to/from the socket?

And you say that it works when run directly from a main method... Is this with both older and newer JRE's?
0
 
LVL 2

Author Comment

by:Cheney
ID: 39256860
Sure. The writer and input variables mentioned in my original post are stored as class variables.

This method is called to send the command:
private synchronized void send(boolean readResponse, String command) throws IOException {
	writer.print(line + EOL_MARKER);
	writer.flush();

	if (readResponse) {
		validateResponse(readLine(), line);
	}
}

private String readLine() throws IOException {
	StringBuffer buf = new StringBuffer(LINE_LENGTH);
	try {
		int data;
		while ((data = input.read()) != -1) {
			buf.append((char) data);

			if (buf.lastIndexOf(EOL_MARKER) != -1) {
				buf.delete(buf.length() - 2, buf.length());
				break;
			}
		}

		return buf.toString();
		
	} catch (IOException e) {
		logger.severe("Socket Error : " + e.getMessage() + " last command " + lastCommand 
			+ " [thread = " + Thread.currentThread().getName());
				
		throw e;
	}
}

Open in new window


The validateResponse methods just checks that the response equals "200 OK" and EOL_MARKER is a constant "\r\n".

And yes, when running from a main method it works on all versions of Java.

Under Axis with a newer JRE, readLine() always returns an empty string.
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 2

Author Comment

by:Cheney
ID: 39256865
... and the full method for connection is just the 6 lines of code posted in the question.
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 39256896
private synchronized void send(boolean readResponse, String command) throws IOException {
	writer.print(line + EOL_MARKER);

Open in new window

What is 'line' and why is 'command' not used?
0
 
LVL 2

Author Comment

by:Cheney
ID: 39256959
Ah, sorry, typo. I was trying to make the intent clearer by changing the var names. Seems I made it worse!

It should read:

private synchronized void send(boolean readResponse, String command) throws IOException {
	writer.print(command+ EOL_MARKER);
	writer.flush();

	if (readResponse) {
		validateResponse(readLine(), line);
	}
}

private String readLine() throws IOException {
	StringBuffer buf = new StringBuffer(LINE_LENGTH);
	try {
		int data;
		while ((data = input.read()) != -1) {
			buf.append((char) data);

			if (buf.lastIndexOf(EOL_MARKER) != -1) {
				buf.delete(buf.length() - 2, buf.length());
				break;
			}
		}

		return buf.toString();
		
	} catch (IOException e) {
		logger.severe("Socket Error : " + e.getMessage() + " last command " + lastCommand 
			+ " [thread = " + Thread.currentThread().getName());
				
		throw e;
	}
}

Open in new window


Also LINE_LENGTH is a constant int 256 if that makes any difference.
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 400 total points
ID: 39257043
You're looking at the client for the answer but of course the problem could just as well be at the server. I know you say other clients are OK with it, but nonetheless, it could be worth looking at the server
0
 
LVL 2

Author Closing Comment

by:Cheney
ID: 39270787
You're right - the problem does seem to be with the server. I don't have the code for this part of the system so there's not a lot I can do.

Thanks for your effort!
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 39270835
:)
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now