Unreachable catch classes
Robert Fischer
robert.fischer at smokejumperit.com
Thu May 26 02:53:33 UTC 2011
Some non-Java languages produce bytecode that lie about which
exceptions they throw, and so unmarked methods may throw
non-RuntimeException Exception instances from there, too.
For instance, this Groovy method:
def bar() {
throw new Exception("Away it goes!")
}
compiles to this bytecode method:
public java.lang.Object bar();
flags: ACC_PUBLIC
Code:
stack=3, locals=2, args_size=1
0: invokestatic #24 // Method
$getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
3: astore_1
4: aload_1
5: ldc #35 // int 0
7: aaload
8: invokestatic #39 // Method
$get$$class$java$lang$Exception:()Ljava/lang/Class;
11: ldc #41 // String Away it goes!
13: invokeinterface #47, 3 // InterfaceMethod
org/codehaus/groovy/runtime/callsite/CallSite.callConstructor:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
18: checkcast #49 // class java/lang/Throwable
21: athrow
22: aconst_null
23: areturn
LocalVariableTable:
Start Length Slot Name Signature
0 22 0 this LFoo;
LineNumberTable:
line 3: 4
Unless I'm missing something, there's no warning to code consuming
this method that a should-be-checked exception is thrown in this
method.
So, as someone who is using that code, it is in my best interest to
catch Exception (not just RuntimeException), because I may well see
Exception.
This "unreachable exception" stuff seems like a nice idea, but not
really feasible. I've taken to just ignoring the warnings.
~~ Robert.
On Wed, May 25, 2011 at 10:27 PM, David Holmes <David.Holmes at oracle.com> wrote:
> It hadn't occurred to me before but the "more precise rethrow" semantics are
> basically making the same invalid assumption about where checked exceptions
> can be thrown. Before if you catch Throwable and want to rethrow then you
> have to cast to an unchecked exception type, or else wrap with an unchecked
> exception type. Now you can catch Throwable and simply rethrow it -
> potentially letting an undeclared checked-exception to continue to make its
> escape.
>
> Now given that you could instead have only caught unchecked-exceptions, and
> the undeclared checked exception would have escaped anyway, this is perhaps
> not a big deal.
>
> But it troubles me that the language assumes things that are known to not be
> upheld by the libraries, and rather than helping to identify such cases this
> language change will now be helping to hide such cases.
>
> David
>
> David Holmes said the following on 04/28/11 22:03:
>>
>> Maurizio Cimadamore said the following on 04/28/11 21:56:
>>>
>>> On 27/04/11 13:51, Maurizio Cimadamore wrote:
>>>>
>>>> On 27/04/11 09:18, David Holmes wrote:
>>>>>
>>>>> Special-casing Throwable wouldn't be sufficient as people may use
>>>>> Exception instead.
>>>>
>>>> I guess this doesn't invalidate the argument - we could special-case
>>>> Exception AND Throwable, since they are already treated specially in the
>>>> language...
>>>>
>>>> Maurizio
>>>
>>> Hi
>>> after a discussion with the team, we have decided that we will relax the
>>> new javac warnings so that they will *not* be generated for those catch
>>> clauses catching Exception or Throwable.
>>>
>>> This is similar to how javac has always handled a similar case (error
>>> message: 'exception never thrown in body of try'); for example, this code
>>> compiles:
>>>
>>> try { }
>>> catch (Exception e) { ... }
>>>
>>> while the following does not compile:
>>>
>>> try { }
>>> catch (IOException e) { ... } //error IOException never thrown
>>
>> Thanks Maurizio. I never realized the above case existed. :)
>>
>> David
>> -----
>>
>>
>>>
>>> The code generating the newly added javac warnings will be changed
>>> accordingly; for example, the following will compile w/o warnings:
>>>
>>> try { throw new FileNotFoundException(); }
>>> catch (FileNotFoundException fnf) { ... }
>>> catch (Exception e) { ... }
>>>
>>> while the following code will still emit a 'dead catch' warning:
>>>
>>> try { throw new FileNotFoundException(); }
>>> catch (FileNotFoundException fnf) { ... }
>>> catch (IOException e) { ... }
>>>
>>>
>>> This should accommodate all weird cases of checked exceptions not being
>>> declared (as in Class.newInstance).
>>>
>>> Maurizio
>>>
>>>
>>>
>>>
>>>
>
More information about the core-libs-dev
mailing list