Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
1.7.10, 1.8.0
-
None
-
None
-
WinXP
Description
Original problem:
I have an abstract groovy class, and two (or more) concrete java subclasses extend it. The superclass has an abstract method, which each concrete subclass overrides (of course).
When I use just one subclass, everything works fine: I call a superclass method that calls the abstract method, and I get the behavior I expect. But when the other subclass has already been loaded, things are different. Then, I get an IllegalArgumentException: object is not an instance of declaring class.
This problem corresponds to testGenericSubclassWithBafflingSymptom() in the attached junit tests. See that test for additional details.
Simpler case that illustrates the likely underlying problem (and does not involve generics):
I have an abstract groovy class, and two concrete java subclasses extend it. If I have an instance of just one of the subclasses, then instance.metaClass.theClass returns exactly what I expect. But if I've already loaded the other subclass, then the metaClass on an instance of either subclass is for the class that was used first!
// snippet of the groovy version of testSubclass(), also attached OtherConcreteJavaSubclass unrelatedInstance = new OtherConcreteJavaSubclass(); ConcreteJavaSubclass instance = new ConcreteJavaSubclass(); assertEquals("this one works", OtherConcreteJavaSubclass, unrelatedInstance.metaClass.theClass) assertEquals("but this one is wrong", ConcreteJavaSubclass, instance.metaClass.theClass)
This mixture of groovy and java may sound a little odd, but we actually ran into it when converting an existing class from java to groovy, and it stumped us for quite a while.