persistence@glassfish.java.net

Re: strange side effect of recent change to Persistence.java while using TopLink Essentials

From: Sahoo <sahoo_at_sun.com>
Date: Wed, 25 Jul 2007 20:58:53 +0530

I have now filed 3420 and 3421.

Thanks,
Sahoo

Tom Ware wrote:
> Hi Sahoo,
>
> You are correct, the two provider names are for backwards compatibility.
>
> Do you know if there was a bug entered yet for the issue with
> TempEntityLoader? I was not able to find it by looking at the forum
> post you indicated.
>
> Could you file a bug for the issue below?
>
> Thanks,
> Tom
>
> Sahoo wrote:
>
>> Because of recent change to Persistence.java, where the code has been
>> added to gracefully recover in case a PersistenceProvider.createEMF()
>> throws exception, I am observing a very strange side effect while
>> using TopLink Essentials. The code that was earlier failing with
>> exception /
>> predeploy for PersistenceUnit [em1] failed.
>> Internal Exception: Exception [TOPLINK-30007] (Oracle TopLink
>> Essentials - 2.0 (Build SNAPSHOT (07/17/2007))):
>> oracle.toplink.essentials.exceptions.PersistenceUnitLoadingException
>> Exception Description: An exception was thrown while loading class:
>> example.UserCredential to check whether it implements @Entity,
>> @Embeddable, or @MappedSuperclass./
>> now succeeds.
>>
>> There are three things contributing to this:
>> 1) TopLink Essentials installs two providers, whose functionalities
>> are identical, but names are different (I think it has to do with
>> backward compatibility).
>> 2) There is a bug in JavaSECMPInitializer.TempEntityLoader (discussed
>> in forum [1] recently).
>> 3) TopLink Essentials is not using this TempEntityLoader during so
>> called redeployment (see code below).
>>
>> This is the sequence of events:
>> 1. The bootstrap code in Persistence.java tries the first TopLink
>> provider.
>> 2. A new EntityManagerSetupImpl is created and registered with the
>> global map of name -> EntittyManagerSetupImpl.
>> 3. EntityManagerSetupImpl.predeploy() throws the aforementioned
>> exception. It is set to STATE_PREDEPLOY_FAILED state and the
>> exception is thrown to bootstrap class, which records it.
>> 4. Bootstrap code tries the second TopLink provider.
>> 5. Now TopLink gets hold of the previous EntityManagerSetupImpl, and
>> proceeds with the deployment. This time, predeploy() succeeds because
>> it uses the real ThreadContextClassLoader as the TempClassLoader as
>> shown below:
>> File EntityManagerFactoryProvider.java:
>> if(emSetupImpl.shouldRedeploy()) {
>> SEPersistenceUnitInfo persistenceInfo =
>> (SEPersistenceUnitInfo)emSetupImpl.getPersistenceUnitInfo();
>>
>> persistenceInfo.setClassLoader(JavaSECMPInitializer.getMainLoader());
>>
>> *persistenceInfo.setNewTempClassLoader(JavaSECMPInitializer.getMainLoader());*
>>
>> }
>>
>> I don't think fixing the TempEntityLoader alone is sufficient. Is
>> TopLink correct in calling predeploy() twice, that too with different
>> temporary class loaders? What are its side effects in a production
>> system? Secondly, why is TopLink not matching the provider name in
>> its createEMF() implementation?
>>
>> Thanks,
>> Sahoo
>>
>> [1] http://forums.java.net/jive/thread.jspa?messageID=227934