JDK-6747877 : Complex use of generics does not compile (javac and javadoc both crash)
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2008-09-12
  • Updated: 2011-02-16
  • Resolved: 2010-07-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7Resolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java -version:
java version "1.6.0_06"
Java(TM) SE Runtime Environment (build 1.6.0_06-b02)
Java HotSpot(TM) Client VM (build 10.0-b22, mixed mode, sharing)

javac - version: javac 1.6.0_06

ADDITIONAL OS VERSION INFORMATION :
Linux XXX  2.6.24-19-386 #1 Wed Aug 20 21:59:50 UTC 2008 i686 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
There were similar bug reports for simpler complex uses of generics and this bug was supposed
to be fixed in Java 6 (if I remember correctly).  I have a 'core' simulation package with a complex
use of generics.  Other packages provide different "flavors" of simulations that provide domain-specific
classes and that hide the complex use of generics from the average programmer.  If I try to compile
everything at once, I get an incorrect errorr message:

org/cmdl/sim/AbstractSimulation.java:18: cannot find symbol
symbol: class AbstractActor
    A extends AbstractActor<S,A,C,D,DM,F,G>,

If I compile the files in a specific order, the compiler crashes:

An exception has occurred in the compiler (1.6.0_06). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport)  after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report.  Thank you.
java.lang.NullPointerException
	at com.sun.tools.javac.comp.Check.checkCompatibleConcretes(Check.java:1215)
	at com.sun.tools.javac.comp.Check.checkCompatibleSupertypes(Check.java:1567)
	at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:2668)
	at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2622)
	at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2558)
	at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1036)
	at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:765)
	at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:730)
	at com.sun.tools.javac.main.Main.compile(Main.java:353)
	at com.sun.tools.javac.main.Main.compile(Main.java:279)
	at com.sun.tools.javac.main.Main.compile(Main.java:270)
	at com.sun.tools.javac.Main.compile(Main.java:69)
	at com.sun.tools.javac.Main.main(Main.java:54)

If I compile all of the files but one and then compile that other file separately, the compliation fails
once but succeeds on subsequent tries.

The use of generics is fairly complex.  In the org.cmdl.sim package, the relevant classes (just the
top level) are:
abstract public class AbstractActor<
    S extends AbstractSimulation<S,A,C,D,DM,F,G>,
    A extends AbstractActor<S,A,C,D,DM,F,G>,
    C extends AbstractCondition<S,A,C,D,DM,F,G>,
    D extends AbstractDomain<S,A,C,D,DM,F,G>,
    DM extends AbstractDomainMember<S,A,C,D,DM,F,G>,
    F extends AbstractFactory<S,A,C,D,DM,F,G>,
    G extends AbstractGroup<S,A,C,D,DM,F,G>>
    extends MessageRecipient<S,A,C,D,DM,F,G> {}
abstract public class AbstractCondition<
    S extends AbstractSimulation<S,A,C,D,DM,F,G>,
    A extends AbstractActor<S,A,C,D,DM,F,G>,
    C extends AbstractCondition<S,A,C,D,DM,F,G>,
    D extends AbstractDomain<S,A,C,D,DM,F,G>,
    DM extends AbstractDomainMember<S,A,C,D,DM,F,G>,
    F extends AbstractFactory<S,A,C,D,DM,F,G>,
    G extends AbstractGroup<S,A,C,D,DM,F,G>>
    extends TaskObject<S,A,C,D,DM,F,G> {}
abstract public class AbstractDomain <
    S extends AbstractSimulation<S,A,C,D,DM,F,G>,
    A extends AbstractActor<S,A,C,D,DM,F,G>,
    C extends AbstractCondition<S,A,C,D,DM,F,G>,
    D extends AbstractDomain<S,A,C,D,DM,F,G>,
    DM extends AbstractDomainMember<S,A,C,D,DM,F,G>,
    F extends AbstractFactory<S,A,C,D,DM,F,G>,
    G extends AbstractGroup<S,A,C,D,DM,F,G>>
    extends TaskObject<S,A,C,D,DM,F,G>
    implements Comparable<D>, CondObserver<C>{}

public class AbstractDomainMember<
    S extends AbstractSimulation<S,A,C,D,DM,F,G>,
    A extends AbstractActor<S,A,C,D,DM,F,G>,
    C extends AbstractCondition<S,A,C,D,DM,F,G>,
    D extends AbstractDomain<S,A,C,D,DM,F,G>,
    DM extends AbstractDomainMember<S,A,C,D,DM,F,G>,
    F extends AbstractFactory<S,A,C,D,DM,F,G>,
    G extends AbstractGroup<S,A,C,D,DM,F,G>>
    extends AbstractSimObject<S,A,C,D,DM,F,G>
{}
abstract public class AbstractFactory<
    S extends AbstractSimulation<S,A,C,D,DM,F,G>,
    A extends AbstractActor<S,A,C,D,DM,F,G>,
    C extends AbstractCondition<S,A,C,D,DM,F,G>,
    D extends AbstractDomain<S,A,C,D,DM,F,G>,
    DM extends AbstractDomainMember<S,A,C,D,DM,F,G>,
    F extends AbstractFactory<S,A,C,D,DM,F,G>,
    G extends AbstractGroup<S,A,C,D,DM,F,G>>
{}
abstract public class AbstractGroup<
    S extends AbstractSimulation<S,A,C,D,DM,F,G>,
    A extends AbstractActor<S,A,C,D,DM,F,G>,
    C extends AbstractCondition<S,A,C,D,DM,F,G>,
    D extends AbstractDomain<S,A,C,D,DM,F,G>,
    DM extends AbstractDomainMember<S,A,C,D,DM,F,G>,
    F extends AbstractFactory<S,A,C,D,DM,F,G>,
    G extends AbstractGroup<S,A,C,D,DM,F,G>>
    extends MessageRecipient<S,A,C,D,DM,F,G>
{}
abstract public class AbstractSimObject<
    S extends AbstractSimulation<S,A,C,D,DM,F,G>,
    A extends AbstractActor<S,A,C,D,DM,F,G>,
    C extends AbstractCondition<S,A,C,D,DM,F,G>,
    D extends AbstractDomain<S,A,C,D,DM,F,G>,
    DM extends AbstractDomainMember<S,A,C,D,DM,F,G>,
    F extends AbstractFactory<S,A,C,D,DM,F,G>,
    G extends AbstractGroup<S,A,C,D,DM,F,G>>
    extends SimObject {}
public class AbstractSimulation<
    S extends AbstractSimulation<S,A,C,D,DM,F,G>,
    A extends AbstractActor<S,A,C,D,DM,F,G>,
    C extends AbstractCondition<S,A,C,D,DM,F,G>,
    D extends AbstractDomain<S,A,C,D,DM,F,G>,
    DM extends AbstractDomainMember<S,A,C,D,DM,F,G>,
    F extends AbstractFactory<S,A,C,D,DM,F,G>,
    G extends AbstractGroup<S,A,C,D,DM,F,G>>
    extends Simulation
{}
abstract public class MessageRecipient<
    S extends AbstractSimulation<S,A,C,D,DM,F,G>,
    A extends AbstractActor<S,A,C,D,DM,F,G>,
    C extends AbstractCondition<S,A,C,D,DM,F,G>,
    D extends AbstractDomain<S,A,C,D,DM,F,G>,
    DM extends AbstractDomainMember<S,A,C,D,DM,F,G>,
    F extends AbstractFactory<S,A,C,D,DM,F,G>,
    G extends AbstractGroup<S,A,C,D,DM,F,G>>
    extends TaskObject<S,A,C,D,DM,F,G> {}
abstract public class TaskObject<
    S extends AbstractSimulation<S,A,C,D,DM,F,G>,
    A extends AbstractActor<S,A,C,D,DM,F,G>,
    C extends AbstractCondition<S,A,C,D,DM,F,G>,
    D extends AbstractDomain<S,A,C,D,DM,F,G>,
    DM extends AbstractDomainMember<S,A,C,D,DM,F,G>,
    F extends AbstractFactory<S,A,C,D,DM,F,G>,
    G extends AbstractGroup<S,A,C,D,DM,F,G>>
    extends AbstractSimObject<S,A,C,D,DM,F,G>
{}






STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
  To get the compiler to crash, pass the following file-name arguments to javac:

files="org/cmdl/sim/SimObject.java org/cmdl/sim/Simulation.java org/cmdl/sim/AbstractSimulation.java org/cmdl/sim/AbstractActor.java org/cmdl/sim/AbstractCondition.java org/cmdl/sim/AbstractDomain.java org/cmdl/sim/AbstractFactory.java org/cmdl/sim/AbstractGroup.java org/cmdl/sim/AbstractDomainMember.java org/cmdl/sim/MessageRecipient.java org/cmdl/sim/AbstractSimObject.java org/cmdl/sim/SimulationEvent.java org/cmdl/sim/MessageSimulationEvent.java org/cmdl/sim/TaskThreadSimEvent.java org/cmdl/sim/Message.java org/cmdl/sim/MessageFilter.java org/cmdl/sim/Callable.java org/cmdl/sim/CondObserver.java org/cmdl/sim/CondObserverImpl.java org/cmdl/sim/ConfigObject.java org/cmdl/sim/ConfigMethod.java org/cmdl/sim/FilteringIterator.java org/cmdl/sim/GroupInfo.java org/cmdl/sim/TaskQueue.java org/cmdl/sim/TaskThread.java org/cmdl/sim/TaskObjectSimEvent.java org/cmdl/sim/TaskSimulationEvent.java org/cmdl/sim/TaskEventCallable.java org/cmdl/sim/FifoTaskQueue.java org/cmdl/sim/SimEventCallable.java org/cmdl/sim/TaskQueueSimEvent.java org/cmdl/sim/TaskQueuePauseSimEvent.java org/cmdl/sim/DefaultSimObject.java org/cmdl/sim/DelayTaskQueue.java org/cmdl/sim/LifoTaskQueue.java org/cmdl/sim/PriorityTaskQueue.java org/cmdl/bsim/Domain.java org/cmdl/bsim/Group.java org/cmdl/bsim/Actor.java org/cmdl/bsim/DoubleCondition.java org/cmdl/bsim/Condition.java org/cmdl/bsim/BasicSimulation.java org/cmdl/bsim/BooleanCondition.java org/cmdl/bsim/DomainMember.java org/cmdl/bsim/IntegerCondition.java org/cmdl/bsim/BasicFactory.java org/cmdl/csim/DistrGroup.java org/cmdl/csim/BeliefOwner.java org/cmdl/csim/Agent.java org/cmdl/csim/Belief.java org/cmdl/csim/BeliefOwnerImpl.java org/cmdl/csim/GeoInfoDomain.java org/cmdl/csim/Action.java org/cmdl/csim/IntegerCMCondition.java org/cmdl/csim/CModelSimulation.java org/cmdl/csim/BooleanCMCondition.java org/cmdl/csim/DoubleCMCondition.java org/cmdl/csim/CModelDomainMember.java org/cmdl/csim/CModelFactory.java org/cmdl/csim/CModelCondition.java org/cmdl/csim/BeliefMessage.java org/cmdl/sim/TaskObject.java "

  To get the incorrect error message, the order of the arguments should be
 org/cmdl/sim/*.java  org/cmdl/csim/*.java   org/cmdl/bsim/*.java

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The compilation should have succeeded.
ACTUAL -
compilation failed (see above for messages)

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
	at com.sun.tools.javac.comp.Check.checkCompatibleConcretes(Check.java:1215)
	at com.sun.tools.javac.comp.Check.checkCompatibleSupertypes(Check.java:1567)
	at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:2668)
	at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2622)
	at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2558)
	at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1036)
	at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:765)
	at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:730)
	at com.sun.tools.javac.main.Main.compile(Main.java:353)
	at com.sun.tools.javac.main.Main.compile(Main.java:279)
	at com.sun.tools.javac.main.Main.compile(Main.java:270)
	at com.sun.tools.javac.Main.compile(Main.java:69)
	at com.sun.tools.javac.Main.main(Main.java:54)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
This is difficult to do.  If you need the source code for evaluation purposes (please treat it as
proprietary for now), I can provide a copy.  Since it is a compilation problem, however, simply
being able to trigger the bug should be useful.
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
break the compilation into multiple steps and put the files in a particular order.  This is not
an adequate solution when there are a very large number of files.

Comments
EVALUATION This bug cannot be reproduced using either the 6-open or the 7 compiler. I was able to reproduce the problem using the 1.6.0_06. It seems like a problem related to attribution of type-variable bounds; Peter and I (more recently) have put a lot of effort in improving cases of mutually referring type variables, by radically changing the compiler code performing type-variable attribution. I suspect that one of these fixes also made this bug not reproducible.
12-09-2008