I seem to be having an issue with a program I am creating. It should be a simple program that sends commands from a Java program to a Groovy script (whether the script be on the same computer or another on the network) but I am running into some problems.

I have found a very simple TCP/IP client snippet and am trying to get it to access a groovy script I have created that is listening on port a certain port.

Before implementing this in my program, I did a simple test with telnet. It came back with positive results so I went ahead and tried it out. Unfortunately I have received the following exception: java.io.StreamCorruptedException: invalid stream header: 57686174

Here is my Java program source:

public class Client {

    Socket requestSocket;
    ObjectOutputStream out;
    ObjectInputStream in;
    String message;


    Client() {


    }

    void run() {
        try {
            requestSocket = new Socket("localhost", 1960);
            System.out.println("Connected to localhost in port 1960");

            out = new ObjectOutputStream(requestSocket.getOutputStream());
            out.flush();
            in = new ObjectInputStream(requestSocket.getInputStream());

            do {
                try {
                    message = (String)in.readObject();
                    System.out.println("server>" + message);
                    sendMessage("dir");
                }
                catch(ClassNotFoundException classNot) {
                    System.err.println("Data received in unknown format");
                }
            } while(!message.equals("exit"));
        }
        catch(UnknownHostException unknownHost) {
            System.err.println("You are trying to connect to an unknown host!");
        }
        catch(IOException ioException) {
            ioException.printStackTrace();
        } finally {
            try {
                in.close();
                out.close();
                requestSocket.close();
            }
            catch(IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }



    void sendMessage(String msg) {
        try {
            out.writeObject(msg);
            out.flush();
            System.out.println("client>" + msg);
        }
        catch(IOException ioException) {
            ioException.printStackTrace();
        }
    }



    public static void main(String args[]) {
        Client client = new Client();
        client.run();
    }


}

Here is my groovy script (forgive me im new to groovy):

//variables
def serialNo
def ipAddress
def hostName
def operatingSystem
def test

server = new ServerSocket(1960)
while(true) {
	server.accept() { socket ->
		socket.withStreams { input, output ->
			// def writer = new BufferedWriter(new OutputStreamWriter(output));
			w << "What is your command? "
			w.flush()
			def reader = new BufferedReader(new InputStreamReader(input));

			r = reader.getText();
	
			if(r=="serial") {
				getSerialNo();
			} else if(r=="dir") {
				getTest();
			} else if(r=="os") {
				getOperatingSystem();
			} else if(r=="host") {
				getHostName();
			} else if(r=="ip") {
				getIpAddress();
			} else if(r=="passthru") {
				//research passing through computers on a network
			} else if(r=="exit") {
				println "Goodbye."
				writer.close()
				reader.close()
			} else {
				println " $r command unknown."
			}

			reader.close()
			writer.close()
		}
	}
}

def getTest() {
	test = "cmd /c dir".execute().text
	println test
	return this.test
}

def getSerialNo() {
	
	//search for hard drives on computer
	//search for file containing serial no.
	return this.serialNo;
}

def getIpAddress() {
	ipAddress = "text"
	return this.ipAddress;
}

def getHostName() {
	machineName = "hostname".execute().text
	return this.operatingSystem;
}

def getOperatingSystem() {
	operatingSystem = "uname -a".execute().text
	return this.operatingSystem;
}

I did some reading on the exception I am getting but couldn't find any definitive answers.

The only thing I could come up with is there might be an issue with my Java program when sending the message over to the computer that is running the groovy script. (for right now im just testing on the same computer)

Output:

Connected to localhost in port 2000
java.io.StreamCorruptedException: invalid stream header: 57686174
        at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:783)
        at java.io.ObjectInputStream.<init>(ObjectInputStream.java:280)
        at testapp.Client.run(Client.java:47)
        at testapp.Client.main(Client.java:198)
Exception in thread "main" java.lang.NullPointerException
        at testapp.Client.run(Client.java:67)
        at testapp.Client.main(Client.java:198)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 seconds)

Anyone have some suggestions?

When you open an ObjectInputStream it attempts to first read the "header" (which will automatically be created upon creating an ObjectOutputStream on the other end), which the API docs clearly state. And, since your groovy script is not creating an ObjectOutputStream for your java program to read your ObjectInputStream fails. Why are you even attempting to open any kind of InputStream on the Java side if your Groovy script is not sending anything? And your using a BufferedReader on the Groovy side will not work with an ObjectOutputStream from the Java side. It would only receive a lot of nonsensical garbage.

Edit: Okay, I see you are writing from the groovy side (although it is sometimes w and sometimes writer and neither, as far as I can see, is ever defined). But, it seems to be a Character stream. So again, why the Object Streams Java side and the character reader/writer on the groovy side. That is destined to fail.

First of all, thank you for the reply masijade.

since your groovy script is not creating an ObjectOutputStream for your java program to read your ObjectInputStream fails.

Thank you for clearing that up. This seems like it is what causes the issue.

Why are you even attempting to open any kind of InputStream on the Java side if your Groovy script is not sending anything?

Edit: Okay, I see you are writing from the groovy side (although it is sometimes w and sometimes writer and neither, as far as I can see, is ever defined).

Basically my script is just supposed to get commands from the java program. In my test I would send a simple string "dir" and it would be sent to the script, and the script would then check what it should do based on the text command that was sent. For example, when 'dir' was sent, it would go to the command prompt and print out a dir of the c drive.

Now my test examples worked because it was from command prompt to command prompt. So I'll need to modify the script to handle objects (if I understand your response correctly)

Sorry for the confusion on the writing from the groovy side, I originally had it as 'w' and then changed it to 'writer' but had issues and right before posting I changed it back to 'w' but missed changing the 'writer.close()' to 'w.close()'

My script has to act as a server and a client. It will be providing information to my java program but will also have to be used as a pass through because my java program won't be able to reach certain computers on the network.

But, it seems to be a Character stream. So again, why the Object Streams Java side and the character reader/writer on the groovy side.

That would be where I messed up! I believe I'll have to change it all to Object Streams.

I'll work on the script and get post back

I'm a bit late on replying to the thread but so far it looks like I have it working the way I want it to. If I have anymore problems, I'll post back and hopefully you'll reply.

Do you see any way I could improve my code?

Client:

public class Client {

    Socket requestSocket;
    BufferedWriter out;
    BufferedReader in;
    String message;


    Client() {


    }

    void run() {
        try {
            requestSocket = new Socket("localhost", 1960);
            System.out.println("Connected to localhost in port 1960");

            in = new BufferedReader(new InputStreamReader(requestSocket.getInputStream()));
            out = new BufferedWriter(new OutputStreamWriter(requestSocket.getOutputStream()));

            do {
                try {
                    message = in.readLine();
                    System.out.println("server>" + message);
                    sendMessage("dir");
		    sendMessage("exit");
                }
                catch(ClassNotFoundException classNot) {
                    System.err.println("Data received in unknown format");
                }
            } while(!message.equals("exit"));
        }
        catch(UnknownHostException unknownHost) {
            System.err.println("You are trying to connect to an unknown host!");
        }
        catch(IOException ioException) {
            ioException.printStackTrace();
        } finally {
            try {
                in.close();
                out.close();
                requestSocket.close();
            }
            catch(IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }



    void sendMessage(String msg) {
        try {
            out.write(msg);
            out.flush();
            System.out.println("client>" + msg);
        }
        catch(IOException ioException) {
            ioException.printStackTrace();
        }
    }



    public static void main(String args[]) {
        Client client = new Client();
        client.run();
    }


}

Server:

//variables
def serialNo
def ipAddress
def hostName
def operatingSystem
def test

server = new ServerSocket(1960)
println("Waiting for connection");
while(true) {
	server.accept() { socket ->
		socket.withStreams { input, output ->
			
			w = new BufferedWriter(new OutputStreamWriter(output))
			String message = "Connection was successful"
			w.writeLine(message)
			w.flush()

			r = new BufferedReader(new InputStreamReader(input))
			String a = r.readLine()

	
			if(a=="serial") {
				getSerialNo();
			} else if(a=="dir") {
				getTest();
			} else if(a=="os") {
				getOperatingSystem();
			} else if(a=="host") {
				getHostName();
			} else if(a=="ip") {
				getIpAddress();
			} else if(a=="passthru") {
				//research passing through computers on a network
			} else if(a=="exit") {
				println "Goodbye."
				writer.close()
				reader.close()
			} else {
				println " $r command unknown."
			}

			r.close()
			w.close()
		}
	}
}

def getTest() {
	test = "cmd /c dir".execute().text
	println test
	return this.test
}

def getSerialNo() {
	
	//search for hard drives on computer
	//search for file containing serial no.
	return this.serialNo;
}

def getIpAddress() {
	ipAddress = "text"
	return this.ipAddress;
}

def getHostName() {
	machineName = "hostname".execute().text
	return this.operatingSystem;
}

def getOperatingSystem() {
	operatingSystem = "uname -a".execute().text
	return this.operatingSystem;
}

It runs smoothly, but I'm sure there are ways of improving it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.