Communication between java programs

K

Kin C. Wong

I am attempting to create a GUI that starts up and monitors 2 other
java programs (running as separate processes on a windows machine). I
am using the GUI to start one of the processes as follows (the other
is started in a similar fashion):

process = "java SSSP_Server.Server";
Runtime rtPrimary = Runtime.getRuntime();
Process pidPrimary = rtPrimary.exec(process);

dataInPrimary = new
DataInputStream(pidPrimary.getInputStream());
getPrimaryMessages(); // thread to listen for input

The getPrimaryMessages() is a thread that listens for the output of
the new process that was created. The listing for that method is:

//doGetPrimaryMessages is a boolean that is initialized to true.

private void getPrimaryMessages() {
Runnable getMessage = new Runnable() {
public void run() {
while (doGetPrimaryMessages) {
try {
String message = dataInPrimary.readUTF();
updateDisplaySafely(message);
} catch (IOException ioe) {
doGetPrimaryMessages = false; // Causes this
thread to stop.
}
}
}
};


The problem is that I'm not getting anything from the input stream. In
pidPrimary I am just using System.out.println() to write to the std
output. Is the output of the the pidPrimary process somehow blocked
because it is running through the JVM? I've also tried putting the
line "start java SSSP_Server.Server" into a bat file and calling the
bat file to start the process, but I get the same result.

Am I doing something wrong or is this not the way to communicate
between processes? I know I could use sockets, but the purpose of the
GUI is to just provide a single window to view the status messages of
the 2 processes I'm running. The GUI doesn't really need to talk to
the processes other than to start them up.

Thanks in advance for any information.
- Kin
 
W

William Brogden

Kin C. Wong said:
I am attempting to create a GUI that starts up and monitors 2 other
java programs (running as separate processes on a windows machine). I
am using the GUI to start one of the processes as follows (the other
is started in a similar fashion):

process = "java SSSP_Server.Server";
Runtime rtPrimary = Runtime.getRuntime();
Process pidPrimary = rtPrimary.exec(process);

dataInPrimary = new
DataInputStream(pidPrimary.getInputStream());
getPrimaryMessages(); // thread to listen for input

The getPrimaryMessages() is a thread that listens for the output of
the new process that was created. The listing for that method is:

//doGetPrimaryMessages is a boolean that is initialized to true.

private void getPrimaryMessages() {
Runnable getMessage = new Runnable() {
public void run() {
while (doGetPrimaryMessages) {
try {
String message = dataInPrimary.readUTF();
updateDisplaySafely(message);
} catch (IOException ioe) {
doGetPrimaryMessages = false; // Causes this
thread to stop.
}
}
}
};


The problem is that I'm not getting anything from the input stream. In
pidPrimary I am just using System.out.println() to write to the std
output. Is the output of the the pidPrimary process somehow blocked
because it is running through the JVM? I've also tried putting the
line "start java SSSP_Server.Server" into a bat file and calling the
bat file to start the process, but I get the same result.

Try System.out.flush() - the output data may be sitting in a buffer.
 
M

Matt Humphrey

Kin C. Wong said:
I am attempting to create a GUI that starts up and monitors 2 other
java programs (running as separate processes on a windows machine). I
am using the GUI to start one of the processes as follows (the other
is started in a similar fashion):

process = "java SSSP_Server.Server";
Runtime rtPrimary = Runtime.getRuntime();
Process pidPrimary = rtPrimary.exec(process);

dataInPrimary = new
DataInputStream(pidPrimary.getInputStream());
getPrimaryMessages(); // thread to listen for input

The getPrimaryMessages() is a thread that listens for the output of
the new process that was created. The listing for that method is:

//doGetPrimaryMessages is a boolean that is initialized to true.

private void getPrimaryMessages() {
Runnable getMessage = new Runnable() {
public void run() {
while (doGetPrimaryMessages) {
try {
String message = dataInPrimary.readUTF();
updateDisplaySafely(message);
} catch (IOException ioe) {
doGetPrimaryMessages = false; // Causes this
thread to stop.
}
}
}
};

Keep in mind that when you launch an external program that it may generate
both standard output and error output. If you only read one of these--or
try to read them sequentially--the external program will block waiting for
you to read. In the mean time your java program will block waiting for more
input and you get deadlock. You should always read both in separate
threads.

In addition, looking at the error stream may give you an idea of what's
going wrong.

The problem is that I'm not getting anything from the input stream. In
pidPrimary I am just using System.out.println() to write to the std
output. Is the output of the the pidPrimary process somehow blocked
because it is running through the JVM? I've also tried putting the
line "start java SSSP_Server.Server" into a bat file and calling the
bat file to start the process, but I get the same result.

Check your path to make sure it's even finding the bat/java. Use absolute
path names to be sure.
Am I doing something wrong or is this not the way to communicate
between processes? I know I could use sockets, but the purpose of the
GUI is to just provide a single window to view the status messages of
the 2 processes I'm running. The GUI doesn't really need to talk to
the processes other than to start them up.

Thanks in advance for any information.
- Kin

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
K

Kin C. Wong

Thanks for the tips, but I'm still not getting anything from the input
streams.
Try System.out.flush() - the output data may be sitting in a buffer.
The flush() doesn't seem to do anything.
Keep in mind that when you launch an external program that it may generate
both standard output and error output. If you only read one of these--or
try to read them sequentially--the external program will block waiting for
you to read. In the mean time your java program will block waiting for more
input and you get deadlock. You should always read both in separate
threads.

In addition, looking at the error stream may give you an idea of what's
going wrong.
I know about reading the error stream, but I figured I'd try to do a
proof-of-concept prototype and just implement reading the output
stream first. But anyway, I put in the code to read the error stream
in separate threads and still nothing.
Check your path to make sure it's even finding the bat/java. Use absolute
path names to be sure.
The processes got started OK and are running because they are socket
server applications and I can connect clients to them. But their
standard outputs are not making it back to the GUI's input stream.

Any other tips or things to try?

Thanks,
Kin
 
M

Matt Humphrey

Kin C. Wong said:
Thanks for the tips, but I'm still not getting anything from the input
streams.

Any other tips or things to try?

-- This is your code from your original message. It's ordinary reading
code, but I've noticed that if taken literally, it does not actually do
anything at all. Your first two lines create your data input stream
(presumably there's an assignment) and then you getPrimaryMesasges. This
method creates a runnable, but I don't actually see where it starts the
thead. Have you left out the (new Thread (getMessage)).start () ? Can you
give the *exact* code that you're using?

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/

-------------------------------------------------

DataInputStream(pidPrimary.getInputStream());
getPrimaryMessages(); // thread to listen for input

The getPrimaryMessages() is a thread that listens for the output of
the new process that was created. The listing for that method is:

//doGetPrimaryMessages is a boolean that is initialized to true.

private void getPrimaryMessages() {
Runnable getMessage = new Runnable() {
public void run() {
while (doGetPrimaryMessages) {
try {
String message = dataInPrimary.readUTF();
updateDisplaySafely(message);
} catch (IOException ioe) {
doGetPrimaryMessages = false; // Causes this
thread to stop.
}
}
}
};
 
K

Kin C. Wong

-- This is your code from your original message. It's ordinary reading
code, but I've noticed that if taken literally, it does not actually do
anything at all. Your first two lines create your data input stream
(presumably there's an assignment) and then you getPrimaryMesasges. This
method creates a runnable, but I don't actually see where it starts the
thead. Have you left out the (new Thread (getMessage)).start () ? Can you
give the *exact* code that you're using?

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/

-------------------------------------------------

Sorry, I probably left some parts out when cutting and pasting. The
thread does get started but I'm just not getting anything fom the
dataInPrimary.readUTF(). It seems like the input stream does get set
up, because I get the "Waiting to read input stream" message in
getPrimaryMessages. I also tried using a BufferredReader, but that
doesn't seem to work either.

Thanks for taking the time to look at this.

Here's the getPrimaryMessages method:

private void getPrimaryMessages() {
Runnable getMessage = new Runnable() {
public void run() {
while (doGetPrimaryMessages) {
try {
System.out.println("Waiting to read input
stream.");
String message = dataInPrimary.readUTF();
System.out.println(message);
updateDisplaySafely(message);
} catch (IOException ioe) {
System.out.println("Error reading input
stream.");
try {
dataInPrimary.close();
} catch (IOException ioe2) {
}
doGetPrimaryMessages = false; // Causes this
thread to stop.
//some cleanup code to reset GUI buttons, etc.
btnStartPrimary.setEnabled(true);
btnKillPrimary.setEnabled(false);
}
}
}
};

Thread getMessagesThread = new Thread(getMessage);
getMessagesThread.start();
}


Here's where I create the Primary process. It's an action tied to a
button:

class StartPrimaryAction extends AbstractAction {
public StartPrimaryAction(String name, Icon icon) {
super(name, icon);
}

public void actionPerformed(ActionEvent ae) {
String process = "java SSSP_Server.Server";
//String process = directory + "SSSP_Primary_Server.bat";
//Kill won't work if running through bat file.
try {
rtPrimary = Runtime.getRuntime();
pidPrimary = rtPrimary.exec(process);
System.out.println("Starting " + process);

//dataInPrimary = new BufferedReader(new
InputStreamReader(pidPrimary.getInputStream()));

dataInPrimary = new
DataInputStream(pidPrimary.getInputStream());
errorInPrimary = new
DataInputStream(pidPrimary.getErrorStream());

doGetPrimaryMessages = true;
doGetPrimaryErrors = true;
getPrimaryMessages();
getPrimaryErrors();
} catch (Exception e) {
System.out.println("Error starting Primary Server.");
System.out.println(e);
}
btnStartPrimary.setEnabled(false);
btnKillPrimary.setEnabled(true);
}
}
 
K

Kin C. Wong

I got it to work with a BufferredReader. When I used tried the
BufferredReader originally, I had declared it locally so I got some
kind of null pointer in the getPrimaryMessages.

I should probably study up on the different type of readers. Anyone
have a good reference that explains the different types of readers and
writers and when to use them?

Thanks again for taking the time to look at this.

Kin
 
N

nos

he is talking about this

Les informations contenues dans le present message et dans tous les
fichiers electroniques qui y sont attaches, sont strictement
confidentielles et ne sont destinees qu'a l'usage de la personne dont le
nom apparait ci-dessus et de toute autre personne specifiquement
autorisee a les recevoir. Si vous n'etes pas la personne a qui ces
informations sont destinees, nous vous informons qu'il est strictement
interdit de les diffuser, de les utiliser ou d'en faire des copies. Si
vous avez recu ce message electronique par erreur, ou si des problemes
de transmission surviennent, nous vous remercions d'en aviser
immediatement l'expediteur ou de telephoner au (33-1) 41.48.10.19.
Attention : Tout message electronique est susceptible d'alteration.
AONIX decline toute responsabilite au titre de ce message s'il a ete
altere, deforme ou falsifié.

This message and any attachments (the « message « ) is intended solely
for the addressees and is confidential. If you receive this message in
error, please delete it and immediately notify the sender (33-1)
41.48.10.19. Any use not in accord with its purpose, any dissemination
or disclosure, either whole or partial, is prohibited except formal
approval. The internet can not guarantee the integrity of this message.
AONIX shall not therefore be liable for the message if modified.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top