persistence@glassfish.java.net

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

From: Tom Ware <tom.ware_at_oracle.com>
Date: Wed, 25 Jul 2007 10:14:17 -0400

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