Share Process / Thread - java

I am facing a problem regarding Process and Threads. My Scenario is:
My Java Application, call it 'Starter-App', starts another exe Application (Diagnosis.exe) with ProcessBuilder within a named Thread:
Thread startGXThread = new Thread(new Runnable() {
#Override
public void run() {
try {
...
File gxExe = new File(pathToGX); // Path to Diagnosis.exe
gxp = pb.start();
gxp.waitFor();
} catch (IOException e) {
LOG.error("Can't start module");
LOG.error(e.getMessage(), e);
} catch (InterruptedException e) {
LOG.debug("thread interrupted. Destroy process");
LOG.debug(e.getMessage(), e);
if (gxp != null) {
gxp.destroy();
LOG.debug("process exit value: " + gxp.exitValue());
}
}
}
}, "diag_thrd");
Afterwards a jetty webserver (ServiceWebApp) is started with a webapp.
start chromium and 'Starter-App' listen when its closed.
Once chromium closes 'Starter-App' recognizes this and stops jetty and also terminate the startet application.Diagnosis.exe. This is done by:
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
stopAsync();
}
});
public static void stopAsync() {
Thread diag = getThread("diag_thrd");
if (diag != null) {
diag.interrupt();
}
if (gxp != null) {
gxp.destroy();
LOG.debug("process exit value: " + gxp.exitValue());
}
}
Question:
I need to be able to stop the startet Diagnosis.exe from within the webapp and start it again, while still be able to destroy/shutdown the Diagnosis.exe once chromium stops within 'Starter-App'.
I hope I could explain my problem and hope for suggestions.

Building on Anands answer, I think you need some form of IPC between the Diagnosis.exe and your Starter-App, using websockets, or a number of other options, for some ideas: How to have 2 JVMs talk to one another.
The webapp would send a request for restarting Diagnosis.exe to the Starter-App and the Starter-App would stay in charge of managing the application trio at all time.

I think there is a solution but a but tricky to implement.
You can always use *nix api's like ps kill #pid as explained in the example here Killing a process using Java
But your webserver has to know which PID's to look for. The only option I see to implement such thing is using sockets or webservices. So you keep track of what is the current pid of Diagnosis.exe process, and use that Id before killing.

Related

Dealing with multithreading in UI

I am actually using sockets listeners in a Java program.
The idea is to let my program run until it catches an external event. As soon as it catches it, I have to update my layout.
In order to let my application run while it was listening on a specific port, I did something like this :
// new thread allows me to let my program continue
new Thread() {
public void run() {
try {
while (true) {
try (ServerSocket listener = new ServerSocket(59090)) {
System.out.println("The server is running...");
// listening
while (true) {
try (Socket socket = listener.accept()) {
// catches event
System.out.println("event caught");
InputStream raw = socket.getInputStream();
headerData = getHeaders(raw);
// some code
// ...
// ...
// Update UI
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
The idea is that I constantly listen on the port 59090 and I execute my specific code once I use that port and that works well.
The problem now is when I catch an event.
It seems that I can't act on the UI if I am not in the "main" Thread. Am I right ?
Is it possible to send an information to my "main thread" in order to tell it to update UI ? Otherwise is it possible to "switch" my main thread to this one ?
EDIT:
I've seen that in Android you could use AsyncTask and the method onPostExecute() allows to send informations to the UI thread.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
Is there an equivalent in Java?
Thank you

How to make a thread wait for a server response

I am currently writing a small Java program where I have a client sending commands to a server. A separate Thread is dealing with replies from that server (the reply is usually pretty fast). Ideally I pause the Thread that made the server request until such time as the reply is received or until some time limit is exceeded.
My current solution looks like this:
public void waitForResponse(){
thisThread = Thread.currentThread();
try {
thisThread.sleep(10000);
//This should not happen.
System.exit(1);
}
catch (InterruptedException e){
//continue with the main programm
}
}
public void notifyOKCommandReceived() {
if(thisThread != null){
thisThread.interrupt();
}
}
The main problem is: This code does throw an exception when everything is going as it should and terminates when something bad happens. What is a good way to fix this?
There are multiple concurrency primitives which allow you to implement thread communication. You can use CountDownLatch to accomplish similar result:
public void waitForResponse() {
boolean result = latch.await(10, TimeUnit.SECONDS);
// check result and react correspondingly
}
public void notifyOKCommandReceived() {
latch.countDown();
}
Initialize latch before sending request as follows:
latch = new CountDownLatch(1);

tyrus websocket connectToServer - how to clean up daemon threads

tyrus websockets ClientManager connectToServer 'Handshake response not received'
how do I retry the connection without more and more daemon and Grizzly-kernel and Grizzly-worker threads created.
Is there a call to Session or client to kill/cleanup
Thread-1 to 4 and Grizzly-kernel and Grizzly-worker threads?
Example JAVA main line which attempts forever to make and maintain a connection with a server which may not be running or is periodically restart.
public void onClose(Session session, CloseReason closeReason) {
latch.countDown();
}
enter code here
public static void main(String[] args) {
while (true) {
latch = new CountDownLatch(1);
ClientManager client = ClientManager.createClient();
try {
client.connectToServer(wsListener.class, new URI("wss://<host>/ws"));
latch.await();
}
catch (DeploymentException e) {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
break;
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
client = null;
latch = null;
// HERE... clean up
}
}
client.connectToServer returns Session instance and when you call Session.close(), client runtime should be shut down (no threads left).
You did not specify version of Tyrus you are using (I recommend 1.3.3, we made some improvements in this area). Also you might be interested in our shared container support, see TYRUS-275. You could combine it with Thread pool config and you should have much better control of number of spawned/running threads.
We are always looking for new use cases, so if you think you have something which should be better supported in Tyrus, feel free to create new enhancement request on our JIRA.
I got this exact same behavior. I was using a lot of threads and synchronization and managed to accidently get the onOpen method of the ClientEndpoint blocking which caused the handshake to time out.

How to stop ServerSocket Thread correctly? Close Socket failed

I know this has been discussed some times before, but I can't find an appropriate solution for my problem. I want to run a ServerSocket thread in the background, listening to the specified port. It's working actually, but only once. Seems that the port the server is listening to is never closed correctly and still active when I try to restart (O don't restart the thread itself). Can some tell why it is not working correctly? Thanks in advance for any help...!
edit:
I have same problem on the client side. I have a sender thread and also that one cannot not be stopped. What is the best way to do that?
The ClientConnector is just a class which connects to the server port and sends the data.
It's not a thread or anything like that.
That's my sender class:
private class InternalCamSender extends Thread {
private int sendInterval = 500; // default 500 ms
private ClientConnector clientConn = null;
public InternalCamSender() {
this.sendInterval = getSendingInterval();
this.clientConn = new ClientConnector();
}
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()) {
clientConn.sendCamPdu(CodingScheme.BER, createNewPDU());
try {
Thread.sleep(sendInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
And I try to handle it's behaviour like that:
if(jButton_startSending.getText().equals(STARTSENDING)) {
new Thread() {
public void run() {
iSender = new InternalCamSender();
iSender.start();
jButton_startSending.setText(STOPSENDING);
}
}.start();
} else {
new Thread() {
public void run() {
if(iSender.isAlive()) {
iSender.interrupt();
try {
iSender.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
iSender = null;
jButton_startSending.setText(STARTSENDING);
}
}.start();
}
Somehow I cannot stop the InternalCamSender like that. I tried with a volatile boolean before, was the same. I read the http://download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html page and tried also the example What should I use instead of Thread.stop? but even that was not stopping the thread? I am lost.
Any ideas?
edit:
found the answer for my clinet sending problem here http://www.petanews.de/code-snippets/java/java-threads-sauber-beenden-ohne-stop/
even i don't know why that is working. I am sure I tried that way before.
Problem solved!
You should close your resources (the streams and socket) in a finally block, rather than a catch block - this way the resources are always closed, whether an exception is caught or not.
It's also a bad practice to call System.exit() from within a catch block or within a thread - you are forcibly shutting down the whole JVM on any instance of an error. This is likely the cause of your problem with the server socket as well - whenever any exception is encountered with reading/closing the streams, you are exiting the JVM before you have a chance to close the server socket.

Using threads and ProcessBuilder

I am really unfamiliar with working with threads, so I was hoping someone could help me figure out the best way to do this.
I have a JButton in my java application...when you click on the button, I have a Process Builder that creates a process which executes some external python code. The python code generates some files, and this can take some time. When the python code is done executing, I need to load those files into an applet within my Java application.
In its current form, I have a p.waitFor() within the code that calls the external python file...so when you click on the button, the button hangs (the entire application hangs actually) until the process is done. Obviously, I want the user to be able to interact with the rest of the application while this process is going on, but as soon as it's done, I want my application to know about it, so that it can load the files into the applet.
What is the best way to do this?
Thanks for your help.
You should use SwingWorker to invoke the Python process on a background thread. This way your UI will remain responsive whilst the long-running task runs.
// Define Action.
Action action = new AbstractAction("Do It") {
public void actionPerformed(ActionEvent e) {
runBackgroundTask();
}
}
// Install Action into JButton.
JButton btn = new JButton(action);
private void runBackgroundTask() {
new SwingWorker<Void, Void>() {
{
// Disable action until task is complete to prevent concurrent tasks.
action.setEnabled(false);
}
// Called on the Swing thread when background task completes.
protected void done() {
action.setEnabled(true);
try {
// No result but calling get() will propagate any exceptions onto Swing thread.
get();
} catch(Exception ex) {
// Handle exception
}
}
// Called on background thread
protected Void doInBackground() throws Exception {
// Add ProcessBuilder code here!
return null; // No result so simply return null.
}
}.execute();
}
You really want to create a new thread for monitoring your new process. As you've discovered, using just one thread for both the UI and monitoring the child process will make the UI seem to hang while the child process runs.
Here's some example code that assumes the existence of a log4j logger which I think will illustrate one possible approach...
Runtime runtime = Runtime.getRuntime();
String[] command = { "myShellCommand", "firstArgument" };
try {
boolean done = false;
int exitValue = 0;
Process proc = runtime.exec(command);
while (!done) {
try {
exitValue = proc.exitValue();
done = true;
} catch (IllegalThreadStateException e) {
// This exception will be thrown only if the process is still running
// because exitValue() will not be a valid method call yet...
logger.info("Process is still running...")
}
}
if (exitValue != 0) {
// Child process exited with non-zero exit code - do something about failure.
logger.info("Deletion failure - exit code " + exitValue);
}
} catch (IOException e) {
// An exception thrown by runtime.exec() which would mean myShellCommand was not
// found in the path or something like that...
logger.info("Deletion failure - error: " + e.getMessage());
}
// If no errors were caught above, the child is now finished with a zero exit code
// Move on happily

Categories

Resources