Solved

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

Posted on 2013-06-18
12
388 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
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
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
 
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

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
tomcat not starting 6 70
Way to decrease size of apk file 9 88
MySQL  on Tomcat 8 71
check java version using powershell 13 182
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
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 will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

821 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