persistence@glassfish.java.net

Re: nb issue 119567 and filing gf/toplink issue]

From: Marina Vatkina <Marina.Vatkina_at_Sun.COM>
Date: Wed, 31 Oct 2007 11:18:55 -0700

Hi Sahoo,

I think I read somewhere that URLs can have problems to compare equal and they
shouldn't be used because they were poorly designed.

Tom,

What do you think?

thanks,
-marina

Sahoo wrote:
> With the extra information supplied by Ken in another email, I am able
> to reproduce this bug on my system using a very basic JPA enabled Java
> SE application. The problem is different from the one faced by Bill. It
> is a very interesting issue. Look at the code snippet below and the
> output it produces:
>
> public class MultiByteDirNameTest {
> public static void main(String[] args) throws Exception {
> URL origURL =
> ClassLoader.getSystemResource("MultiByteDirNameTest.class");
> System.out.println("origURL = " + origURL);
> URI origURI = origURL.toURI();
> System.out.println("origURI = " + origURI);
> File f = new File(origURI);
> System.out.println("f = " + f);
> URI newURI = f.toURI();
> System.out.println("newURI = " + newURI);
> URL newURL = newURI.toURL();
> System.out.println("newURL = " + newURL);
> boolean areBothURLsSame = origURL.equals(newURL);
> System.out.println("areBothURLsSame = " + areBothURLsSame);
> boolean areBothURIsSame = origURI.equals(newURI);
> System.out.println("areBothURIsSame = " + areBothURIsSame);
> }
> }
>
> origURL = file:/tmp/%3f%3f%3f%3f/MultiByteDirNameTest.class
> origURI = file:/tmp/%3f%3f%3f%3f/MultiByteDirNameTest.class
> f = /tmp/????/MultiByteDirNameTest.class
> newURI = file:/tmp/%3F%3F%3F%3F/MultiByteDirNameTest.class
> newURL = file:/tmp/%3F%3F%3F%3F/MultiByteDirNameTest.class
> areBothURLsSame = false
> areBothURIsSame = true
>
> --------
>
> Are you surprised to see areBothURLsSame being false, yet
> areBothURIsSame is true? I suspect that is because URL is known not to
> handle special characters well.
>
> JDK team must have good reasons to design these things the way they have
> done it. Even otherwise, it will be extremely difficult to get a fix in
> java.net classes. So, I think this should be handled in our code.
>
> Now why TopLink is failing:
> -------------------------------------
> TopLink creates a emf name using the origURL + puName. Subsequently,
> they try to look up an emf name using newURL + puName assuming that
> origURL and newURL would be same. Since that's not the case, the String
> comparison fails, and the code fails to locate the emf in the global map
> maintained in EntityManagerFactoryProvider.
>
> The Fix:
> -----------
> In EntityManagerFactoryProvider, change
> protected static final HashMap<String, EntityManagerSetupImpl> emSetupImpls
> to
> protected static final HashMap<PUName, EntityManagerSetupImpl>
> emSetupImpls,
> where PUName is defined like this:
> class PUName {
> URI puRootURI; String name;
> @Override public int hashCode() {return
> puRootURI.hashCode()+name.hashCode();}
> @Override public boolean equals(Object other) {
> if (other instanceof PUName) {
> PUName another = PUName.class.cast(other);
> return (another.puRootURI.equals(puRootURI) &&
> another.name.equals(name));
> }
> return false;
> }
> }
>
> The callers have to be changed as well.
> Thanks,
> Sahoo
>
> Sahoo wrote:
>
>> Hi Marina,
>>
>> Without having access to the test case and the full details of the
>> failure, I am inclined to say that this is a different problem from
>> what Bill was facing.
>>
>> Thanks,
>> Sahoo
>>
>> Marina Vatkina wrote:
>>
>>> Hi Sahoo,
>>>
>>> Can it be the same change that caused problems to Bill Shannon (do
>>> you remember that?), cause the multibyte problem?
>>>
>>> thanks,
>>> -marina
>>>
>>> Ken Frank wrote:
>>>
>>>> Here is more specific info on how we call the toplink for the situation
>>>> where it does not work when a dir path has multibyte in it.
>>>>
>>>> I can file an issue; what cat/subcat should be used and what is
>>>> location
>>>> of the bug filing s/w ?
>>>>
>>>> -------------------------------------------------------------
>>>>
>>>> javax.persistence.Persistence.createEntityManagerFactory("samplePU")
>>>> call fails with the following exception
>>>>
>>>> javax.persistence.PersistenceException:
>>>> No Persistence provider for EntityManager named samplePU: The
>>>> following providers:
>>>> oracle.toplink.essentials.PersistenceProvider
>>>> oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
>>>> Returned null to createEntityManagerFactory.
>>>> at
>>>> javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:154)
>>>>
>>>> at
>>>> javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83)
>>>>
>>>> ...
>>>>
>>>> when a standalone (J2SE) application is executed in a directory with
>>>> multibyte characters (both, the application jar file and TopLink
>>>> classes are in such directory). The same application works correctly
>>>> when executed in a directory with ASCII characters only.
>>>>
>>>>
>>>> Thanks - Ken
>>>>
>>