-
Bug
-
Resolution: Won't Fix
-
P2
-
None
-
1.4.0
-
None
-
generic
-
generic
Since at least JDK 1.2 (and likely before that, but am having trouble running
earlier binaries) the implementation of Class.newInstance() has had the
following behavior:
- If the no-arg constructor invoked reflectively threw an exception, regardless
of the type of that exception, it would be propagated out unchanged from the
newInstance() call, despite the fact that newInstance() is specified to throw
only InstantiationException and IllegalAccessException.
This behavior is neither spec-compliant nor language-compliant; the
documentation states that InstantiationException is thrown "...if the
instantiation fails for some other reason", and random checked exceptions could propagate out of Class.newInstance(); see the attached NewInstance.java.
Conversely, since JDK 1.1, Method.invoke() and Constructor.newInstance() have
been specified to wrap all exceptions in java.lang.InvocationTargetException. We
recommend amending the Class.newInstance() specification in JDK 1.4 to be more
precise:
- If the constructor completes abruptly by throwing an exception, the exception
is placed in an <code>InstantiationException</code> using the
<code>initCause</code> method of <code>Throwable</code> and thrown in turn to
the caller of <code>newInstance</code>.
This will bring the Constructor.newInstance() and Class.newInstance()
specifications in line, and allow proper implementation of Class.newInstance()
in terms of Constructor.newInstance(), as has been done in JDK 1.4.
The risk of making this change is that using code which has relied on catching
certain types of Throwables from reflective invocations will now only see those
Throwables in the form of InstantiationExceptions. The risks of not making this
change are that the specification will continue to be unclear and that
Class.newInstance()'s old behavior, implicitly specified to this point via its
native-code implementation, is unimplementable with the Java programming
language.
earlier binaries) the implementation of Class.newInstance() has had the
following behavior:
- If the no-arg constructor invoked reflectively threw an exception, regardless
of the type of that exception, it would be propagated out unchanged from the
newInstance() call, despite the fact that newInstance() is specified to throw
only InstantiationException and IllegalAccessException.
This behavior is neither spec-compliant nor language-compliant; the
documentation states that InstantiationException is thrown "...if the
instantiation fails for some other reason", and random checked exceptions could propagate out of Class.newInstance(); see the attached NewInstance.java.
Conversely, since JDK 1.1, Method.invoke() and Constructor.newInstance() have
been specified to wrap all exceptions in java.lang.InvocationTargetException. We
recommend amending the Class.newInstance() specification in JDK 1.4 to be more
precise:
- If the constructor completes abruptly by throwing an exception, the exception
is placed in an <code>InstantiationException</code> using the
<code>initCause</code> method of <code>Throwable</code> and thrown in turn to
the caller of <code>newInstance</code>.
This will bring the Constructor.newInstance() and Class.newInstance()
specifications in line, and allow proper implementation of Class.newInstance()
in terms of Constructor.newInstance(), as has been done in JDK 1.4.
The risk of making this change is that using code which has relied on catching
certain types of Throwables from reflective invocations will now only see those
Throwables in the form of InstantiationExceptions. The risks of not making this
change are that the specification will continue to be unclear and that
Class.newInstance()'s old behavior, implicitly specified to this point via its
native-code implementation, is unimplementable with the Java programming
language.
- relates to
-
JDK-4428861 java.lang.reflect.Method.invoke() throws incorrect exceptions
-
- Closed
-