What happens if one throws a Java exception using ThrowNew from a natively-created thread?
If the native code that throws a Java exception is called from Java, then the exception goes back to the Java side as expected, but what if someone calls this native code without directly or indirectly coming from the Java? It's not going to go back to the Java obviously, since we're not coming from there.
Note: This answer is outdated as of Java 9 (which was not available when the answer was written).
If native code is making Java calls, it must have called AttachCurrentThread() to obtain a JNI env value if the native code is called in a manner that it did not have a JNI env passed to it.
So, before the native thread or call ends, it must call DetachCurrentThread(). But if there are any pending Java exceptions, DetachCurrentThread() will invoke the Thread.UncaughtExceptionHandler, as posted by #EJP.
Per the JNI specification regarding exceptions:
Exception Handling
There are two ways to handle an exception in native code:
The native method can choose to return immediately, causing the exception to be thrown in the Java code that initiated the native
method call.
The native code can clear the exception by calling ExceptionClear(), and then execute its own exception-handling code.
After an exception has been raised, the native code must first clear
the exception before making other JNI calls. When there is a pending
exception, the JNI functions that are safe to call are:
ExceptionOccurred()
ExceptionDescribe()
ExceptionClear()
ExceptionCheck()
ReleaseStringChars()
ReleaseStringUTFChars()
ReleaseStringCritical()
Release<Type>ArrayElements()
ReleasePrimitiveArrayCritical()
DeleteLocalRef()
DeleteGlobalRef()
DeleteWeakGlobalRef()
MonitorExit()
PushLocalFrame()
PopLocalFrame()
Note that DetachCurrentThread() is not safe to all with any pending Java exception.
Yet a native thread that has previously called AttachCurrentThread() must call DetachCurrentThread():
Attaching to the VM
The JNI interface pointer (JNIEnv) is valid only in the current
thread. Should another thread need to access the Java VM, it must
first call AttachCurrentThread() to attach itself to the VM and
obtain a JNI interface pointer. Once attached to the VM, a native
thread works just like an ordinary Java thread running inside a native
method. The native thread remains attached to the VM until it calls
DetachCurrentThread() to detach itself.
The attached thread should have enough stack space to perform a
reasonable amount of work. The allocation of stack space per thread is
operating system-specific. For example, using pthreads, the stack size
can be specified in the pthread_attr_t argument to pthread_create.
Detaching from the VM
A native thread attached to the VM must call DetachCurrentThread() to detach itself before exiting. A thread cannot detach itself if
there are Java methods on the call stack.
So native code must call DetachCurrentThread() before exiting, yet DetachCurrentThread() can not be safely called with Java exceptions pending.
In Java 8 and earlier, the only JNI functions that are safe to call with a pending exception are those which either release locks/references or themselves relate to exception handling. The idea is that when a JVM exception is passed to native code, it is supposed to either catch the exception itself or unwind the stack to a call frame that will. If a thread has no such call frame to unwind to, it follows that it should do the former. So the only specification-compliant way to handle an uncaught exception in a native thread was to clear it (i.e. call ExceptionClear) before calling DetachCurrentThread, perhaps after passing it to some custom handler.
In practice, if a pending exception made its way to the DetachCurrentThread call without being caught, the HotSpot VM has always handled them in the same manner as in JVM-managed threads, by passing it to the uncaught exception handler and terminating the thread. The problem is, the JNI specification did not offer a way for uncaught exceptions in native threads to defer to the JVM implementation’s uncaught exception handling in this manner.
This deficiency was noticed in two tickets: JDK-8155881 and JDK-8179050, but requiring HotSpot behaviour was deemed too burdensome for other implementations. As a compromise, in Java 9 the JNI specification was amended so that DetachCurrentThread is safe to call with a pending exception, but the effect of this is implementation-defined: ‘If an exception is pending when DetachCurrentThread is called, the VM may choose to report its existence.’. This wording remains there in JNI 15.
Long story short, if you just unwind the call stack while releasing all resources up to the point of DetachCurrentThread, you should probably be fine; with (a little) luck, the uncaught exception will be handled the same way as any other. But for extra safety, you should catch the exception yourself.
Related
I was reading article about Internal Java Memory Model.
There is one point I want to ask about :
Each thread running in the Java virtual machine has its own thread stack. The thread stack contains information about what methods the thread has called to reach the current point of execution.
Why each thread needs to save information about what methods has been executed(!) ? If it's related to context-switching then (if I'm not wrong) thread must save the information about method which is currently being executed.
What is actual need for save already executed method's information?
This is referring to the currently active methods. Note that there can be several methods in a thread active at the same time (A calls B calls C, ...). The stack does not contain information about methods that have already completed.
I think rephrasing this paragraph makes it clearer and easier to understand:
Each thread running in the Java virtual machine allocates some memory for its call stack. The call stack contains information about what methods the thread has called to reach the current point of execution.
I am writing a fairly large, multithreaded application, with many differing roles for threads (e.g. event processing, metrics, networking). Currently, if there is any inconsistency that cannot be handled, it will manifest itself as an exception. Since there's really no way to recover from some of them, I've been rethrowing it as a runtime exception of type ApplicationDeathException.
Any classes that need to handle shutdown would call it from a catch block for this exception, and then rethrow it in order for it to propagate up the stack).
I am considering killing off all other threads in this same manner by calling Thread#stop(Throwable) upon them. Most are fine with sudden termination, and can catch this exception should there be a need for shutdown logic. They will simply have the exception propagate up the stack, performing shutdown logic whereever needed, and eventually just killing the thread in the end. Are there any hidden dangers that I'm missing with this approach?
Thread.stop has been deprecated since it is unsafe (see the Javadoc). Instead have each thread monitor a boolean flag of some sort (see Java: How to stop thread? and likely countless other threads on SO).
In situations like this I typically implement some sort of thread pool manager that is responsible for cleanly shutting down running threads. Then when something really bad happens you only need to notify the manager to shut things down.
I am writing a game program, and rarely i will get an exception. I want to be able to record all the exceptions i get on a separate thread. My program is already multi-threaded. In some cases i use try catch, and for those i could just set an exception variable to the caught exception. However i want to be able to find out all exceptions that have been thrown on all threads without putting every statement in a try catch. For clarification i want the exception object not just the name of the exception.
You want the Thread.UncaughtExceptionHandler:
Interface for handlers invoked when a Thread abruptly terminates due to an uncaught exception.
When a thread is about to terminate due to an uncaught exception the Java Virtual Machine will query the thread for its UncaughtExceptionHandler using Thread.getUncaughtExceptionHandler() and will invoke the handler's uncaughtException method, passing the thread and the exception as arguments. If a thread has not had its UncaughtExceptionHandler explicitly set, then its ThreadGroup object acts as its UncaughtExceptionHandler. If the ThreadGroup object has no special requirements for dealing with the exception, it can forward the invocation to the default uncaught exception handler.
See here for details.
This can be done using Spring AOP which is useful in these cases.
#AfterThrowing aspect
You will require Spring AOP libraries for that.
A similar question was answered previously.
This can be done through Java Debug Interface (JDI) that is part of Java Platform Debugger Architecture (JPDA).
In particular, see ExceptionRequest and ExceptionEvent.
I have a class for threads (implements runnable). I want to be able to print text to a file inside the method "run", but I can't add "throws IOException" because run() is an implementation of a method in runnable.
Of course there's no way I'll use a gazillion "Try-Catch" in run()...
Thanks
Dealing with checked exceptions in your run() method is tricky for the following reasons:
As #kenson john says (and you observed) you can't simply let them propagate, because run() is not declared as throwing checked exceptions.
If you catch them and rethrow them wrapped in unchecked exceptions, they are likely to go unnoticed by the main thread. Why? Because the exceptions are thrown on the stack of the child thread. Unless they are caught in the run() method, they will be dealt with by the thread's UncaughtExceptionHandler object ... which is likely to be the default handler ... which writes a stacktrace to System.err and then discards the exception.
Now you can set another UncaughtExceptionHandler object for the child thread, or even set a default UncaughtExceptionHandler for the JVM. But what should the handler do? Ideally, the exception needs to be reported back to the main thread (or whatever) to take executive action. But there's no way that the child thread, or a handler for that thread can throw an exception on the main thread's stack. (The best you could do to get the main thread's attention would be to set a flag or call Thread.interrupt() on the main thread ... and hope that it checks the flag / interrupt status periodically.)
Any IOException that is thrown while writing to an output file indicates that something serious has gone wrong; e.g. the file system is full, or the socket or pipe you were writing to is broken / closed. So simply ignoring it could be a big mistake. (For instance, suppose that the file is precious, and that the last thing that the application does is to delete the old version of the file and replace it with the new version we just created. Ooops! We didn't notice that the FS filled up, the new version of the file is corrupt and we just deleted the old version.)
In the light of this, the PrintStream approach is simplest. A PrintStream will quietly catch any IOException that occurs while writing, but record the fact that an exception has occurred. So when the main thread decides that everything should have finished writing, it needs to call PrintStream.checkError() to test if any errors have occurred. (Unfortunately, the API does not allow you to find out what the actual exception was.)
You could wrap the output with a PrintStream, it never throws exceptions.
If you want to do a particular I/O operation in many places without putting each one in an exception handler, just create a function with an exception handler (i.e. it doesn't throw). Then call the non-throwing function to do all your I/O.
I understand why you want to do this, but I think it is a bad practice to throw and catch an exception from run() (which is impossible for the reason mentioned below).
An exception generated from run() would be considered as an "Unchecked" exception in Java. This kind of exception should not be caught by the programmer, and should be taken care of by the VM.
Unchecked exception generally happen at runtime, example: NullPointerException, IllegalStateException.
IOException being a subclass of java.lang.Exception is considered a Checked Exception, therefore should be handled using a try catch within run() or in a method invoked by run().
I am writing a java program which tracks as threads are created in a program and is then supposed to perform some work as each Thread terminates.
I dont see any 'thread termination hooks' out there in the javadoc.
Currently the only way I can think of to achieve my requirement is to hold on to the thread objects and query its 'state' at repeated intervals.
Is there any better way to do this?
Edit:
I cannot wrap the runnable or modify the runnable in any way.
My code uses runtime instrumentation and just detects that a thread is created and gets a reference to the Thread object.
The runnable is already running at this point.
You can use the join() method.
EDIT
If your main thread must not be blocked until threads are not terminated, you can create a sub main thread which will call the threads, then wait for them with join() method.
I see four possible methods.
Use your own Thread subclass with an
overridden run() method. Add a
finally block for thread
termination.
Use a Runnable with
similar decoration, perhaps as a
wrapper around the supplied
Runnable. A variant of this is to
subclass Thread in order to apply
this wrapper at construction time.
Create a 2nd thread to join() on the
real thread and thus detect its
termination.
Use instrumentation to rewrite the Thread.run() method as above.
Just poking around in the (sun 1.5) source code for java.lang.Thread and sun.misc.VM, there is a field in thread called threadStatus. It is a private int and its values map to the enum java.lang.Thread.State. I have not verified this, nor determined how quickly it occurs if it does, but when a thread eventually terminates, this value will be set to java.lang.Thread.State.TERMINATED.
With this relatively simple condition to detect, I think it would be fairly straightforward to inject a field interceptor on threadStatus to fire an event when the field is set to a specific target value.
You could write a decorator for Runnable which calls a termination hook and wrap your thread code in it when you create the threads.
If you added a try/finally block to each run method, the code inside would be executed when each thread completed. Let the thread be responsible for its own clean-up.
AspectJ could help you do this if you needed to inject code into third-party compiled code, but apparently it doesn't work on standard Java class libraries.
Looks like there's a whitepaper on doing this here, but there's no telling if it's practical. I think you have to pay for it.
http://portal.acm.org/citation.cfm?doid=1411732.1411754
You could download OpenJDK, put the hook in yourself, compile a custom JRE and ship that with your application :)
As you say, there are no thread termination hooks. You have to code them yourself; call some method on a controller at the end of the run() method of your Runnables (AFAIK subclassing Thread is considered bad practice, you should implement Runnable and create a Thread with that Runnable as its target).
You can also implement an UncaughtExceptionHandler to know if a thread terminated abnormally due to an exception, in which case your controller's method won't be called.
If you run on java 1.5 you can probably do it using java.lang.instrument and the -javaagent option to the jvm.
Redefine the run method on the thread object which should call your code. You already seem to use instrumentation so it should be available. as it modifies runtime bytecode you should be fine
That said, it is hard to provide a more specific and detailed answer your question lacks at least the jvm version and the main frameworks in use (think spring-aop, jboss-aop, jvm version etc)