persistence@glassfish.java.net

Re: One-to-Many bug

From: Sanjeeb Kumar Sahoo <Sanjeeb.Sahoo_at_Sun.COM>
Date: Mon, 07 Nov 2005 19:02:53 +0530

Hi Tom/Chris,
I have figured out what is causing that failure. TopLink Essentials
calls PersistenceUnitInfo.getTempClassLoader() twice:

public EntityManagerFactory
createContainerEntityManagerFactory(PersistenceUnitInfo info){
EntityManagerSetupImpl emSetupImpl = new EntityManagerSetupImpl();
Collection entities = buildEntityList(info, info.getTempClassLoader());
ClassFileTransformer transformer = emSetupImpl.predeploy(entities,
info.getTempClassLoader(), info);
...
}

When I changed the above TopLink file to call getTempClassLoader() only
once, that validation exception went away. Looks like the contract for
getTempClassLoader() needs to be well defined.

Our container creates a new ClassLoader for each invocation of
getTempClassLoader. This is fine as far as the contract defined in the
javadocs of that API:
/**
* Return a ClassLoader that the provider may use to temporarily load any
* classes, resources, or open URLs. The scope and classpath of this loader
* is exactly the same as that of the loader returned by
* PersistenceInfo.getClassLoader. None of the classes loaded by this class
* loader will be visible to application components.
*
* @return Temporary ClassLoader with same visibility as current loader
*/
public ClassLoader getTempClassLoader();


See the above javadocs is silent about what should happen for multiple
invocations. Where as the earlier javadocs for
InstrumentableClassLoader's copy() method used to say the following:

/**
* Create and return a temporary loader with the same visibility
* as this loader. The temporary loader may be used to load
* resources or any other application classes for the purposes of
* introspecting them for annotations. The persistence provider
* should not maintain any references to the temporary loader,
* or any objects loaded by it.
*
* @return A temporary classloader with the same classpath as this loader
*/
public ClassLoader copy();

The earlier one at least talked about what should happen each time it is
called.

Since container is not allowed to maintain a reference to this class
loader, I think provider should not call getTempClassLoader() multiple
times.

Thanks,
Sahoo

Markus Fuchs wrote:

> Hi Shelly, hi Ken,
>
> Thanks very much for forwarding this information.
>
> Ken,
>
> I see the same behavior when running the Quicklook
> persistence-onetomanyApp.ear:
>
> The class pe.ejb.ejb30.persistence.toplinksample.ejb.OrderEntity is
> loaded twice.
>
> once with a ClassLoader I:
> com.sun.enterprise.util.ConnectorClassLoader @8537
> Parent: com.sun.enterprise.loader.EJBClassLoader @8732
>
> once with a ClassLoader II:
> com.sun.enterprise.util.ConnectorClassLoader @6763
> Parent: com.sun.enterprise.loader.EJBClassLoader @8732
>
> Any idea, why the same class is loader twice by different
> ClassLoaders, each sharing the same ParentClassLoader? The Quicklook
> test can be found
> appserv-tests/sqetests/ejb/ejb30/persistence/onetomany in the
> glassfish repository.
>
> Thanks!
>
> -- markus.
>
>
> Shelly (Donna) McGowan wrote:
>
>>Markus,
>>
>>I'm not sure if your debugging the schema deployment problem exhibited
>>in Deepa's quicklook test or the ManyToOne/OneToMany relationships fail
>>to load or both, but Oracle sent this email on Friday inferring a
>>classloader issue on the ManyToOne/OneToMany issue. Just wanted to make
>>sure you saw this.
>>
>>Shelly
>>
>>
>>
>>Markus Fuchs wrote On 11/04/05 20:13,:
>>
>>
>>>Hi,
>>>
>>>I now can reproduce the problem in my environment and should be able to
>>>find the problem soon. But I have to leave now. I'm planning on updating
>>>y'all Sunday.
>>>
>>>Have a good weekend,
>>>
>>>-- markus.
>>>
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> Subject:
>>> Re: [Issue 66] New - Enterprise archives fail to load if MX1 and 1XM
>>> relationships used in entities within persistence archive
>>> From:
>>> Christopher Delahunt <christopher.delahunt_at_oracle.com>
>>> Date:
>>> Fri, 04 Nov 2005 14:53:04 -0500
>>> To:
>>> persistence_at_glassfish.dev.java.net
>>>
>>> To:
>>> persistence_at_glassfish.dev.java.net
>>> CC:
>>> Peter Krogh <peter.krogh_at_oracle.com>, Shelly.McGowan_at_Sun.COM
>>>
>>>
>>> Hello Sun,
>>>
>>> In tracking down this bug, we have encountered a situation we cannot
>>> explain. In our initialization code we explicitly load all entity
>>> classes with the provided temp loader. When processing Order, the
>>> return type on getLineItem yields a class that was loaded by a
>>> loader that is different than the one provided. This behavior is the
>>> root of the problem, and is occurring since the changes on the 26th.
>>>
>>>
>>> Any insight is appreciated.
>>>
>>>
>>> Best Regards,
>>> Chris
>>>
>>>> -----Original Message-----
>>>> From: Shelly (Donna) McGowan [mailto:Shelly.McGowan_at_Sun.COM]
>>>> Sent: Wednesday, November 02, 2005 4:58 PM
>>>> To: persistence_at_glassfish.dev.java.net
>>>> Subject: Re: [Issue 66] New - Enterprise archives fail to load if MX1
>>>> and 1XM relationships used in entities within persistence archive
>>>>
>>>>
>>>>
>>>>
>>>> This issue is still occurring on the latest Glassfish builds (11/1).
>>>> There is no workaround that I'm aware of that resolves the issue
>>>> except
>>>> to use last week's promoted build (10/26).
>>>>
>>>> If there is a workaround, please reply to this alias.
>>>>
>>>> Shelly
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> smcgowan_at_dev.java.net wrote On 10/30/05 17:01,:
>>>>
>>>>> https://glassfish.dev.java.net/issues/show_bug.cgi?id=66
>>>>> Issue #|66
>>>>> Summary|Enterprise archives fail to load if MX1 and 1XM relati
>>>>> |onships used in entities within persistence archive
>>>>> Component|glassfish
>>>>> Version|9.0pe
>>>>> Platform|Sun
>>>>> OS/Version|Solaris
>>>>> URL|
>>>>> Status|NEW
>>>>> Status whiteboard|
>>>>> Keywords|
>>>>> Resolution|
>>>>> Issue type|DEFECT
>>>>> Priority|P1
>>>>> Subcomponent|entity-persistence
>>>>> Assigned to|mvatkina
>>>>> Reported by|smcgowan
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> ------- Additional comments from smcgowan_at_dev.java.net Sun Oct 30
>>>>> 22:01:42 +0000 2005 -------
>>>>> enterprise archives containing a persistence archive in which the
>>>>> entities have
>>>>> a ManyToOne or OneToMany relationship defined fail to load with a
>>>>> ValidationException as shown below. These mapping of the
>>>>> relationships are
>>>>> correctly defined and have worked till recently (10/27). The verifier
>>>>> highlights the same problem.
>>>>>
>>>>>
>>>>>
>>>>> Exception Description: The attribute [employees] in entity class
>>>>> [class
>>>>> com.sun.ts.tests.ejb30.persistence.query.apitests.Insurance] has
>>>>> a mappedBy value of [insurance] which does not exist in its owning
>>>>> entity class
>>>>> [class com.sun.ts.tests.ejb30.persistence.query.apitests.
>>>>> EmbeddableSuperclass, this is invalid, and your attribute should
>>>>> reference the
>>>>> correct subclass.
>>>>> Local Exception Stack:
>>>>> Exception [TOPLINK-7154] (Oracle TopLink Essentials - 10g release
>>>>> 4 (10.1.4.0.0)
>>>>> (Build 051026Dev)):
>>>>> oracle.toplink.essentials.exceptions.ValidationException
>>>>> Exception Description: The attribute [employees] in entity class
>>>>> [class
>>>>> com.sun.ts.tests.ejb30.persistence.query.apitests.Insurance] has
>>>>> a mappedBy value of [insurance] which does not exist in its owning
>>>>> entity class
>>>>> [class com.sun.ts.tests.ejb30.persistence.query.apitests.
>>>>> EmbeddableSuperclass, this is invalid, and your attribute should
>>>>> reference the
>>>>> correct subclass.
>>>>> at
>>>>> oracle.toplink.essentials.exceptions.ValidationException.noMappedByAttributeFound(ValidationException.java:1019)
>>>>>
>>>>> at
>>>>> oracle.toplink.essentials.internal.annotations.EJBAnnotationsProcessor.getOwnerMapping(EJBAnnotationsProcessor.java:418)
>>>>>
>>>>> at
>>>>> oracle.toplink.essentials.internal.annotations.EJBAnnotationsProcessor.getOwnerMappingForeignKeys(EJBAnnotationsProcessor.java:430)
>>>>>
>>>>> at
>>>>> oracle.toplink.essentials.internal.annotations.EJBAnnotationsProcessor.processOneToMany(EJBAnnotationsProcessor.java:1893)
>>>>>
>>>>> at
>>>>> oracle.toplink.essentials.internal.annotations.EJBAnnotationsProcessor.processRelationshipAccessor(EJBAnnotationsProcessor.java:2236)
>>>>>
>>>>> at
>>>>> oracle.toplink.essentials.internal.annotations.EJBAnnotationsProcessor.processRelatedClass(EJBAnnotationsProcessor.java:2207)
>>>>>
>>>>> at
>>>>> oracle.toplink.essentials.internal.annotations.EJBAnnotationsProcessor.processORAnnotations(EJBAnnotationsProcessor.java:1989)
>>>>>
>>>>> at
>>>>> oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:299)
>>>>>
>>>>> at
>>>>> oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.createContainerEntityManagerFactory(EntityManagerFactoryProvider.java:
>>>>>
>>>>> 104)
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: issues-unsubscribe_at_glassfish.dev.java.net
>>>>> For additional commands, e-mail: issues-help_at_glassfish.dev.java.net
>>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>