Hi Tom,
I'll forward you Ken's steps. But I don't think it's a NetBeans problem - it had
been reported by the user with multi-byte locale on NetBeans.
Tom Ware wrote:
> Hi Marina and Sahoo,
>
> What do we have to do to reproduce the problem shown in Sahoo's
> recreation. i.e. what are the prerequisites of running that code?
Just have a path with a multi-byte chars in them.
> Where do you put MultiByteDirNameTest.class to get the URL:
> file:/tmp/%3f%3f%3f%3f/MultiByteDirNameTest.class?
On that path.
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
>>>>>>
>>>>