harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Deven You <devyo...@gmail.com>
Subject Re: [classlib][luni] String.toLowerCase/toUpperCase incorrect for supplementary characters (HARMONY-6649)
Date Fri, 24 Sep 2010 16:08:47 GMT
It is a bit complex. First of all, I meet this problem because when I run
specjbb benchmark, at the during of vm startup, it returned just the same
error mentioned by Mohan.

Then I used java -verbose to show the boot classes load order, compared to
harmony build between before this commit and after this commit and saw:
before this commit, Locale is first loaded, and then ULocale loaded
after this commit, ULocale is first loaded, and then Locale is loaded. this
build will return the above NPE error.

Then I went on to check why with this commit, Locale won't be loaded before
ULocale, I found before this commit,at the vm start up, CharsetProviderImpl
will be invoked, it will invoke String.toUpperCase() which in turn invoke
String.toUpperCase(Locale.getDefault()), at this point, Locale class will be
loaded, and also at this point, there is no class used ULoclae yet, so
ULocale is not loadede yet. And again at this point, Locale class will
invoke ULocale class, so sequentially ULocale will be used thus loaded
during Locale class init.

After with this commit, now CharsetPorviderImple will invoke its own
toUpperCase() method which dose not depend on Locale class any longer, so at
the point CharsetProviderImple is invoked, it dose not need Locale, so
Locale class won't be loaded at this point. Later for some reason, maybe
other class need ULoclae, so ULocale is loaded. Again at that point, Locale
class is still not loaded. With this condition, ULocale will invoke Locale
methods, so Locale class will be loaded during ULocale class init. This
cause Locale class is loaded after ULocale class.

Unfortunately, Current ULocale class will meet NPE  exception with above
situation: Locale class is loaded after ULocale class. The root cause is
that:
ULocale class init will initialize below static field:
public static final ULocale ENGLISH = new ULocale("en", Locale.ENGLISH);
This cause Locale will be loaded, during Locale class init, below static
field will be initialized:
    public static final Locale CANADA = new Locale("en", "CA");
new Locale("en", "CA"); will finally calls new ULocale(language, country,
variant) and which will invoke getName(String localeID) and which will
execute:
       String name = nameCache.get(localeID), here, nameCache is a static
field of ULocale, from above call sequence, we can see the ULocale class
 just execute to initialize new ULocale("en", Locale.ENGLISH). It have no
chance to initialze nameCache yet, so at this point, the java will throw NPE
exception.

If Locale is loaded before ULocale, from Locale initialization process, the
code logic and interaction mechanism between Locale and ULocale just by
chance can avoid such situation and execute successfully.

I am not sure this is enough for you. Any unclear things please point out to
me. Thanks a lot!





  From current Local and ULocale code logic. Locale class initialization
process will call ULocale, it cause ULocal class init.

2010/9/24 Tim Ellison <t.p.ellison@gmail.com>

> On 24/Sep/2010 08:17, Deven You wrote:
> > I have saw the error before, and I have some investigation of it. I think
> > the root cause is the commit change the class load order. Before this
> > commit, Locale class will be loaded before ULocale class And after this
> > commit, ULocale is loaded before Locale.
>
> I'm not near the code right now so can you explain this to me please?
> IIRC the Locale and ULocale are mutually dependent so will be loaded
> together anyway. There is an 'early' initialization in Locale to set up
> the US-en values for booting.
>
> So my question is where is the reference to ULocale being made earlier
> now? and how did this change the behavior as it existed before.
>
> Regards,
> Tim
>
> > The direct cause is CharsetProviderImpl no longer use String.toUpperCase,
> > instead it uses its own toUpperCase.  And String.toUpperCase calls
> > String.toUpperCase(Locale), this ensure Locale class will be loaded
> before
> > ULocale. However CharsetProviderImpl own toUpperCase uses no Locale, so
> it
> > causes Locale class loaded after ULocale.
> >
> > To solve this problem, a work around could simply be below:
> > 1.Add a Locale static field in String:
> > private static Locale defaulLocale = new Locale.getDefaultLocale();
> > ...
> > 2. Change the String.toUpperCase() from calling
> > toUpperCase(Locale.getDefaultLocale()) to toUpperCase(defaultLocale)
> >
> > above change could solve the NullPointerException mentioned by Mohan, but
> I
> > am not sure if it is a good design.
> >
> > Caused by: java.lang.NullPointerException
> >        at com.ibm.icu.util.ULocale.getName(ULocale.java:827)
> >        at com.ibm.icu.util.ULocale.<init>(ULocale.java:480)
> >        at java.util.Locale.<init>(Locale.java:228)
> >        at java.util.Locale.<init>(Locale.java:201)
> >        at java.util.Locale.<clinit>(Locale.java:51)
> >        at com.ibm.icu.util.ULocale.<clinit>(ULocale.java:109)
> >
> >
> >
> >
> >
> > 2010/9/24 Mohanraj Loganathan <mohanraj.l@gmail.com>
> >
> >> On loading junit.jar[2] i get initialization exception[3]. This
> >> exception disappears if i revert the patch committed for
> >> (HARMONY-6649) toUpper/toLowerCase.
> >>
> >> Make sure your junit.jar contains the signature files[1]. (use the
> >> junit.jar(version 3.8.2) bundled with eclipse).  So with HARMONY-6649
> >> commit, I am not able to load the jar file if it's manifest contains
> >> any signature related files. Any thought on this?
> >>
> >>
> >> [1] jar -tvf junit.jar
> >>  9714 Thu Aug 07 12:04:14 GMT+05:30 2008 META-INF/MANIFEST.MF
> >>  9791 Thu Aug 07 12:04:14 GMT+05:30 2008 META-INF/ECLIPSE.SF
> >>  3487 Thu Aug 07 12:04:14 GMT+05:30 2008 META-INF/ECLIPSE.RSA
> >>     0 Fri Mar 03 15:22:26 GMT+05:30 2006 META-INF/
> >>    76 Thu Aug 07 12:04:08 GMT+05:30 2008 META-INF/eclipse.inf
> >>     0 Fri Mar 03 15:22:10 GMT+05:30 2006 junit/
> >>     0 Fri Mar 03 15:22:26 GMT+05:30 2006 junit3.8.2/
> >>     0 Fri Mar 03 15:22:24 GMT+05:30 2006 junit/awtui/
> >>      ............
> >>
> >> [2] run command : java -cp junit.jar junit.textui.TestRunner
> >>
> >> [3] Exception:
> >> Uncaught exception in main:
> >> java.lang.ExceptionInInitializerError
> >>        at com.ibm.icu.util.ULocale.<clinit>(ULocale.java:109)
> >>        at
> >> com.ibm.icu.impl.ICUResourceBundle.instantiateBundle(ICUResourceBundl
> >> e.java:810)
> >>        at
> >> com.ibm.icu.impl.ICUResourceBundle.getBundleInstance(ICUResourceBundl
> >> e.java:801)
> >>        at
> >> com.ibm.icu.util.UResourceBundle.getRootType(UResourceBundle.java:489
> >> )
> >>        at
> >> com.ibm.icu.util.UResourceBundle.instantiateBundle(UResourceBundle.ja
> >> va:536)
> >>        at
> >> com.ibm.icu.util.UResourceBundle.getBundleInstance(UResourceBundle.ja
> >> va:144)
> >>        at
> >> com.ibm.icu.util.UResourceBundle.getBundleInstance(UResourceBundle.ja
> >> va:124)
> >>        at com.ibm.icu.impl.ZoneMeta.getSystemTimeZone(ZoneMeta.java:509)
> >>        at com.ibm.icu.util.TimeZone.getTimeZone(TimeZone.java:617)
> >>        at com.ibm.icu.util.TimeZone.getTimeZone(TimeZone.java:587)
> >>        at java.util.SimpleTimeZone$1.run(SimpleTimeZone.java:50)
> >>        at java.util.SimpleTimeZone$1.run(SimpleTimeZone.java:1)
> >>        at
> >> java.security.AccessController.doPrivilegedImpl(AccessController.java
> >> :171)
> >>        at
> >> java.security.AccessController.doPrivileged(AccessController.java:53)
> >>
> >>        at
> java.util.SimpleTimeZone.getICUTimeZone(SimpleTimeZone.java:48)
> >>        at java.util.SimpleTimeZone.<init>(SimpleTimeZone.java:110)
> >>        at java.util.TimeZone.<clinit>(TimeZone.java:91)
> >>        at
> >> org.apache.harmony.security.asn1.ASN1Time.getDecodedObject(ASN1Time.j
> >> ava:51)
> >>        at
> >> org.apache.harmony.security.asn1.ASN1UTCTime.decode(ASN1UTCTime.java:
> >> 96)
> >>        at
> >> org.apache.harmony.security.asn1.ASN1Choice.decode(ASN1Choice.java:32
> >> 0)
> >>        at
> >> org.apache.harmony.security.asn1.BerInputStream.readSequence(BerInput
> >> Stream.java:665)
> >>        at
> >> org.apache.harmony.security.asn1.DerInputStream.readSequence(DerInput
> >> Stream.java:125)
> >>        at
> >> org.apache.harmony.security.asn1.ASN1Sequence.decode(ASN1Sequence.jav
> >> a:48)
> >>        at
> >> org.apache.harmony.security.asn1.BerInputStream.readSequence(BerInput
> >> Stream.java:665)
> >>        at
> >> org.apache.harmony.security.asn1.DerInputStream.readSequence(DerInput
> >> Stream.java:125)
> >>        at
> >> org.apache.harmony.security.asn1.ASN1Sequence.decode(ASN1Sequence.jav
> >> a:48)
> >>        at
> >> org.apache.harmony.security.asn1.BerInputStream.readSequence(BerInput
> >> Stream.java:665)
> >>        at
> >> org.apache.harmony.security.asn1.DerInputStream.readSequence(DerInput
> >> Stream.java:125)
> >>        at
> >> org.apache.harmony.security.asn1.ASN1Sequence.decode(ASN1Sequence.jav
> >> a:48)
> >>        at
> >> org.apache.harmony.security.asn1.BerInputStream.decodeValueCollection
> >> (BerInputStream.java:755)
> >>        at
> >> org.apache.harmony.security.asn1.BerInputStream.readSetOf(BerInputStr
> >> eam.java:733)
> >>        at
> >> org.apache.harmony.security.asn1.DerInputStream.readSetOf(DerInputStr
> >> eam.java:138)
> >>        at
> >> org.apache.harmony.security.asn1.ASN1SetOf.decode(ASN1SetOf.java:48)
> >>        at
> >> org.apache.harmony.security.asn1.ASN1Implicit.decode(ASN1Implicit.jav
> >> a:140)
> >>        at
> >> org.apache.harmony.security.asn1.BerInputStream.readSequence(BerInput
> >> Stream.java:665)
> >>        at
> >> org.apache.harmony.security.asn1.DerInputStream.readSequence(DerInput
> >> Stream.java:125)
> >>        at
> >> org.apache.harmony.security.asn1.ASN1Sequence.decode(ASN1Sequence.jav
> >> a:48)
> >>        at
> >> org.apache.harmony.security.asn1.ASN1Type.decode(ASN1Type.java:97)
> >>        at
> >> org.apache.harmony.security.pkcs7.ContentInfo$1.getDecodedObject(Cont
> >> entInfo.java:153)
> >>        at
> >> org.apache.harmony.security.asn1.ASN1Sequence.decode(ASN1Sequence.jav
> >> a:53)
> >>        at
> >> org.apache.harmony.security.utils.JarUtils.verifySignature(JarUtils.j
> >> ava:73)
> >>        at
> java.util.jar.JarVerifier.verifyCertificate(JarVerifier.java:296)
> >>        at
> java.util.jar.JarVerifier.readCertificates(JarVerifier.java:265)
> >>        at java.util.jar.JarFile.getInputStream(JarFile.java:392)
> >>        at
> >> java.net.URLClassLoader$URLJarHandler.createClass(URLClassLoader.java
> >> :402)
> >>        at
> >> java.net.URLClassLoader$URLJarHandler.findClass(URLClassLoader.java:3
> >> 71)
> >>        at
> java.net.URLClassLoader.findClassImpl(URLClassLoader.java:1209)
> >>        at java.net.URLClassLoader$4.run(URLClassLoader.java:901)
> >>        at java.net.URLClassLoader$4.run(URLClassLoader.java:1)
> >>        at
> >> java.security.AccessController.doPrivilegedImpl(AccessController.java
> >> :171)
> >>        at
> >> java.security.AccessController.doPrivileged(AccessController.java:64)
> >>
> >>        at java.net.URLClassLoader.findClass(URLClassLoader.java:903)
> >>        at java.lang.ClassLoader.loadClass(ClassLoader.java:488)
> >>        at
> >> java.lang.ClassLoader$SystemClassLoader.loadClass(ClassLoader.java:87
> >> 0)
> >>        at java.lang.ClassLoader.loadClass(ClassLoader.java:267)
> >> Caused by: java.lang.NullPointerException
> >>        at com.ibm.icu.util.ULocale.getName(ULocale.java:827)
> >>        at com.ibm.icu.util.ULocale.<init>(ULocale.java:480)
> >>        at java.util.Locale.<init>(Locale.java:228)
> >>        at java.util.Locale.<init>(Locale.java:201)
> >>        at java.util.Locale.<clinit>(Locale.java:51)
> >>        at com.ibm.icu.util.ULocale.<clinit>(ULocale.java:109)
> >>        ... 54 more
> >> FAILED to invoke JVM.
> >>
> >>
> >>
> >>
> >>
> >>
> >> On Fri, Sep 24, 2010 at 11:57 AM, Tim Ellison <t.p.ellison@gmail.com>
> >> wrote:
> >>> On 24/Sep/2010 06:58, Robert Muir wrote:
> >>>> On Fri, Sep 24, 2010 at 1:49 AM, Tim Ellison <t.p.ellison@gmail.com>
> >> wrote:
> >>>>> System.out.println(new File("σ.txt").hashCode());
> >>>>> System.out.println(new File("ς.txt").hashCode());
> >>>>>
> >>>>> prints out
> >>>>>
> >>>>> 889962580
> >>>>> 890776533
> >>>>>
> >>>>> on both Harmony and the RI.
> >>>>>
> >>>>>
> >>>> but perhaps this is just a bug in the RI?
> >>>> according to the link:
> >>>>
> >>
> http://download.oracle.com/javase/6/docs/api/java/io/File.html#hashCode%28%29
> >>>> <
> >>
> http://download.oracle.com/javase/6/docs/api/java/io/File.html#hashCode%28%29
> >>> Because
> >>>> equality of abstract pathnames is inherently system-dependent, so is
> the
> >>>> computation of their hash codes.
> >>>>
> >>>> Is it a problem that "windows equals" is inconsistent with hashCode
> >> here? I
> >>>> admit these are corner cases.
> >>> No, I don't think it is a problem.  I was reviewing the invokers of
> >>> toLowerCase() and was confused by the wording in the spec.  I'm happy
> >>> that we should simply lowercase it in a locale independent way, and
> >>> don't need to do a "windows equals" implementation.
> >>>
> >>> Regards,
> >>> Tim
> >>>
> >>
> >>
> >> --
> >> Mohan
> >>
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message