persistence@glassfish.java.net

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

From: Tom Ware <tom.ware_at_oracle.com>
Date: Thu, 01 Nov 2007 13:04:52 -0400

Hi Marina,

  One question

<snip>

>
>> Where do you put MultiByteDirNameTest.class to get the URL:
>> file:/tmp/%3f%3f%3f%3f/MultiByteDirNameTest.class?
>
>
> On that path.


What character is the %3f? It looks like we interpret "tmp" ok. What
causes the special characters.

-Tom

>
> How specific is this
>
>> problem to NetBeans? (i.e. is it more of a problem because of where
>> NetBeans tends to put things?
>
>
> NetBeans put things where you ask it to. I think it defaults to your
> home dir.
>
> thanks,
> -marina
>
>>
>> -Tom
>>
>> Marina Vatkina wrote:
>>
>>> 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
>>>>>>>
>>>>>