[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

how to handle throws declarations with duplicate exceptions



This note seeks input on the best approach to take to fixing a
minor bug in Soot.

As a result of a bug report, I have just learned that javac (and
jikes) both accept methods with "throws" declarations that
include the same exception more than once, as in this example:

  public static int 
  method(int i) throws IllegalArgumentException, IllegalArgumentException {

Moreover, the compilers generate class files with an Exceptions
attribute which also contains multiple copies of the declared
exception (i.e., "javap -c" on the output class file will still
show you "throws IllegalArgumentException, IllegalArgumentException").

But soot.SootMethod.addException() refuses to add multiple copies
of the same exception to the "throws" declaration of a given
method. It throws a RuntimeException instead:

    public void addException(SootClass e) 
    {
        if (exceptions == null)
            exceptions = new ArrayList();
        else if (exceptions.contains(e))
            throw new RuntimeException("already throws exception "+e.getName());

        exceptions.add(e);
    }

This seems unacceptable since it prevents Soot from reading some
class files produced by the standard tools for compiling Java.
The question is how to fix the problem.

I imagine that the original author of addException() included the
check to ensure that people using Soot to modify class files
could not inadvertently add multiple declarations of the same
exception, probably never suspecting that a class file might
include attributes with multiple copies of a single exception even
before its file was read into Soot.  

This suggests that we might want to continue to provide some kind
of duplication exception from addException(), without preventing
the input of class files whose Exceptions attributes already
contain duplicate entries (probably by catching and discarding
the duplication exception in the Coffi routines that read class
files).

A simpler alternative would be for addException() to simply
ignore requests to add an exception that is already included. In
this case we could stop throwing the exception---since adding
duplicates would have no effect---but the output Exception
attributes would differ from the input, lacking the duplicate
declarations. Would that matter?  Can anybody think of
circumstances where multiple copies of the same exception in the
Exceptions attribute means something different than a single
copy?

In principle there are two orthogonal issues:

   - whether to include multiple copies of an exception
     in the Exceptions attribute, rather than simply ignore
     repeated additions of the same exception.

   - whether or not to warn addException()'s caller when it requests
     the addition of an exception that is already included.

and thus four possible solutions:

1. Add duplicates and throw an exception (which coffi would
   ignore).

2. Add duplicates and don't throw an exception.

3. Don't add duplicates and throw an exception.

4. Don't add duplicates and don't throw an exception.


My preference is for option 4, since it is the simplest, with 1
as my second choice. (In the case of option 1, I would also
change the duplicate exception to IllegalArgumentException, since
that more accurately reflects the error condition, yet does not
requiring existing callers of addException() to change their own
"throws" declaration).

The only objection I can imagine to option 4 would be if there is
some significance to multiple copies of a single exception in an
Exceptions attribute.  So does anybody know of any such
significance?

Thanks.

-- 
John Jorgensen		jjorge1@cs.mcgill.ca