How can I ensure all Java threads die - java

I am writing a multithreaded Java program, which I will run from the command prompt. It's got both a gui (javafx) and a lot of background threads. If I hit Ctrl+C from the command prompt that I started the program with, it asks "Terminate Batch job? Y/N" and I hit Y and then I'm simply returned to the prompt. However - I am wondering if there by any chance might still be running any background threads that weren't terminated gracefully?

Your "main" code and all the threads run in JVM. If you terminate JVM (as process) then everything running in it will be terminated as well.
More on "catching" ctrl+c: Catching Ctrl+C in Java

As far as I know, there's no way to "catch" or "intercept" Ctrl+C "event" from the command line, so your can't really tell if there are any unfinished threads and end them gracefully. (disappointing, I know).

Related

Stop a CMD run from SQL Job

I need to have a java program always running in the background. I've set it up as a SQL Job that runs periodically, running the Java from CMD. The job runs periodically to check if the Java program is still active.
The issue I'm encountering is that if I stop the SQL Job, the Java program seems to continue running. I need a way to stop the program. Without the ability to stop the Java program, I can't rerun the Job.
Any ideas?
With the given information, I understand, that although you are periodically starting your Java program, it is not exiting.
Maybe you should check if your Java program ever exits.
If it does, then from your Java program, you could check if the corresponding job is enabled/disabled in the sysjobs table, and decide whether or not to stop running the Java program.

How do I stop a daemon thread that does scheduled database backup ?

I've written a very simple command line programme that uses mysqldump to dump data at a specified interval. I wanted it to be running after I run the programme and I disconnect putty ssh connection.
But as soon as I exit the ssh connection, the programme shuts down.
I think I can make my programme run even after I disconnected from the ssh by using daemon threads but I'm worried about not being able to find and stop unnecessary duplicate daemon threads.
The scenario I'm decribing is...
1. I log into the server using putty.
2. Turn on the auto backup programme.
3. I exit the putty connection.
---the daemon is running
4. Hopefully, when I log into the server again, I have a way to stop the auto backup programme if needed.
Cron jobs and DBMS specific methods are out of my options. I'd like to learn how to do the job described above and use it where ever the situation fits not just database backup.
Any good ideas ? : )
In short, you have to launch your program in a special way, and you have (at least) two options: nohup or screen.
Let's now discuss why and how each one works.
nohup
Java's daemon threads is not what you are looking for, they have nothing to do with the issue. You can use normal threads (or even a single-threaded java program). You just need to change the way you launch your java program.
I have many executable jars that run as "daemons" on a bunch of servers, and I made a simple launch script that prepares the environment and makes it possible to terminate the SSH connection without stopping it. The main part is how to invoke the JVM: you use nohup.
nohup java -jar myfile.jar > stdout.log &
From nohup's man,
nohup - run a command immune to hangups, with output to a non-tty
So, when you terminate your SSH connection, it will send SIGHUP to all processes it started which would terminate them as you are observing. With nohup, however, your process is immune to it.
Also, note that I redirect the standard output to a file called stdout.log. This is done so that you can see whatever your program writes to STDOUT (generally some logging information that would be useful for debugging).
To terminate your program, you can use jps to list the PID of your process (say it's 123), then call kill 123. Note that for this to work your program needs to correctly handle this kind of shutdown (which involves adding a shutdown hook with Runtime.getRuntime().addShutdownHook(...) which will terminate all the threads you launched).
If, for whatever reason (a bug, or you didn't implement a graceful shutdown), the program won't terminate after issuing the kill command (which sends the process a SIGTERM), you can change the signal it sends to SIGKILL with kill -9 123, which will simply destroy the process. Mind that this can be as dangerous as a power failure (ie, suppose you are in the middle of the try block of a try {} finally {} -- your finally block will not execute!).
screen
There's an alternative, which is to use SCREEN. With it, you launch a shell that is also immune to shutdowns, and that you can share among many connections. To use it, connect to your server, and then:
screen -R
A new shell will start, in which you run your java program as normal:
java -jar myfile.jar
To make it go to the background, just press ctrl+a ctrl+d. To bring it back to the front, just execute screen -R again. If you wish to terminate your program, you could do so by entering the screen session again and pressing ctrl+c (if your java program correctly deals with this kind of shutdown).
Two possibilities for scheduled tasks, in order from least to most complex, are the TimerTask and the Quartz Scheduler. Both offer the option to cancel/delete the scheduled job.

Strange behavior re-runing java application in a loop

Unix daemon runs a script a loop, the script calls a java program: java {java_args} myClas.jar
The java program is heavy program with multiple threads.
The problem is very strange: First execution works as expected.
But the second execution is stuck some where and I can't find a reason (very hard to debug this).
Is there a possibility that when first execution is finished there are still not-cleaned resources or threads left from this execution?
If yes, is it possible to clean and kill everything right after process completes?
If by resources, you mean threads, then no. When the VM shuts down, everything on the heap, all threads, objects and monitors are disposed of. However if you're depending on the existence/absence of a file for locking or something similar, a deadlock is possible. Also, is it possible that the first process is still running when you launch the second one?
If your java process is stuck on the second run, you can attach jvisualvm to it and should be able to figure out where it's stuck.

Runtime.exec getting killed by System.exit?

I have a java program that is supposed to run a bat file, and then exit with a success code 0.
The code essentially looks like this
Runtime.exec(....);
System.exit(0);
99.8% of the time, this works perfectly. But very sporadically the bat file won't get run.
My theory is that on certain systems, the Runtime.exec can't finish its spawning before the System.exit runs. Is this likely/possible?
I looked at the source of Runtime.exec but it drops into native code to do the interesting stuff.
EDIT
Based on the answers so far, I should state that the .bat file executes another java process using javaw. I can confirm that the 1st java process ending does NOT kill the 2nd one run in the bat file.
Is it possible that when the problem happens the bat file hadn't spawned the 2nd java process before the System.exit occurred? Perhaps it is not a Runtime.exec problem after all?
EDIT2
I cannot wait for the 2nd process to end, it could run indefinitely and my 1st process must exit.
Try to change to ProcessBuilder. Maybe it works better.
You are creating a child process that will terminate with its parent. You must use Process.waitFor in Java to ensure that Java process waits for the bat process to finish.
System.exit(0) kills jvm instance. All process will be terminated. If you want to really execute System.exit(0), make sure exec process is done before calling System.exit.
Use Process.waitFor(), the return type of this method is int which gives you the return code as per your current solution using Runtime.
waitFor() causes the current thread to wait, if necessary, until the process represented by this Process object has terminated.
Change it to
Runtime.getRuntime().exec(....).waitFor();
System.exit(0);
But then this will wait for batch file to complete execution and in your case completion of javaw instance.

Find, from a ShutdownHook, why a program exits

If I've got a Java program that can exit for various reasons, like:
because the main window, which is set to "exit on close", was closed
because there are some System.exit( 0 ) in the code
because there are no more window at all (and none was set to exit on close) but there's still several threads running then at one point there are only daemon threads running and hence the program exits.
And I've got a shutdown hook installed (which is running fine).
Is there any way to know, from my shutdown hook, what caused the Java program to exit?
(note that I'm not asking if it's a good idea or not to have System.exit(...) spread over the codebase: this is not what this question is about)
Basically I'd like to know if I'm forced myself to intercept every single possible JVM exit point and add infos there or if there's already a method allowing to do that.
You can add a SecurityManager which will be called on System exit (to determine if its allowed). You can save where this was called for later or deal with it in the SecurityManager.
Your shutdown hook will just run your runnable logic in a separate thread when the JVM is shutting down. You cant do anything more with this.

Categories