Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4209652
Votes 147
Synopsis Put recursive exception handling (ala InvocationTargetException) into Throwable!
Category java:specification
Reported Against 1.2 , 1.3 , 1.1.5
Release Fixed 1.4(merlin-beta)
State 10-Fix Delivered, request for enhancement
Priority: 5-Very Low
Related Bugs 4355074 , 4398872 , 4487432 , 4794674
Submit Date 08-FEB-1999
Description




It seems that lots of exceptions need support for "internal" or "child" exceptions ala InvocationTargetException. For instance, you often have to
catch exceptions of one type and re-throw them as an xxxxx . If this functionality was built into Throwable, it would mean that I (and lots of  xxxxx s)
wouldn't have to make incompatible implementations of this functionality. For example, the OO-RDBMS mapping product we're using (TOPLink)
implements this in their TOPLinkException, and so do we in our code. However, using this is a nightmare because the exception handling code
has to support each type of exception differently.

Note also that this could provide an xxxxx , even more useful feature - the ability to avoid the "got an silly exception in a finally clause which blows
away the important exception I had in the first place" which is pointed out in the Java book "Thinking in Java" by Bruce Eckel (www.bruceeckel.com).
Simply append any exceptions found whilst processing the original exception as "sub" exceptions using the mechanism outlined above and I belive
you have avoided the problem. Of course, how the VM would actually handle that may be harder but thats your job, huh?

:-)
(Review ID: 52287)
======================================================================




In fact this particular one is just an instance of a more general
need to have the JDK exceptions carry useful information about what
caused them and to make that information available programatically.

It would improve error handling to be able to
find out from a ClassCastException what class
(or interface) the cast was to and what class
it was from. Something like:

public Class targetClass();
public Class sourceClass();

or maybe just return Strings with the class name
and folks can Class.forName() them if they need
to.

P.S. I realize that the message currently returns
the name of the class the cast was from. But
that's not part of the contract.

An xxxxx  thought: you might need to make these
methods possibly return null if the class isn't
known. But since most ClassCastExceptions should
be generated by the VM and it certainly knows both
classes.
(Review ID: 25234)
======================================================================
Work Around
N/A
Evaluation
If I understand what is meant by "internal" exceptions correctly, they
are often needed in order to permit static typechecking.  In some APIs,
e.g., reflection, part of the functionality may be delegated to code that
is entirely unknown at compile-time, thus the set of possible exceptions
is open-ended.  Using an internal exception allows the set of exceptions
that we do know to expect at compile-time to be explicitly declared,
providing tighter static typing than simply declaring "throws Throwable".

 xxxxx@xxxxx  1999-02-12

I could be wrong, but I suspect this happens mostly to sophisticated users, and
is NOT all that frequent relative to all users of Java.  I doubt if adding this
either as a special class or (worse) by modifying Throwable is justified.
It just seems like creeping featurism.


 xxxxx@xxxxx  1999-02-16

I think that this is a good idea; it's not really adding a new feature, but providing a quality abstraction for one that already exists.  In practice, I believe that it will increase the quality of information available after an exception is thrown.

 xxxxx@xxxxx  1999-08-17

This is now the draft feature list for Merlin as 4293532

 xxxxx@xxxxx  2000-03-03
Comments
  
  Include a link with my name & email   

Submitted On 21-MAY-1999
seibel
[Note: this comment was originally sent via email
to some individuals at Javasoft. Hopefully they
won't mind me posting it again here.]
I'd like to respectfully disagree with both the
claim that this is not a frequently encountered
problem and with the fear that the proposed
addition to Throwable would be creeping featurism.
There are a number of reasons that building the
concept of nested exceptions into Throwable would
be a good idea:
* Refactoring and Standardization *
  Lots of folks need this functionality. Since
  they don't get it from Throwable they are forced
  to write it into their own exception classes
  leading to code duplication and differences in
  implementation. Just looking at the JDK and
  standard extensions we see several examples:
    java.sql.SQLException
    java.lang.reflect.InvocationTargetException
    java.lang.ExceptionInInitializerError
    java.rmi.RemoteException
    javax.naming.NamingException
  These classes vary in how the nested exception
  is passed in: some via constructor, some by a
  setter; the name of the method to get the nested
  exception: getNextException(),
  getTargetException(), getException(),
  getRootCause(), and even a public field; and,
  finally, what printStackTrace() does with the
  nested exception: many include an apparently
  cut-n-pasted swatch of code to print out the
  name of the exception and the nested execption's
  stack trace if there is a nested exception.
  Others print both stack traces (which seems the
  most useful to me) and others don't print it at
  all. Clearly there is a bunch of duplicated
  functionality that could be refactored and
  standardized by moving nesting into Throwable.
  (This lack of factoring has already hurt you;
  see bugs 4086279 and 4019376.) And that's just
  in the JDK--every organization that I know of
  that does serious Java programming pretty soon
  runs into the need for nested exceptions and
  starts sprinkling the code for it throughout
  their system or writes their own top-level
  exception (e.g. the TOPLinkException mentioned
  in the RFE). At WebLogic, we found that we
  needed nested exceptions so often that we went
  the route of a common base class. But it
  distorts our exception hierarchy to have a class
  that everything extends just for code sharing.
  And we still don't get a consistent interface
  since we obviously don't control all the
  exception classes we use.
* It allows for clean abstractions without
  losing information *
  One of the important (perhaps even fundamental)
  ideas, it seems to me, behind exceptions is that
  they are way to pass failure information across
  levels of abstraction. That is, a lower-level
  piece of code can indicate that something failed
  without having to decide what to do about it.
  But when abstractions are layered, without
  nested exceptions, we run into a problem of
  which layer's info to pass on. For example if my
  application is using some storage API and a
  particular implementation of that API uses a
  networking API to store stuff on remote machines
  then things could go wrong for my app at both
  the storage and the network layer. Suppose my
  app is responsible for initializing both the
  storage subsystem and the networking layer. When
  I go to use the storage API things could fail at
  either the storage API level or the networking
  level and in either case I need to either try to
  recover or at least give a meaningful error
  message about what's not configured properly.
  Presumably the storage API will translate
  networking exceptions into storage exceptions
  (because it's not part of the storage
  abstraction to throw network exceptions) but
  that means that without nested exceptions I have
  no good way of finding out what really went
  wrong if it was a networking problem. If the
  author of the storage API thought of this then
  he or she could have made the storage-API's
  exceptions handle nesting but then we're back to


Submitted On 21-MAY-1999
adam@organic.com
Every Java project I've worked on has implemented
its own nested exception.  Since this seems to be
a common need, it would be nice if everyone didn't
have to re-invent the wheel here.
Additionally every project I've worked on has also
implemented a static method to stringify a 
stacktrace.  It would also be nice if there were
a good way to get this from the Throwable base
class.


Submitted On 15-AUG-1999
tbreuel
The creeping featurism is a result of requiring
exception declarations in Java.  If you want
to simplify the language, just drop exception
declarations altogether, like most other
languages with exceptions have done (a 
backwards compatible change).  Otherwise, it seems
to me you should add better support for nested
exceptions, as well as making exceptions part
of any future genericity mechanism.


Submitted On 12-OCT-1999
MPocock
The stack traces should work something like this. If Throwable A is thrown, and
then wrapped in Throwable B, a call to A.printStackTrace() should do what it
always would have done - list the stack for that Throwable. If you call
B.printStackTrace() it should print out the message for A, A's stack trace down
to where it was caught, a message like " rethrown ", B's message and
B's stack trace from then down.
i.e.
A.printStackTrace()
BadException: Something went realy wrong
place1
place2
place3
Main
B.printStackTrace()
BadException: Something went realy wrong
place1
place2
Rethrown by ExpectedException: I noticed something wrong
place3
Main


Submitted On 10-DEC-1999
william.connor
The Federated Management Architecture Java
extension introduces an interface named
ComppositeThrowable to handle nested throwables.
It handles not just chains of throwables, but
trees of throwables, which we found neccessary
when a throwable was thrown for multiple reasons,
as is common in retry situations. Composite
throwable also does the following:
- captures stack traces during remote operations.
- uses localizable messages rather than strings.
The specification for CompositeThrowable may be
found in the FMA Specification at
http://java.sun.com/aboutJava/communityprocess/review/jsr009/index.html


Submitted On 05-JAN-2000
jglick
I'm not sure what the best solution would be but something really seems to be
needed.
I also have seen numerous (re-)implementations of nested exceptions, none of
them
of course interoperable with anyone else's code, especially that in the Java
platform.
E.g. look at the following code from 1.2.2 Beans.instantiate and think about
how you
would go about debugging things when a needed class' constructor threw a
NullPointerException
(note that no stack trace will be available):
	    try {
	        result = cl.newInstance();
	    } catch (Exception ex) {
		// We have to remap the exception to one in our signature.
		// But we pass extra information in the detail message.
	        throw new ClassNotFoundException("" + cl + " : " +
ex);
	    }


Submitted On 24-JAN-2000
MiguelM
Even if this only happens to sophisticated users, that's because they are the
ones who 
know how to write maintainable code. I encountered this when adding a
third-party 
spelling checker. I encapsulated all of the third-party code into a single
class. This allows
me to change to a different spell-checker in the future, without having to
rewrite a bunch
of classes. However, my encapsulating class can't throw any third-party
exceptions, or 
the encapsulation will get broken. I handle this by wrapping my exception into
a custom
exception wrapper. It would be very nice to have this functionality in a single
class. Even
if you don't put this feature into Throwable, (which would be my preference),
you could 
make a single wrapping exception which provides this functionality.


Submitted On 26-FEB-2000
Diekhans
This is an essentially feature if one is to implement robust
error handling in a simple way.  Without providing some
complex framework outside of
the standard java error handling, one is forced to discard
information
that maybe critical to understanding a bug.  This is the
cause of the
classic frustrating  class of error messages where one gets
either  `can not open foo'  or `permission denied'' when one
needs both pieces of
information to understand what occured.  While we base all
of our errors
on a set of classes that have an associated causing
exceptions, we
still run into problems with other packages not having such
a mechanism.

The proliferation of stadard java exceptions that implement
this mechanism
demostrates its importance.  RemoteException,
ServletException,
SQLException, ExceptionInInitializerError,  and
InvocationTargetException
all implement this in incompatbile ways.  The fix is trivial
and the
value of not discarding error information huge.  Please add
this
ASAP.  Robust applications come from  desiging in error
handling.
Help us write robust applications.





Submitted On 15-JUN-2000
ljnelson
I'd like to add my voice to those chiming for a
CompositeThrowable class.  Here is a sketch at the way I'd
personally like to have it implemented:

public interface ThrowableContainer {
  public Throwable getThrowable();
}

public class CompositeThrowable extends Throwable
  implements ThrowableContainer {
  // blah blah blah
  private final Throwable contained;
  public CompositeThrowable(Throwable t, String msg) {
    super(msg);
    this.contained = t;
  }
  public Throwable getThrowable() {
    return this.contained;
  }
}

Additionally another class, call it ThrowableUtilities (or
perhaps just a static method on CompositeThrowable or
something) should provide for extracting the String
representation of a stack trace.  The String representation
of a stack trace of a CompositeThrowable should reflect all
stack traces that are available.


Submitted On 21-JUL-2000
pnkfelix
I think this RFE in general demonstrates how poorly
Exceptions are used in most parts of the Java class
libraries.  

I personally don't know how necessary it is to make all
Throwables support nested exceptions...seibel said the
following: 

JD: Well, I don't know about how useful that would be but I
guess you couldn't even do it without some help from
Throwable. You're
right. Let's do it...

I personally don't see why "you couldn't even do it without
some help from Throwable"... if you're designing your
Exceptions and you see a good chance that you're going to
have to deal with subExceptions, then you can add the data
and accessors to your Exception itself.   The code I write
doesn't catch "Throwable", it catches specific Exception
types. 
But, I suppose adding an additional method
"getSubException()" that just returns null in its default
implementations wouldn't be a bad idea.

That being said, I'm going to reiterate that the majority of
Exceptions in the JDK *do* seem to cop out in terms of
design and don't include half of the information that they
should... Why *doesn't* ClassCastException include the
castTo/castFrom fields?  That just seems too logical!  Why
do all the methods in java.io.* just say "throws
IOException" instead of specifying the subset of IOException
that actually might be thrown?  Why doesn't
FileNotFoundException have a field with the String/File for
the file that we were attempting to find?  Why AREN'T we
giving the application the information it needs to properly
recover from an error situation?

So, I guess what I'd fight for here would be for Sun to
revamp the designs they've put in for the majority* of their
Exception classes.  I can see that you all are fighting for
a useful design addition for many exception types, but let's
not overlook the possibility for even more improvement in
this regard...


*I'll forgive them for not enhancing NullPointerException
C;)


Submitted On 15-SEP-2000
eblake
This feature could fix other problems.  For example, it is
possible to write code that allows checked exceptions to
escape unchecked (which seems highly illegal according to
the JLS) by exploiting a hole in Class.newInstance().

import java.lang.reflect.*;
class ExceptionProblem {
  public static void main(String[] args) {
    try {
     
ExceptionProblem.class.getConstructor(null).newInstance(null);
    } catch (InstantiationException e1) {
    } catch (IllegalAccessException e2) {
    } catch (InvocationTargetException e3) {
      System.out.println("Notice that we trapped the
exception " +
e3.getTargetException());
    } catch (NoSuchMethodException e4) {
    } catch (RuntimeException e5) {
    } catch (Error e6) {
    }
    try {
      ExceptionProblem.class.newInstance();
    } catch (InstantiationException e1) {
    } catch (IllegalAccessException e2) {
    } catch (RuntimeException e3) {
    } catch (Error e4) {
    }
    System.out.println("Since all declared checked
exceptions and all unchecked
exceptions were caught by the prior try-catch block, this
should be printed.");
  }

  public ExceptionProblem() throws MyException {
    throw new MyException("My exception must be caught, as
it is checked.");
  }

}
class MyException extends Exception {
  MyException(String msg) { super(msg); }
}


/* Produces the following output:
Notice that we trapped the exception MyException: My
exception must be caught,
as it is checked.
Exception in thread "main" MyException: My exception must be
caught, as it is
checked.
        at java.lang.Throwable.<init>(Throwable.java:96)
        at java.lang.Exception.<init>(Exception.java:44)
        at MyException.<init>(ExceptionProblem.java:31)
        at ExceptionProblem.<init>(ExceptionProblem.java:26)
        at java.lang.Class.newInstance0(Native Method)
        at java.lang.Class.newInstance(Class.java:254)
        at ExceptionProblem.main(ExceptionProblem.java:16)
*/

It would be nice if Class.newInstance() behaved more like
Constructor.newInstance, wrapping any exception that occurs
in an easy-to-obtain format, and ensuring that no checked
exceptions escape out of a try block or method declaration.


Submitted On 28-FEB-2001
rfwan
> I could be wrong, but I suspect this happens mostly to 
> sophisticated users, and
> is NOT all that frequent relative to all users of Java.
How about a method called by a Servlet which tries
to persist to the database and gets a SQL Exception
but is only allowed to throw an IOException, that sounds
fairly common.

>  I doubt if adding this
> either as a special class or (worse) by modifying 
> Throwable is justified.

the modification is short and breaks no code:
public Throwable getNestedThrowable(){return null;}
subclasses can then override the method if they need to.

> It just seems like creeping featurism.
but it is a required feature of so many exceptions that
it makes sense to make it available at the root rather
than have inconsistent implementations and naming
conventions.  Take for example, ExceptionInInitializerError,
SAXException, InvocationTargetException, Class.newInstance,
SQLException.  IOException should also have this 
functionality but it does not.  Placing the functionality
in Throwable will remove the burden from all the subclasses
to implement nested exception capability.



Submitted On 19-JUL-2001
auinger
Submitted Feb 08, 1999 and it's NOW in JDK1.4 beta..
Why did it take SO LONG???!!


Submitted On 04-MAR-2002
jqb
I'm glad to see this feature made it, but this comment

"xxxxx@xxxxx 1999-02-12

                                       I could be wrong, but I suspect this happens mostly to sophisticated users, 
and
                                       is NOT all that frequent relative to all users of Java.  I doubt if adding this
                                       either as a special class or (worse) by modifying Throwable is justified.
                                       It just seems like creeping featurism."

is wrong on *so* many levels -- it explains a lot of why Java has been such
a mess for so long.




PLEASE NOTE: JDK6 is formerly known as Project Mustang