Generics compiler bug?
I've been using generics for a few years, and I'm happy with them. I'm
aware of the issues related to their design, and I agree that they
could have been made a bit better (but I understand the trade-offs made
for backward compability), but on the whole I consider them quite
useful for writing better code. I haven't had any problems so far, but
now I got stuck with a thing that looks like a compiler error. Consider
this class that I'm using as a transactional decorator (*) in my
NetBeans RCP stuff:
package it.tidalwave.bluemarine.persistence;
...
public abstract class TxTask<T, E extends Throwable>
{
...
public abstract T run()
throws E;
public static <T> T
execute (final TxTask<T, RuntimeException> task)
{
return execute(RuntimeException.class, task);
}
public static <T, E extends
Throwable> T execute (final Class<E>
exceptionClass,
final TxTask<T, E> task)
throws E
{
try
{
...
try
{
result = task.run();
...
}
catch (RetryException e)
{
...
}
catch (PersistenceException e)
{
...
}
}
catch (Throwable t)
{
...
if (exceptionClass.isAssignableFrom(t.getClass()))
{
////////////////////// THE PROBLEM IS HERE
throw (E)t;
////////////////////// THE PROBLEM IS HERE
}
throw (t instanceof RuntimeException) ? (RuntimeException)t : new
RuntimeException(t);
}
...
}
...
return result;
}
}
The peculiarity of this class is that it uses a generic in
the "throws" clause. This is ok with the language specifications, see
for instance the excellent
href="http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#Can%20I%20use%20a%20type%20parameter%20in%20in%20a%20throws%20clause">Angelika
Langer's tutorial on generics (even
though it's considered pretty useless in most cases, since you can't
throw a generified exception because of type erasure - but in my code
things are ok since I'm just rethrowing).
Now, the history of this issue is pretty complicated:
- The thing worked for several weeks, if not months (I remind
you, in a NetBeans RCP project) - At a certain point, I copied the class in the prototype of
a
web application, and I got a compiler error (see below); since I was
focused on other things, I just commented out the offending part.
blueMarine was still compiling ok. - Since a few weeks, this is triggering the compiler error
even in the NetBeans RCP project: but ONLY IF I BUILD THE WHOLE
PROJECT (that is, if multiple *.java files are compiled at the same
time). If I select the single TxTask.java file and compile it with
the pop-up menu, it gets compiled ok (in fact, with this trick
blueMarine builds, runs and passes the tests).
<br>.../TxTask.java:169: unreported exception java.lang.Throwable; must be caught or declared to be thrown<br> throw (E)t;<br><br>This happens with the Java 5 compiler both on Mac OS X and Ubuntu
Linux. I've asked for help in a couple of mailing lists so far, without
success. So if you have any hints, please help: it is causing major
pain, since it's breaking the CI on Hudson. The full source of the
class is here: href="https://bluemarine.dev.java.net/svn/bluemarine/trunk/src/blueMarine-core/Core/Persistence/src/it/tidalwave/bluemarine/persistence/TxTask.java">
https://bluemarine.dev.java.net/svn/bluemarine/trunk/src/blueMarine-core/Core/Persistence/src/it/tidalwave/bluemarine/persistence/TxTask.java
(*) I'd like to get rid of this class sooner or later and use Spring or
EJB3 annotations for transactions - but this won't happen before the
next release, and I need to have CI working before that.
- Login or register to post comments
- Printer-friendly version
- fabriziogiudici's blog
- 1102 reads






Comments
by fabriziogiudici - 2008-06-14 05:20
Thanks for the suggestion, it's one of the things I tried (together with other tricks such as encapsulating the thing in a method, etc...) but it doesn't make the error go away (it's an error, not a warning).
The benefit is important, the capability of wrapping any piece of code without changing the type of the exception it may throw.
by mcnepp - 2008-06-16 02:53
As a sidenote, I suggest declaring the static methods as public static <T> T execute (final TxTask<T, ? extends RuntimeException> task) and public static <T, E extends Throwable> T execute (final Class<E> exceptionClass, final TxTask<T, ? extends E> task) throws E so that you'll be able to easily execute tasks declaring all kinds of RuntimeExceptions.by yardena - 2008-06-13 09:38
In my project I used to have problems compiling generics with Java 5 - from files compiling individually, but not together, to even compiler crashes; but they issues gradually went away while I was upgrading to latest version of Java 6. With 6.6 I don't see any of the issues I used to have. Maybe you should try compiling with Java 6. Also using "throw exceptionClass.cast(t)" instead of "throe (E)t" would make the warning go away. Last (and least) - perhaps I don't see a larger picture, but does parametrization on exception type actually give you any benefit? If not, I would suggest to simply avoid it... But again, I may be judging incorrectly based on a short snippet. HTH.by forax - 2008-06-15 13:03
This bug is referenced here:
http://bugs.sun.com/view_bug.do?bug_id=6280975
It was fixed when working on JSR 199
http://bugs.sun.com/view_bug.do?bug_id=6199662
Rémi
by fabriziogiudici - 2008-06-16 15:36
Ok, I'll never be able to escape all the stuff and post the code here... look at the comment at DZone: http://netbeans.dzone.com/news/generics-compiler-bug#comment-4085by fabriziogiudici - 2008-06-16 15:32
Ok, my Hudson thanks for the advice :-) In my NetBeans RCP project I worked around the problem by adding this in the build.xml file Basically, it overrides the target for compiling the project and makes sure that the TxTask file is compiled alone before the others.by fabriziogiudici - 2008-06-15 16:17
Ops, yes, thanks for the clarification. I can't use Java 6 on my MBP >:-( but I'll try to set up javac -target 1.5 on my CI server, which is a Linux box.by forax - 2008-06-15 16:03
It's not strange, it's a bug in the compiler architecture so it can't be easily backported. So the bug is corrected in jdk 6 but is not corrected in jdk5.
Also note that jdk6 compiler can generate 1.5 compatible classes using -target 1.5
Rémi
by fabriziogiudici - 2008-06-15 14:29
Thanks Rèmi. Both issues are closed since a few years - so it seems I'm triggering it again... Very strange, I'll try to post a test case to the bug parade.