Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 365811 - resolveGenericTypes causes IndexOutOfBounds in MetadataAsmFactory
Summary: resolveGenericTypes causes IndexOutOfBounds in MetadataAsmFactory
Status: RESOLVED WONTFIX
Alias: None
Product: Gemini.JPA
Classification: RT
Component: Core (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows 7
: P3 minor (vote)
Target Milestone: 1.1.0 M1   Edit
Assignee: Michael Keith CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-12-06 16:21 EST by Nobody - feel free to take it CLA
Modified: 2012-03-27 09:42 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nobody - feel free to take it CLA 2011-12-06 16:21:44 EST
Build Identifier: 1.0.0

My situation involves updating some legacy code, and enhancing it to make use of javax.persistence annotations for use with Gemini JPA. I'm sure I can solve this issue by improving my @Entity class modelling for this particular class, but my current situation seems to have exposed a problematic case in the internal Gemini codebase which leads to a vague exception.

I have a clumsy @Entity class in my persistence unit which has an excessively complex hierarchy of non-abstract and abstract superclasses.

Various classes in the hierarchy are contributed by different bundles (at least 3 different ones). This could be a red herring, as I have many other working @Entity classes with the same root super class.

The issue takes place every time I call javax.persistence.Persistence.createEntityManagerFactory
and have the offending @Entity class specified in the persistence unit (or when exclude-unlisted-classes=false).

The issue is...
Caused by: java.lang.IndexOutOfBoundsException: Index: 9, Size: 9
	at java.util.ArrayList.rangeCheck(Unknown Source)
	at java.util.ArrayList.get(Unknown Source)
	at org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAsmFactory.resolveGenericTypes(MetadataAsmFactory.java:151)
	at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor.resolveGenericTypes(ClassAccessor.java:1611)
	at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.discoverMappedSuperclassesAndInheritanceParents(EntityAccessor.java:280)
	at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.preProcess(EntityAccessor.java:514)
	at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage1(MetadataProject.java:1590)
	at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:517)
	at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:526)
	at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1320)
	... 59 more


The code where this takes place looks like:

for (int index = genericTypes.indexOf(parent.getName()) + 1; index < size; index++) {
    String actualTypeArgument = genericTypes.get(index);
    // Ignore extra types on the end of the child, such as
    // interface generics.
    if (parentIndex >= parentGenericTypes.size()) {
        break;
    }
    String variable = parentGenericTypes.get(parentIndex);
    parentIndex = parentIndex + 3;

    // We are building bottom up and need to link up any
    // TypeVariables with the actual class from the originating
    // entity.
    if (actualTypeArgument.length() == 1) {
        index++;
        actualTypeArgument = genericTypes.get(index);
        descriptor.addGenericType(variable, descriptor.getGenericType(actualTypeArgument));
    } else {
        descriptor.addGenericType(variable, actualTypeArgument);
    }
}

Note that the index is incremented (index++) right before the offending call: "genericTypes.get(index)"

Reproducible: Always

Steps to Reproduce:
1. Using gemini.jpa framework....
2. Have an @Entity class with an abstract superclass, where the superclass is non-abstract
3. Request the entityManagerFactory for the persistence unit which contains the class
Comment 1 Nobody - feel free to take it CLA 2011-12-06 16:25:08 EST
Clarification:

2. Have an @Entity class with an abstract superclass, where the superclass is
non-abstract

Should be:

2. Have an @Entity class with an abstract super-class and a non-abstract super-super-class

class Thing;

abstract class VagueThing extends Thing;

@Entity
class SpecificThing extends VagueThing;
Comment 2 Nobody - feel free to take it CLA 2011-12-07 09:17:30 EST
Correction, there are no abstract classes involved; there are Generics however, and combinations of interfaces. Please disregard "Comment 1"; The hierarchy is a real mess.
Let me know if you need more information for issue reproduction.
Comment 3 Michael Keith CLA 2012-03-20 16:49:08 EDT
Hi Darren,

Just getting to this bug now, but I'm afraid I don't quite get what the problem is. Did you end up getting any handle on what the mapping scenario was that caused the exception? It looks like Gemini JPA is nowhere in the stack trace so I'm wondering if this is just an EclipseLink bug. Did you ever try running it outside of OSGi?

Thanks,
-Mike
Comment 4 Michael Keith CLA 2012-03-27 09:42:39 EDT
Closing. No reproduction was submitted, but it appears the problem may have been a mapping scenario in EclipseLink.