Java compiler rejects variable declaration with parameterized inner class

generics, groovy, inner-classes, java

Solution

Since the `ProcessingQueueMember` class is a non-static inner class of `AbstractProcessingQueue`, its body can refer to the `T` type parameter of `AbstractProcessingQueue`. Thus, a non-raw reference to the `ProcessingQueueMember` must supply both the type arguments. For example,

protected java.util.Queue<AbstractProcessingQueue<T>.ProcessingQueueMember<T>> items;

will compile. This code is probably excessively generic. I believe you actually want one of these two alternatives:

- Make `ProcessingQueueMember<E>` static (i.e. a nested class as opposed to an inner class)

- Remove the type parameter from `ProcessingQueueMember`

I do not know anything about the groovy stub generator, but maybe there is some way to annotate your groovy code to express this?

Problem

I have some Groovy code which works fine in the Groovy bytecode compiler, but the Java stub generated by it causes an error in the Java compiler. I think this is probably yet another bug in the Groovy stub generator, but I really can't figure out why the Java compiler doesn't like the generated code. Here's a truncated version of the generated Java class (please excuse the ugly formatting): ``` @groovy.util.logging.Log4j() public abstract class AbstractProcessingQueue <T> extends nz.ac.auckland.digitizer.AbstractAgent implements groovy.lang.GroovyObject { protected int retryFrequency; protected java.util.Queue<nz.ac.auckland.digitizer.AbstractProcessingQueue.ProcessingQueueMember<T>> items; public AbstractProcessingQueue (int processFrequency, int timeout, int retryFrequency) { super ((int)0, (int)0); } private enum ProcessState implements groovy.lang.GroovyObject { NEW, FAILED, FINISHED; } private class ProcessingQueueMember<E> extends java.lang.Object implements groovy.lang.GroovyObject { public ProcessingQueueMember (E object) {} } } ``` The offending line in the generated code is this: ``` protected java.util.Queue<nz.ac.auckland.digitizer.AbstractProcessingQueue.ProcessingQueueMember<T>> items; ``` which produces the following compile error: ``` [ERROR] C:\Documents and Settings\Administrator\digitizer\target\generated-sources\groovy-stubs\main\nz\ac\auckland\digitizer\AbstractProcessingQueue.java:[14,96] error: improperly formed type, type arguments given on a raw type ``` The column index of 96 in the compile error points to the `<T>` parameterization of the `ProcessingQueueMember` type. But `ProcessingQueueMember` is not a raw type as the compiler claims, it is a generic type: ``` private class ProcessingQueueMember <E> extends java.lang.Object implements groovy.lang.GroovyObject { ... ``` I am very confused as to why the compiler thinks that the type `Queue<ProcessingQueueMember<T>>` is invalid. The Groovy source compiles fine, and the generated Java code looks perfectly correct to me too. What am I missing here? Is it something to do with the fact that the type in question is a nested class? (in case anyone is interested, I have filed this bug report relating to the issue in this question) Edit: Turns out this was indeed a stub compiler bug- this issue is now fixed in 1.8.9, 2.0.4 and 2.1, so if you're still having this issue just upgrade to one of those versions. :)

Original source