Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

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

Posted on 2013-06-18
12
Medium Priority
?
414 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
Put Machine Learning to Work--Protect Your Clients

Machine learning means Smarter Cybersecurity™ Solutions.
As technology continues to advance, managing and analyzing massive data sets just can’t be accomplished by humans alone. It requires huge amounts of memory and storage, as well as the high-speed power of the cloud.

 
LVL 86

Expert Comment

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

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

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

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

These instructions are based on installing Owncloud on your new raspberry pi connected with a usb HDD. What do you need Part A? A Raspberry Pi, model B. A boot SD card for the Raspberry Pi. A usb HDD An Ethernet cable to connect to the lo…
The task of choosing a web design company to build a website for your business should never be taken in a light manner. Provided the fact that your website will act as a representative to your business and will be responsible for imposing an online …
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
Suggested Courses

916 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