Terminate a Thread thats running a jar - java

I have a class that extends Thread and when started, it runs a jar's Main method. When I terminate the Thread it does not kill the process it started. How do I go about that? Thanks!
Below if the run() method from my custom Thread class.
#Override
public void run() {
if(parent != null) {
MessageConsole console = new MessageConsole(parent.getConsole().getTextPane());
console.redirectOut(new Color(240, 240, 240), null);
console.redirectErr(Color.RED, null);
console.setMessageLines(20);
}
if(oParent != null) {
MessageConsole console = new MessageConsole(oParent.getConsole().getTextPane());
console.redirectOut(new Color(240, 240, 240), null);
console.redirectErr(Color.RED, null);
console.setMessageLines(20);
}
try {
somejar.SomeJar.main(args);
} catch (Exception ex) {
System.err.println("Engine failed to start!\nSuggestion: Restart the application, and if the issue is not fixed reinstall the application.");
}
}

When I terminate the Thread it does not kill the process it started. How do I go about that?
There is no reliable way to do that.
Firstly, there is no reliable way to terminate the thread. The preferred way to try is to call Thread.interrupt() on the thread, but this may be ignored. If you call the deprecated method Thread.stop(), you are liable to destabilize your JVM.
Second, even assuming you kill the JAR thread, you cannot reliably kill any child threads that it created. You cannot reliably distinguish the child threads from other threads created by other parts of your application. And if you could identify them, you cannot reliably kill them.
The best you can do is launch a new JVM as an external process to run the JAR. Under normal circumstances a JVM can reliably kill an external process that it has created. (There are exceptions, e.g. setuid commands, but they shouldn't be an issue here.)

You cannot terminate a thread without terminating the process.
You can signal it to stop e.g. interrupt() or throw an exception, but the only way to get it to stop is for it to return or throw a Throwable from the run() method.

Related

Kill or stop a endless/not-returning-value thread in Java

I have a function in Java. It normally returns a value after it completes its task. However, in some conditions it returns nothing. I create a runnable and run this function as a thread. However, because of its not returning a value, it does not finish although it does its task. The process stays alive because it waits a returning value. Is there a way to kill this thread after it is triggered or after a timeout? Stop() or Destroy() did not work. During debug, the thread is seen as alive and I want it to bi deleted/removed
Runnable runnable = new Runnable() {
#Override
public void run() {
int stat = RunMyFunction();
}
};
Thread thread = new Thread(runnable);
thread.start();
Java does not support killing a thread via any method on java.lang.Thread.
stop() and destroy() do look promising at first glance, but they have both been deprecated.
The documentation for destroy states:
This method was originally designed to destroy this thread without any cleanup. However, the method was never implemented. If if were to be implemented, it would be deadlock-prone
and stop:
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
Thus when the documentation says 'deprecated', what it really means is that they are broken and must never be used!?! The Java API designers put a lot of work into backwards compatibility of their APIs, where other languages would have removed these methods Sun decided to keep them as their internal guides (rightly or wrongly) do not permit the removal of a public api method.
So, the question remains. How is one to get a thread to exit from another thread? Sadly one must go out of ones way to poll an exit variable. This can be a custom variable, or it can be a standard flag within java.lang.Thread that is accessible via 'interrupted()'. The advantage of using interrupted() is that other Java APIs such as IO support this flag during otherwise blocking API calls and will exit throwing an InterruptedException. The detection of calling interrupt() is not immediate, as it sets a flag and relies on the Thread to poll the variable at some point in the future.
Oracle offers a tutorial on how to code using interrupt here.
The real problem you have is that RunMyFunction sometimes never terminates. As others have already stated, killing a thread is not intended in Java, so there is no good way to do it. Instead, you should reason about why you call a possibly non-terminating method. This looks like a code smell. Do the following:
If you are the author of RunMyFunction, make sure that it always terminates or it can be interrupted. You can do this by checking Thread.currentThread().isInterrupted() and throwing an InterruptedException when it is. E.g:
void run(){
while(...){ // this loop sometimes runs forever
if(Thread.currentThread().isInterrupted())
throw new InterruptedException(); // Now, we can "kill" this thread here
}
}
Using ExecuterService you can specify a timeout.
ExecutorService executor = Executors.newFixedThreadPool(1);
List<Callable<String>> tasks = new ArrayList<Callable<String>>();
tasks.add(new Callable<String>() {
#Override
public String call() throws Exception {
int stat = RunMyFunction();
return "Execution Finished";
}
});
new Thread(new Runnable() {
#Override
public void run() {
try {
executor.invokeAll(tasks, 10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
invokeAll(...) is a blocking call so i've added inside a new thread.
Solution 1: Timed run: If you want a method to return or throw an exception after a specified amount of time, use the following method to execute the method on a background thread while waiting for it to complete:
public static void timedRun(Runnable r, long timeout, TimeUnit unit)
throws InterruptedException, TimeoutException {
Future<?> task = executor.submit(r);
try {
task.get(timeout, unit);
} catch (ExecutionException e) {
throw launderThrowable(e.getCause());
} finally {
task.cancel(true);
}
}
private static RuntimeException launderThrowable(Throwable t) {
if (t instanceof RuntimeException) return (RuntimeException)t;
else if (t instanceof Error) throw (Error)t;
else throw new IllegalStateException("Not unchecked", t);
}
(Source: Goetz, Brian, Bloch, Joshua, Bowbeer, Joseph, Lea, Doug, Holmes, David and Peierls, Tim. Java Concurrency in Practice. : Addison-Wesley Longman, Amsterdam, 2006. Listing 5.13 and 7.10)
For executor, you can either create a new one using Executor.newSingleThreadExecutor(), or reuse an existing one.
But be warned: Although this method is guaranteed to return or throw an exception after the specified timeout, it cannot guarantee that the runnable will really stop! It interrupts the executing thread, but if the runnable does not react to thread interruption (e.g. by internally checking Thread.interrupted()), it may continue to run in the background - possibly forever - occupying a thread! But at least it does not block.
Solution 2: Timed run with custom threads: If there is any possibility beside thread interruption to cancel your method call, you can still use the approach above, but then you have to use an Executor with custom ThreadFactory that creates a special Thread instance with overridden interrupt method:
Executor executor = Executor.newSingleThreadExecutor(r -> new WsdlThread(r));
public class WsdlThread extends Thread {
public WsdlThread(Runnable r) { super(r); }
public void interrupt() {
try {
// TODO: do something that will interrupt the wsdl call
// e.g. close connection to server, etc.
// example: ((WsdlRunnable)r).getWsdlConnection().close();
} finally {
super.interrupt();
}
}
}
If this isn't possible too, and Thread.stop() doesn't work either, this last solution might work:
Solution 3: Start non-cancellable call in another JVM:
Use Runtime.exec to start another JVM and execute the method call there (See Executing a Java application in a separate process for more info on how to do this). Runtime.exec will return a Process object, which represents the running process.
You can kill it by calling destroy() or destroyForcibly().

How can I "capture" System.exit(-1) from different thread?

I have the following
System.setSecurityManager(new SecurityManager() {
#Override
public void checkExit(int status) {
super.checkExit(status);
//custom exception extends SecurityException
throw new SystemExitCalledException();
}
});
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
//never reaches here somehow...
//maybe some3rdPartyStaticMethod sets this, too?
}
});
try {
//this method spawns threads and some call System.exit().
some3rdPartyStaticMethod.invoke(null, new Object[]{args});
} catch (SystemExitCalledException e) {
//it never reaches here because
//SystemExitCalledException is thrown on different thread??
//
}
Is there a way to prevent some3rdPartyStaticMethod's spawned thread's System.exit() call from halting jvm?
You can start the code in a separate process and communicate with it using RMI. If the third party code calls System.exit and kills its process, your process can continue to run and recreate the child process if necessary.
Note that there are some caveats with this approach:
The two processes don't share the same heap space.
You will need to marshal all data that is passed between the two processes. This means that the data must be serializable.
There will be a considerable overhead for every method call. This may give performance problems if you need to make many calls per second.
Writing a custom SecurityManager policy should help -- I've never done this myself :)
According to this post (scroll down to the bottom):
However, when anything in the VM tries to call System.exit(), the VM exits. Since this includes a brutal shotdown of mvn, the normal mvn process is interrupted. A SecurityManager can be used to prevent code from calling System.exit(), but nobody mentions the side-effects.
A colleague of mine mentioned that you can setup your policies system-wide, per-user and as a system-property when starting the VM and after a quick test this has proven to solve my problem. I've since managed to figure out how to set my own policy from my code (before setting up the SecurityManager) and this solves my problems.
I used the following code:
//Setup security to prevent System.exit()
SecurityManager sm = System.getSecurityManager();
URL policy = getClass().getClassLoader().getResource("jsdoc.policy");
System.setProperty("java.security.policy", policy.toString());
System.setSecurityManager(new JSDocSecurityManager(getLog()));
With a simple, wide-open, policy file reading this:
grant {
permission java.security.AllPermission;
};
If it works it supposed to capture the System.exit() request and throw a SecurityException instead

How to gracefully handle the SIGKILL signal in Java

How do you handle clean up when the program receives a kill signal?
For instance, there is an application I connect to that wants any third party app (my app) to send a finish command when logging out. What is the best say to send that finish command when my app has been destroyed with a kill -9?
edit 1: kill -9 cannot be captured. Thank you guys for correcting me.
edit 2: I guess this case would be when the one calls just kill which is the same as ctrl-c
It is impossible for any program, in any language, to handle a SIGKILL. This is so it is always possible to terminate a program, even if the program is buggy or malicious. But SIGKILL is not the only means for terminating a program. The other is to use a SIGTERM. Programs can handle that signal. The program should handle the signal by doing a controlled, but rapid, shutdown. When a computer shuts down, the final stage of the shutdown process sends every remaining process a SIGTERM, gives those processes a few seconds grace, then sends them a SIGKILL.
The way to handle this for anything other than kill -9 would be to register a shutdown hook. If you can use (SIGTERM) kill -15 the shutdown hook will work. (SIGINT) kill -2 DOES cause the program to gracefully exit and run the shutdown hooks.
Registers a new virtual-machine shutdown hook.
The Java virtual machine shuts down in response to two kinds of events:
The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
I tried the following test program on OSX 10.6.3 and on kill -9 it did NOT run the shutdown hook, as expected. On a kill -15 it DOES run the shutdown hook every time.
public class TestShutdownHook
{
public static void main(String[] args) throws InterruptedException
{
Runtime.getRuntime().addShutdownHook(new Thread()
{
#Override
public void run()
{
System.out.println("Shutdown hook ran!");
}
});
while (true)
{
Thread.sleep(1000);
}
}
}
There isn't any way to really gracefully handle a kill -9 in any program.
In rare circumstances the virtual
machine may abort, that is, stop
running without shutting down cleanly.
This occurs when the virtual machine
is terminated externally, for example
with the SIGKILL signal on Unix or the
TerminateProcess call on Microsoft
Windows.
The only real option to handle a kill -9 is to have another watcher program watch for your main program to go away or use a wrapper script. You could do with this with a shell script that polled the ps command looking for your program in the list and act accordingly when it disappeared.
#!/usr/bin/env bash
java TestShutdownHook
wait
# notify your other app that you quit
echo "TestShutdownHook quit"
I would expect that the JVM gracefully interrupts (thread.interrupt()) all the running threads created by the application, at least for signals SIGINT (kill -2) and SIGTERM (kill -15).
This way, the signal will be forwarded to them, allowing a gracefully thread cancellation and resource finalization in the standard ways.
But this is not the case (at least in my JVM implementation: Java(TM) SE Runtime Environment (build 1.8.0_25-b17), Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode).
As other users commented, the usage of shutdown hooks seems mandatory.
So, how do I would handle it?
Well first, I do not care about it in all programs, only in those where I want to keep track of user cancellations and unexpected ends. For example, imagine that your java program is a process managed by other. You may want to differentiate whether it has been terminated gracefully (SIGTERM from the manager process) or a shutdown has occurred (in order to relaunch automatically the job on startup).
As a basis, I always make my long-running threads periodically aware of interrupted status and throw an InterruptedException if they interrupted. This enables execution finalization in way controlled by the developer (also producing the same outcome as standard blocking operations). Then, at the top level of the thread stack, InterruptedException is captured and appropriate clean-up performed. These threads are coded to known how to respond to an interruption request. High cohesion design.
So, in these cases, I add a shutdown hook, that does what I think the JVM should do by default: interrupt all the non-daemon threads created by my application that are still running:
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
System.out.println("Interrupting threads");
Set<Thread> runningThreads = Thread.getAllStackTraces().keySet();
for (Thread th : runningThreads) {
if (th != Thread.currentThread()
&& !th.isDaemon()
&& th.getClass().getName().startsWith("org.brutusin")) {
System.out.println("Interrupting '" + th.getClass() + "' termination");
th.interrupt();
}
}
for (Thread th : runningThreads) {
try {
if (th != Thread.currentThread()
&& !th.isDaemon()
&& th.isInterrupted()) {
System.out.println("Waiting '" + th.getName() + "' termination");
th.join();
}
} catch (InterruptedException ex) {
System.out.println("Shutdown interrupted");
}
}
System.out.println("Shutdown finished");
}
});
Complete test application at github: https://github.com/idelvall/kill-test
There are ways to handle your own signals in certain JVMs -- see this article about the HotSpot JVM for example.
By using the Sun internal sun.misc.Signal.handle(Signal, SignalHandler) method call you are also able to register a signal handler, but probably not for signals like INT or TERM as they are used by the JVM.
To be able to handle any signal you would have to jump out of the JVM and into Operating System territory.
What I generally do to (for instance) detect abnormal termination is to launch my JVM inside a Perl script, but have the script wait for the JVM using the waitpid system call.
I am then informed whenever the JVM exits, and why it exited, and can take the necessary action.
You can use Runtime.getRuntime().addShutdownHook(...), but you cannot be guaranteed that it will be called in any case.
Reference https://aws.amazon.com/blogs/containers/graceful-shutdowns-with-ecs/
import sun.misc.Signal;
import sun.misc.SignalHandler;
public class ExampleSignalHandler {
public static void main(String... args) throws InterruptedException {
final long start = System.nanoTime();
Signal.handle(new Signal("TERM"), new SignalHandler() {
public void handle(Signal sig) {
System.out.format("\nProgram execution took %f seconds\n", (System.nanoTime() - start) / 1e9f);
System.exit(0);
}
});
int counter = 0;
while(true) {
System.out.println(counter++);
Thread.sleep(500);
}
}
}
There is one way to react to a kill -9: that is to have a separate process that monitors the process being killed and cleans up after it if necessary. This would probably involve IPC and would be quite a bit of work, and you can still override it by killing both processes at the same time. I assume it will not be worth the trouble in most cases.
Whoever kills a process with -9 should theoretically know what he/she is doing and that it may leave things in an inconsistent state.

About multi threading

How to kill the thread?
.....
How to restart them again in multi threading?
Since your post is tagged "Java," I have a good idea of what you are saying. Let's say you start a thread by doing:
Thread foo = new Thread(someRunnable);
foo.start();
Now that destroy and friends are deprecated, you need a way to kill the thread. Luckily for you, there has always been the concept of "interrupts." Simply change your runnable so that, on interrupt, it exits. Then call the thread's interrupt method.
foo.interrupt();
If you wrote your Runnable to handle this correctly, it will stop whatever it is doing and terminate.
Thread.stop() kills a thread, but you definitely don't want to do this (see the API documentation for an explanation why). Thread.interrupt() sends an asynchronous notification to a thread, so that it can shut itself gracefully.
For a comprehensive text on Java multithreading, I recommend B. Goetz, Java Concurrency in Practice, Addison-Wesley Professional.
The preferred way for a Thread to die is for the execution of the run method to go to completion:
Thread t = new Thread(new Runnable() {
public void run() {
// Do something...
// Thread will end gracefully here.
}
}
Once a thread gracefully dies in the example above, the Thread cannot be restarted. (Trying to call Thread.start on a thread that has already been started will cause an IllegalThreadStateException.)
In that case, one can make another instance of the thread and call start on that.
Probably a good place to get more information on threading would be Lesson: Concurrency from The Java Tutorials.
i wrap my worker threads up in their own class and use a terminated property to kill the thread proc loop.
sorry i dont have a java version to hand right now but you should get the idea from this
http://pastie.org/880516
using System.Threading;
namespace LoaderDemo
{
class ParserThread
{
private bool m_Terminated;
private AutoResetEvent m_Signal;
private string m_FilePath;
...
public ParserThread(AutoResetEvent signal, string filePath)
{
m_Signal = signal;
m_FilePath = filePath;
Thread thrd = new Thread(this.ThreadProc);
thrd.Start();
}
public bool Terminated {
set { m_Terminated = value; }
}
private Guid Parse(ref string s)
{
//parse the string s and return a populated Guid object
Guid g = new Guid();
// do stuff...
return g;
}
private void ThreadProc()
{
TextReader tr = null;
string line = null;
int lines = 0;
try
{
tr = new StreamReader(m_FilePath);
while ((line = tr.ReadLine()) != null)
{
if (m_Terminated) break;
Guid g = Parse(ref line);
m_GuidList.Add(g);
lines++;
}
m_Signal.Set(); //signal done
}
finally
{
tr.Close();
}
}
}
}
The best way to kill a thread is to set up a flag for the thread to watch. Program the thread to exit when it sees the flag is set to true. There's no way to restart a killed thread.
If you want to start, stop, restart threads at will, maybe using the Java 5 concurrency package would be a good idea. You can have an Executor that will do a bit of work, and when you need that bit of work to be done again, you can just re-schedule it to be done in the executor.
Regarding your first query on killing thread:
You can find more details about topic in below SE questions:
How to properly stop the Thread in Java?
How can I kill a thread? without using stop();
How to start/stop/restart a thread in Java?
Regarding your second query of re-starting thread, it's not possible in java.
You can find below details in documentation page
public void start()
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
Instead of plain Threads, you can use advanced concurrent API for thread life cycle management. Have a look at this post for ExecutorService details :
How to properly use Java Executor?

Why does JVM does not terminate when using RMI

I just read the Trail on RMI from sun at http://java.sun.com/docs/books/tutorial/rmi/implementing.html
When I run the example, the JVM does not terminate although main has finished. Is RMI spawning a Thread somewhere internally?
What is the behaviour of multiple Threads spawned in main, after main exits?
Is it a clean way to let the Threads exit whenever they want or should you do a join on each Thread you spawn? I did not find any documentation on this question.
Thank you very much for your help!!
public class ComputeEngine implements Compute {
public ComputeEngine() {
super();
}
public <T> T executeTask(Task<T> t) {
return t.execute();
}
public static void main(String[] args) {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Compute";
Compute engine = new ComputeEngine();
Compute stub = (Compute) UnicastRemoteObject.exportObject(engine, 0);
Registry registry = LocateRegistry.getRegistry();
registry.rebind(name, stub);
System.out.println("ComputeEngine bound");
} catch (Exception e) {
System.err.println("ComputeEngine exception:");
e.printStackTrace();
}
}
}
A thread is created for listening the socket and reply to requests to your object. One way to stop the JVM is to unbind the server:
Registry.unbind()
and unexport the objects:
UnicastRemoteObject.unexportObject()).
You can use the jstack utility program, included in the JDK to see which threads are running in a java program, and even what line those threads are on.
So if you're program is still running you just run jstack on the pid and it will tell you which threads are still running and what they're doing.
Concerning the "behaviour of multiple threads" part of your question: yes, the JVM will keep on running until all threads finished. The only exception are threads marked as daemon (see Thread.setDaemon()), the JVM will not wait for them.
Yes, when you are exposing objects through RMI it needs a thread to accept incoming requests for these objects. This thread could be a daemon thread which wouldn't stop the JVM from exiting but it isn't for several reasons and as long as there are still active exported objects it hinders the JVM from exiting normally. So you can use unexportObject for all objects or just use System.exit() to end the JVM although this would leave the clients uninformed about the shutdown.

Categories

Resources