Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

Java does not execute all the code!

Hi,

I encountered an incredible problem :eek: in Java!

Please look at the following code:

int conta=0;
char[] c = new char[1024];

while( ((conta=in.read(c)) != -1)) {
for(int i=0; i<conta; i++)
System.out.print(c[i]);

}

System.out.println("\n\n*** COMPLETED.");

I'm creating a simple web server, and "in" is the socket input stream:

InputStream is = socket.getInputStream();

My problem is the last instruction is never executed, but the code exits properly!!! It seems everything is ok (no exception, no other error), but is like if the program does not include the last line (System.out.println("\n\n*** COMPLETED."); )

If I force an exit using a flag, the application functions correctly.

I tried several pieces of code (using "in", or using...

String thisLine;

while( (thisLine = in.readLine()) != null) {
System.out.println(new StringBuffer(">").append(thisLine).toString());
}

System.out.println("\n\n*** COMPLETED.");

Please help me, since I'm becoming mad! :confused:
[1154 byte] By [ale870] at [2007-11-11 7:25:55]
# 1 Re: Java does not execute all the code!
could you post the full code?
Phaelax at 2007-11-11 22:38:19 >
# 2 Re: Java does not execute all the code!
/**
* Created Alessandro MANOTTI
* Date: Dec 3, 2005
* Time: 12:21:20 AM
*
* Manage a single socket connection, using Multi Thread fashion. Used by "ServerHttp" class.
*
* History:
* 2005-12-02 Original file
*/

import java.net.Socket;
import java.io.*;
import java.util.*;
import java.text.SimpleDateFormat;

public class RequestManager {
private Thread runner;
private Socket socket;

public RequestManager(Socket argSocket) {
socket = argSocket;
}

/**
* Manage an error; it could be a protocol error, or an invalid request, etc...
* @param argError Error message to be sent to the client.
*/
private void msgError(String argError) {
msgResponse(argError);
Thread.currentThread().interrupt();
}

/**
* Send a message to the client.
* @param argMsg
*/
private void msgResponse(String argMsg) {
try {

// Open response channel.

OutputStream os = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(os);

// Send headers.

printWriter.print("HTTP/1.0 200 OK\r\n");
printWriter.print("Content-Type: text/html\r\n");

SimpleDateFormat httpDate = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
httpDate.setTimeZone(TimeZone.getTimeZone("GMT"));

printWriter.print("Date: " + httpDate.format(new Date()) + "\r\n");

// Send <<End Of Headers>>.

printWriter.print("\r\n");
printWriter.flush();

// Write response message.

printWriter.print(argMsg);
printWriter.flush();

printWriter.close();
os.close();

socket.close();

//TODO: fix try... except to manage close() channels.

} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}

/**
* Start to handle a new client request.
*/
public void start() {

// Internal class.

runner = new Thread() {

public void run() { // RUN //////////////////////////////////////////////////////////////

// Jell Desktop accepts only local connections!

if(!socket.getInetAddress().toString().equals("/127.0.0.1")) {
msgResponse("Security violation: Access denied.");
Thread.currentThread().interrupt();
}

try {
// Read data from client

InputStream is = socket.getInputStream();
BufferedReader in = new BufferedReader( new InputStreamReader(is));

// Read the request line, then parse it.

String thisLine;

//int postLen = 0;

// Check if the request is a valid request.

while( (thisLine = in.readLine()) != null) {
System.out.println(new StringBuffer(">").append(thisLine).toString());

// if(thisLine.startsWith("Content-Length:")) {
// String[] leng = thisLine.split("\\:");
// postLen = Integer.parseInt(leng[1].trim());
// }
}

int conta=0;
int conta2=0;
char[] c = new char[1024];

for(conta=in.read(c); conta != -1; conta=in.read(c)) {
//while( ((conta=in.read(c)) >= 0) || conta2==0) {
System.out.println("#"+conta+"#");

for(int i=0; i<conta; i++)
System.out.print(c[i]);

}

System.out.println("\n\n*** COMPLETED.");

/* if( (thisLine = in.readLine()) != null) {
String[] parser = thisLine.split("\\s"); // Break-up using spaces

if(parser.length == 0) {
msgError("BAD HTTP REQUEST.");
} else {

if(parser[0].equals("GET")) {
System.out.println(">>> GET");

} else if(parser[0].equals("POST")) {
System.out.println(">>> POST");

}

if(parser[1].equals("/")) {
parser[1] = "/login.html";
}

msgResponse(readWWW(parser[1]));
}//if
} */

in.close();
is.close();
msgResponse(readWWW("/login.html"));

} catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
Thread.currentThread().interrupt();
}
};//run
};//new Thread()

runner.start();
}

/**
* Read a web file. They are contained inside "www" package, but this method can be
* modified to let it access to external files (just to test all the www files).
* @param argResource Filename to be red.
* @return File text (www resource).
*/
public String readWWW(String argResource) {
String thisLine;
StringBuffer thisText = new StringBuffer();

try {
// READ FROM JAR
//InputStream is = getClass().getResourceAsStream(new StringBuffer("www").append(argResource).toString());

// READ FROM DIRECTORY
InputStream is = new FileInputStream(new StringBuffer("www").append(argResource).toString());

BufferedReader br = new BufferedReader(new InputStreamReader(is));

while ((thisLine = br.readLine()) != null) {
thisText.append(thisLine);
}

br.close();
is.close();

} catch (Exception e) {
e.printStackTrace();
}

return thisText.toString();
}

}
ale870 at 2007-11-11 22:39:19 >
# 3 Re: Java does not execute all the code!
in.read(c) returns the number of bytes read into the byte[], which is always != -1.
what you want to check if more then 0 bytes are read.
ractoc at 2007-11-11 22:40:23 >
# 4 Re: Java does not execute all the code!
But JDK documentation says:

read

public int read()
throws IOException

See the general contract of the read method of InputStream.

Overrides:
read in class FilterInputStream

Returns:
the next byte of data, or -1 if the end of the stream is reached.
Throws:
IOException - if an I/O error occurs.
See Also:
FilterInputStream.in

It seems the only way to know if I reached the end of the file is "-1" check.

Do you think I can assume if read() returns "0" it means (always means!) I reached the end of file?
ale870 at 2007-11-11 22:41:29 >
# 5 Re: Java does not execute all the code!
I was carefully reading the documentation.

It seems "read()" blocks the execution until an input is available, or reached EOF.
Based on this information, it seems (in my code) the "read()" method is waiting for forever of the next byte... but this byte will never come!

Neither a byte nor an EOF are incoming, and the socket channel remain open, and the application remains locked.

So the next question is:

why the serverSocket remains open? Maybe I need to find-out a way to understand when the socket data are terminated.
ale870 at 2007-11-11 22:42:22 >
# 6 Re: Java does not execute all the code!
Here I am.

This is the solution. It seems java cannot correctly verify when the socket flow is completed.

In this case, you can use the following workaround:

int counter=0;

String s = in.readLine();

while( s.trim().length() > 0) {
System.out.println(new StringBuffer("<").append(counter++).append(">").append(s).toString());
s = in.readLine();
}

System.out.println("\n\n*** COMPLETED.");

NOTE: check the input channel using the syntax:

while( s.trim().length() > 0) {

Bye!

--Alessandro
ale870 at 2007-11-11 22:43:26 >