Search |
||
Generics compiler bug?Posted by fabriziogiudici on June 13, 2008 at 2:14 AM PDT
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 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:
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: 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. »
Comments
Comments are listed in date ascending order (oldest first)
Submitted by fabriziogiudici on Sun, 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.
Submitted by forax on Sun, 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
Submitted by fabriziogiudici on Sun, 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.
Submitted by fabriziogiudici on Mon, 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.
Submitted by fabriziogiudici on Mon, 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-4085
Submitted by forax on Sun, 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
Submitted by yardena on Fri, 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.
Submitted by mcnepp on Mon, 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.
Submitted by fabriziogiudici on Sat, 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.
|
||
|
|