Re-connecting to a process using Java - java

I'm attempting to connect to a process I created before my application closed.
So basically my method will be to ensure a few processes are running before my Java APP continues, if the processes are not running the app will create new processes. I just do not want to have these processes running as child processes.
I'm already maintaining the PID of the processes i start in a pids file so I know which process I should attempt to reconnect to upon rebooting my app but I have no clue how to actually go ahead and actually re-attach to an existing Process and listen to the input/output stream.
Right now I'm just holding reference to the Process object created by the ProcessBuilder but I'd like to not rely on child processes as they'll be killed once the JVM exits and want them to remain running.

Related

How to uniquely identify a java process after multiple restart

I have number of java process running on my machine. I need to track how many times each process is getting restarted.
For Example:
Let us consider two java process
Process 1 - Its restarted for 5 times.
Process 2 - Its restarted for 2 times.
I'm able to get the PID, java command of the running processes. But I could not able to differentiate once the process got restarted. Because the PID changed after the restart. Also I can't consider the java command because two instance of same application which has same command.
So what are the other ways to track the java process restart ?
You want your processes to keep the same identity after a restart. Ideally, you would have a parameter, system property or environment variable telling the process its identity.
As you state in the question, this identity cannot be passed on the command line. Thus, the process has to "find" its identity by acquiring an exclusive resource.
This resource could be a shared system implementing locks but it is probably to complex.
As exclusive resources, we have network sockets. So you could make your processes artificially opening a socket in the sole objective to make it acquire an identity.
You can use the code from https://stackoverflow.com/a/116113/2242270 in order to open a socket in a range. The identity of the process is then the port that could be opened.

How to check a process is killed and started again in linux command

I have command where it performs a sort of front end restart. This process kills the currently running java instance (process) and once the restart completes, it automatically restarts the java instance (as a result of front end restart).
Is there a way to monitor(observe) this process (killing process and re-spawn) process using one command.

How to manage Process and ProcessBuilder objects from Java WebApplication

From my java web application I am creating process object and after passing commands I am starting the process.
Along with the process start I am maintaining another thread which is keeping a look at the exit value of the current process.
Does this process.exitValue() causes the current thread to wait?
Updated Question:
Please can you give some information about why process.destroy() is able to kill gcc(for c and c++) , java processes, but while coming to c# programs running in mono these processes cannot be destroyed, why?
And can I get pid value from the Process object while running it in ubuntu server to kill the process by pid ?
To wait end of created process you can use Process.waitFor()
exitValue doesn't wait process termination. Moreover it will throw exception in case if process still in progress.

Java Runtime.exec communictation possible?

I have a main java program which should launch other java programs in an own process using Runtime.exec(), e.g.
Runtime.exec("java -jar myapp.jar");
Is there a possibility to communicate with this new process, e.g. sending request, chaing fields...?
How can I shutdown this new created process? I think I get an handler back and thus can kill the process. But is there a nicer way?
If I kill the process, will the shutdownhook still be executed before the process is killed?
Runtime.getRuntime().addShutdownHook
Is there a possibility to communicate with this new process, e.g. sending request, chaing fields...?
You can communicate with the process through the Process object returned by Runtime.exec. Just use Process.getInputStream/.getOutputStream.
If you want to invoke methods on the other Java process you could look into RMI ("Remote method invocation"). Another option is of course sockets. See this related answer.
There's no straight forward platform independent way of changing fields of the other Java process.
If I kill the process, will the shutdownhook still be executed before the process is killed?
Depends on how you kill it, but typically, yes, the shutdown hooks will be executed.

How to kill a child process spawned by Java when tomcat is shutdown

I have written a service for JIRA(a web application runs in tomcat) which runs periodically(say 1 hour). Basically, the service executes a system command thru runtime.exec(command) and parses the output generated by the command then updates a Lucene index with it, output will be huge.
The problems are:
1) If I shutdown tomcat with shutdown.sh while the above service is executing, the java(or the catalina) process is not getting killed. Both the java & child process are living for a while i.e., until the system command completes & service processes the output. But then the service fails to update the index leaving the index in an inconsistent state.
If I shutdown tomcat when the above service is not running, everything is good. I think, this is explained here. I am still not clear why JVM won't shutdown as the above service is running within tomcat?
Note that this is the only java app running on that machine.
2) Then, if I kill java using kill <pid>, both the java & child process are getting killed contradicting to this post.
Is this because the child process is sending output to parent(java) and once parent is killed, the child has no idea where to send the output and thus got killed ?
3) I tried to use shutdownhook as explained in this post, but that's not working for me. The code inside the shutdownhook is getting executed only after the java & child processes are done with their work. So, calling process.destroy() inside shutdownhook is not useful here.
This seems obvious, as the JVM is still running in my case, it won't call shutdownhooks until it starts it's shutdown sequence. Don't know how this worked for the other guy, I mean, how come the child process spawned by java is still running when JVM is down.
4) If I restart tomcat, new java process with different pid is generated.
Is it possible to stop the child process programmatically when tomcat is shutdown ?
Let me know if I am not clear with my explanation...
Here is the code that executes system command:
String command = getCommand();
File view = new File(viewPath);
Runtime runtime = Runtime.getRuntime();
try
{
final Process process = runtime.exec(command, null, view);
StreamReader errorStreamReader = new StreamReader(process
.getErrorStream());
Thread errorStreamThread = new Thread(errorStreamReader);
errorStreamThread.start();
revisions = parseRevisionLogs(process.getInputStream());
process.waitFor();
process.getInputStream().close();
process.getErrorStream().close();
process.getOutputStream().close();
}
The JVM will not shutdown unless the threads that are left are marked as "daemon". Any non-daemon user threads must finish before the JVM will exit. See this question. If your periodic tasks are not set with setDaemon(true) then they will have to finish before the JVM will exit. You have to call setDaemon before the process starts.
You should be able to make your periodic tasks to be daemon however you do have a race condition with JVM shutdown. You might consider having one daemon task doing the reading from the process but having a non-daemon task do the updating of the index which probably should not get killed while it is working.
Your non-daemon thread could then be sleeping, waiting for the load to finish, and testing to see if it should terminate with a volatile boolean field or other signal.
I'd suggest you to do the following.
Do not read the process' output directly from java. Instead redirect the output to file and read it from there when process is terminated. Wrap your command using batch file or shell script that stores the PID of separate process, so that you will be able to kill this process separately. Now add shutdown hook to tomcat that will run kill PID where PID is the process ID of separate process.
I believe this will work because now your tomcat and separate process are totally decoupled, so nothing bothers tomcat to shutdown. The same is about the process.
Good luck.
Are you doing a waitFor() on the process?
If so you could catch InterruptedException and to a p.destroy()

Categories