Serious Design Limitation/Flaw in Reflection API

The default behaiviour of an uncaught Exception is that it trickles up to the ThreadGroup that owns it. The only time this should not be the case, is if you can do something intelligent with this exception.

My situation is this: I have a ThreadGroup that has some intelligent Exception Handleing and Logging. There are some cases when it decides it's OK for the thread to continue even though an exception occurred. For example, during debugging it can ask the developer if it's OK to proceed. The problem is when a method is invoked by the "invoke" method of the "Method" object. For some reason, it catches any exception thrown my the invoked method and re-throws it as an InvocationTargetException. This means there is no way (that I can see), to resume execution in the Thread where the Exception occured. What if I just want it to leave the exception alone?

Why did Sun assume that no one would want to do this? Or was it just not considered? Or have I made a mistake?

invoke is a native method so I think I'm pretty screwed here.

Thanks in advance for any tips.

[1116 byte] By [mgbolusm] at [2007-9-26 7:29:12]
# 1
I am not sure I do understand your problem, but did you notice you can get the original exception by getTargetException()?
ipreuss at 2007-7-1 17:25:30 > top of Java-index,Core,Core APIs...
# 2

> I am not sure I do understand your problem, but did

> you notice you can get the original exception by

> getTargetException()?

Yes. The problem is this:

in my ThreadGroup I can override the following method

uncaughtExteption(Thread td, Throwable t);

And I can continue the Thread if I decide the Exception isn't important.

With invoke, it catches the exception, and just rethrows it. How is this usefull? It TAKES AWAY value from Java, because the uncaught Exception never makes it to the ThreadGroup's uncaughtException method. A proper stacktrace would tell me that I had passed into the invoke method, so wrapping the Exception is utterly useless.

(Sorry about the rant. I'm a bit flustered.)

-mark

mgbolusm at 2007-7-1 17:25:30 > top of Java-index,Core,Core APIs...
# 3
Can't you manually call uncaughtExteption() with the "true" exception when you get the InvocationTargetException.
hlindqvi at 2007-7-1 17:25:30 > top of Java-index,Core,Core APIs...
# 4
Yes but the thread is in the wrong state. There's no way to call (thread.start()) and have it resume where the original Exception occured.
mgbolusm at 2007-7-1 17:25:30 > top of Java-index,Core,Core APIs...
# 5

I must be missing something. No matter what you cannot call thread.start() and have it resume where the original Exception occurred. This is because 1) you can't restart threads regardless of whether an Exception was thrown and 2) you can't resume where an Exception was thrown no matter what Exception was thrown.

Maybe you could give an example of resuming a thread with thread.start(), or resuming where an Exception occurred.

schapel at 2007-7-1 17:25:30 > top of Java-index,Core,Core APIs...
# 6

Your problem is that InvocationTargetException is a checked exception. I'm not sure where your calling invoke from, but from there, if you check to see if the target exception is a runtime or an error and rethrow it as such then I would think (never done this so done know) that it would make it to uncaughtException...

cheers

dim

dimc at 2007-7-1 17:25:30 > top of Java-index,Core,Core APIs...
# 7

> I must be missing something. No matter what you cannot

> call thread.start() and have it resume where the

> original Exception occurred. This is because 1) you

> can't restart threads regardless of whether an

> Exception was thrown and 2) you can't resume where an

> Exception was thrown no matter what Exception was

> thrown.

>

> Maybe you could give an example of resuming a thread

> with thread.start(), or resuming where an Exception

> occurred.

The point is not that you can restart a thread.

If invoke() didn't catch the exception, then the thread wouldn't be interrupted in the first place and would go on if you don't end it in uncaughtException().

chuanhaochiu at 2007-7-1 17:25:30 > top of Java-index,Core,Core APIs...
# 8

> The point is not that you can restart a thread.

> If invoke() didn't catch the exception, then the

> thread wouldn't be interrupted in the first place and

> would go on if you don't end it in

> uncaughtException().

I don't get it. What exactly is the difference between the original Exception and the InvocationTargetException regarding thread execution? Perhaps you could provide some code?

ipreuss at 2007-7-1 17:25:30 > top of Java-index,Core,Core APIs...
# 9

> > I am not sure I do understand your problem, but did

> > you notice you can get the original exception by

> > getTargetException()?

>

> Yes. The problem is this:

> in my ThreadGroup I can override the following method

>

> uncaughtExteption(Thread td, Throwable t);

>

> And I can continue the Thread if I decide the

> Exception isn't important.

Wouldn't it be a more extensible approach to determine the importance of an exception from the context it was thrown? That is, in the thread implementation that called the method that created the exception. If common behaviour is required, this can trivially be provided through subclassing or delegation, with no loss in configurability from the ThreadGroup approach.

My concern here is such an approach may promote 'lazy' exception handling by programmers, throwing exceptions on when they would be more sensibly (?) handled in context.

> With invoke, it catches the exception, and just

> rethrows it. How is this usefull? It TAKES AWAY value

> from Java, because the uncaught Exception never makes

> it to the ThreadGroup's uncaughtException method. A

> proper stacktrace would tell me that I had passed into

> the invoke method, so wrapping the Exception is

> utterly useless.

I don't understand this point of view... no value is lost from wrapping an exception in a more context-appropriate exception. The call to invoke resulted in an exception, but the invoke() call did not cause the exception, the reflected method did. So to provide an exception more appropriate to the context, the exception is wrapped and rethrown. Both stack traces are still available, and the once the InvocationTargetException is thrown, the application is in exactly the same state as if you had called the reflected method directly.

This is an example, IMHO, of intelligently handling an exception to provide a more accurate context of the situation.

My first and last response would be, that if you want a thread to continue execution in the face of an exception, then you should catch the exception and deal with it in the thread.

> (Sorry about the rant. I'm a bit flustered.)

> -mark

Ranting is acceptable, it offers proof that programmers have heart :-)

-Troy

fiontan at 2007-7-1 17:25:30 > top of Java-index,Core,Core APIs...
# 10

> There are some cases when it decides it's OK for the

> thread to continue even though an exception occurred.

> For example, during debugging it can ask the developer

> if it's OK to proceed.

How can this matter? The target Thread's run() has terminated abnormally anyway. You can't proceed from the throw point anyway.

Vlad.

vladimp at 2007-7-1 17:25:30 > top of Java-index,Core,Core APIs...