JVM won't terminate - java

I have a simple test run of some medium-complexity code that won't terminate, i.e. the main method finishes but the process does not die.
Here is a rundown of the code (which is too long to be pasted here):
ProcessBuilder is used to create a bunch of subprocesses. They all die properly (if you can believe VisualVM).
We use log4j.
The main algorithm runs inside a FutureTask on which run and later get are called.
We don't explicitly use RMI, even though the list of threads seems to suggest so.
Obviously, I can call System.exit(0), but I'd like to know what is amiss here. I have not been able to produce a minimum failing example. Also, I can not identify an obvious culprit from the thread list; maybe you can?
Edit: See here for a thread dump.

Scorpion lead me to the right answer:
RMI Reaper is something like a garbage collector for remote objects, e.g. instances of (subclasses of) UnicastRemoteObject. It is a non-daemon thread and therefore blocks JVM termination if there are still exported objects which can not be cleaned up.
You can explicity force remote objects to be cleaned up in this sense by passing them to UnicastRemoteObject.unexportObject(., true). If you do this on all previously exported objects, RMI Reaper terminates and JVM is free to shut down.

You mention FutureTask. The first thing that comes to my mind is: are you using ExecutorService and forgetting to shut it down?
The second thing that comes to my mind is: are you reading to the end all the streams from the process? I worked with subprocesses long ago, and I don't remember exactly, but. I had problems similar to what you described, and by reading the streams to the end the problem would misteriously disappear!

Related

What are the possible reasons that even after successfull execution control doesnt come back to prompt?

I am running a Java Program in command prompt
The normal course is after successfully executing the program it comes back to prompt .. what are the possible reasons it will not come back to prompt after successfully executing the program
why is it not coming back to prompt after execution
usually it comes back but sometimes it doesn't...
This sounds like a race condition. Something in your application's shutdown sequence is non-deterministic, and it works or does not work depending on various platform specific (and possibly external) factors. There is probably no point figuring out what those factors are (or might be), since it won't help you fix the problem.
Only difference is in RAM hard disk capacity mine is slower.. Can it be possible reason?
These could be factors, but they are not the cause of the problem. So focus on figuring out what makes your application non-deterministic.
As others have said, without more information (and relevant code) we can only guess.
When the application has failed to shut down, get it to give you a thread dump. Or try shutting it down while it is attached to a debugger. These may allow you to get some clues as to what is going wrong.
Finally, the brute force solution is simply to have the main method (or whatever) call System.exit(0) on its way out. But beware of the possibility of files not being flushed, etc if you do that.
Because it's not finishing. If it's sometimes happening and sometimes not, my instinct is that you have some sort of race condition. Probably one of your cleanup steps is hanging if another action has or hasn't been taken.
Without source code this will be hard to debug.
There could be an active thread still running which is not in "daemon" mode. For example, if you have a Swing GUI and all of the frames are closed the Event Dispatch thread is still active so the JVM will not exit.

Repast restart issue

I'm developing an artificial intelligent program to explore a given space for resources.
I'd like to run multiple scenarios in order to collect data and output to a file.
I used the "multiple runs" option in the gui and i do stop() when one module run is finished (all the resources have been explored). The problem is when It runs the model a second turn, it doesn't work properly.
What I mean is that after running once I always need to kill the application by exiting because the restart option doesn't work properly.
Is there anything that "restart" forgets to do? Because if I exit the application and run it again it works perfectly
Edited so it's more clear:
I use the Repast platform in order to simulate an exploration to Mars. I have 3 kinds of agents, scouting, digging and transporting. They communicate among them to schedule tasks and other things.
The first time I run the simulation everything runs smoothly. And when all the mineral resources of the planet have been explored I restart the model and try again so I can collect data.
The problem is, when I use the "restart" option the Simulation doesn't run well. But if I exit (not restart) and run it again it works fine.
What I'd like to know is if the restart option of Repast GUI misses any steps..
Thanks in advance
PS: If you guys think that it's absolutely necessary I can post some code...but the project is quite big
Don't use Thread.stop() method. It is deprecated. Thread.stop is being deprecated because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors was in an inconsistent state, other threads might view these objects in an inconsistent state. Such objects are said to be damaged. Threads operating on damaged objects can behave arbitrarily, either obviously or not. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that the program may be corrupted. The corruption can manifest itself at an unpredictable time after the damage occurs. Substitute any use of Thread.stop with code that provides for a gentler termination.
http://docs.sun.com/app/docs/doc/805-4031/6j3qv1of1?a=view
Consider thread stopping either via Thread.interrupt() or via setting cancel flag. Look at Java Concurrency in Practice, Section 7.1. Task Cancellation.

Can I use thread.stop () in Java if I really need it?

I need to use deprecated stop () because I need to run Runnable classes which were developed by other programmers and I can't use while (isRunning == true) inside method run.
The question is: Is it safety enough to use method stop ()? Theads don't work with any resources (like files, DB, or Internet connections). But I want to be sure that JVM wouln't be corrupted after I stop a dozen of threads with stop () method.
P.S.: yes, I can write some code to test it, but I hope somebody knows the answer)
Sort of. There's nothing inherently "corrupting" about Thread.stop(). The problem is that it can leave objects in a damaged state, when the thread executing them suddenly stops. If the rest of your program has no visibility to those objects, then it's alright. On the other hand, if some of those objects are visible to the rest of the program, you might run into problems that are hard to diagnose.
If you use Thread.stop you'll probably get away with, assuming you have few users. It is exceptionally hard to test for. It can cause an exception anywhere in executing code. You can't test all possible situations. On your machine in your set up you might never find a problem; come the next JRE update your program might start failing with a highly obscure intermittent bug.
An example problem case is if the thread is loading a class at the time. The class fails to load and will not be retried again. You program is broken.
The JVM won't be corrupt, but read the javadocs closely to make sure that you don't meet their conditions for "disaster."
You'll need to take a close look at any synchronization monitors that the thread is holding onto. You mentioned files and sockets as resources being hung onto, but you'll also need to consider any shared data structures. Also make sure your exception handling doesn't catch RuntimeExceptions (see stop()).

Killing thread instantly in Java

Is it possible to kill a Java thread without raising an exception in it?
This is just for testing purposes - I want to simulate a case when the entire computer dies mid-thread.
Note - I saw a deprecated Thread.destroy() method, but the documentation says it never got implemented in the first place.
No. There is the deprecated, 'inherently unsafe' Thread.stop() method, but as its comment emphasizes, things could be left in an deeply corrupted state, and the ThreadDeath Error is still thrown inside the thread.
Sun's explanation of the problems with stop(), which can manifest long after it appears to work, is at:
http://java.sun.com/j2se/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
Wouldn't killing the JVM process (or yanking the plug) be a better simulation of computer death?
There is no portable method. You might try to call "kill -9" (or your local equivalent) on the whole java process, if you want to suppress the running of finalizers and shutdown hooks.
You won't get any kind of repeatable results out of such a test, but it might be interesting to perform such tests a few thousand times if your program is writing to the file system or a database and might leave inconsistent data structures when being killed.
Or you could... kill the process. (ie, if this is Linux, send a kill -9 signal to the process).
Beware the race issues if you're trying to test something - if you hoping to crash badly - it might only do it once a month if you're particularly unlucky.
What is the point of your test? Java offers no guarantees about what happens on an exit, apart from attempting to run shutdown hooks if the exit is a "clean" one
It sounds akin to trying to test your program's behaviour in the case it goes OutOfMemory; there's nothing you can do about it and no way of telling deterministically what will happen
Is there any reason you can't use Thread.suspend()? It will stop the thread so you can examine the state when the thread is interrupted.
You could also use Thread.stop() although that risks throwing multiple ThreadDeathExceptions. You can wrap it int try/catch/finally blocks, but there are no guarantees.
Thread stop() throws an error in the thread. ThreadDeath
The only way to simulate an application dying mid thread is to call System.exit().
However, this is pretty random so you have to perform the test many times to have any confidence you application behaves correctly no matter where it dies.

How to pass sockets created to another Java Process

We have an application which creates many sockets which belongs to its thread, By design if this application somehow fails, all threads stop which is not wanted. So to overcome this issue, each thread must be separated from the main application, if one of the threads fails, the other ones should be running. One thing in our mind is to pass created socket to another java process, so what is the correct way?
An other approach also is welcome?
Waiting for your suggestions...
Forking:
You can't pass a socket handle between Java processes using the normal API as far as I can tell. However, it does seem to be possible on windows using the Winsock 2 API. On Posix you should be able to fork a child process with access to the parent socket, since forked processes inherit the parent's sockets.
You could, I think, implement a new SocketImpl class which supports moving a socket handle to another process, but you'd need to write some JNI code to do it.
Sounds pretty hairy to me, I doubt forking a new process from within Java is a good idea!
Listeners:
Another approach might be to spawn a new 'listener' process which is essentially a new pre-forked worker. Each worker could then take turns to listen to the socket for connections.
The workers would then need to coordinate with a control process which manages spawning new processes as needed.
I agree with #Bozho, if an error in one thread can take them all down (I guess it would have to be a JVM exception killing the whole app) you have a bigger problem. You should look at isolating the threads if possible.
It isn't. (Sockets can't be serialized.)
When one thread fails, its exception should be caught, logged, and this should not interfere with other threads.
So either design it to stop completely, or design it to not stop completely.
Or pass all the information about the socket (address/port) to another application, which itself could open a similar socket.
see this similar question socket passing between processes.
Unfortunately the barrier of the address space can not be exceeded.
I rather agree with Bozho you need to redesign your applications / critic threads so that an Exception or an Error does kill your whole VM.
To help you with that I suggest you to have a look to :
Thread.setDefaultUncaughtExceptionHandler(...) and Thread.setUncaughtExceptionHandler(...) (see hyperlink below) which helps to fetch unforseen problems (such as runtimes)
Runtime.addShutdownHook(...) (see hyperlink below) which helps closing things nicely (for example when an OutOfMemoryError occurs)
Regards
Cerber
http: //java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html#setUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler)
http: //java.sun.com/j2se/1.5.0/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)
Use a class that is shared between threads to hold sockets. You can use a HashMap to label each socket so other threads can reference the one it needs.
I want to respond to those who say 'just catch the exceptions and exit the thread'.
You cannot catch all the exceptions. The following cause the java jvm to exit:
assertion the jvm due to bugs in the jvm implementation
some faillure in jni code (sigsegv, sigabrt)
OutOfMemory

Categories

Resources