< prev index next >

src/java.base/share/classes/java/nio/charset/Charset.java

Print this page
rev 12062 : 8081674: EmptyStackException at startup if running with extended or unsupported charset
   1 /*
   2  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 376                     throw new UnsupportedOperationException();
 377                 }
 378 
 379             };
 380     }
 381 
 382     // Thread-local gate to prevent recursive provider lookups
 383     private static ThreadLocal<ThreadLocal<?>> gate =
 384             new ThreadLocal<ThreadLocal<?>>();
 385 
 386     private static Charset lookupViaProviders(final String charsetName) {
 387 
 388         // The runtime startup sequence looks up standard charsets as a
 389         // consequence of the VM's invocation of System.initializeSystemClass
 390         // in order to, e.g., set system properties and encode filenames.  At
 391         // that point the application class loader has not been initialized,
 392         // however, so we can't look for providers because doing so will cause
 393         // that loader to be prematurely initialized with incomplete
 394         // information.
 395         //
 396         if (!sun.misc.VM.isBooted())





 397             return null;
 398 
 399         if (gate.get() != null)
 400             // Avoid recursive provider lookups
 401             return null;
 402         try {
 403             gate.set(gate);
 404 
 405             return AccessController.doPrivileged(
 406                 new PrivilegedAction<>() {
 407                     public Charset run() {
 408                         for (Iterator<CharsetProvider> i = providers();
 409                              i.hasNext();) {
 410                             CharsetProvider cp = i.next();
 411                             Charset cs = cp.charsetForName(charsetName);
 412                             if (cs != null)
 413                                 return cs;
 414                         }
 415                         return null;
 416                     }


 427         // returns ExtendedProvider, if installed
 428         private static CharsetProvider[] extendedProviders() {
 429             return AccessController.doPrivileged(new PrivilegedAction<>() {
 430                     public CharsetProvider[] run() {
 431                         CharsetProvider[] cps = new CharsetProvider[1];
 432                         int n = 0;
 433                         ServiceLoader<CharsetProvider> sl =
 434                             ServiceLoader.loadInstalled(CharsetProvider.class);
 435                         for (CharsetProvider cp : sl) {
 436                             if (n + 1 > cps.length) {
 437                                 cps = Arrays.copyOf(cps, cps.length << 1);
 438                             }
 439                             cps[n++] = cp;
 440                         }
 441                         return n == cps.length ? cps : Arrays.copyOf(cps, n);
 442                     }});
 443         }
 444     }
 445 
 446     private static Charset lookupExtendedCharset(String charsetName) {
 447         if (!sun.misc.VM.isBooted())  // see lookupViaProviders()

 448             return null;
 449         CharsetProvider[] ecps = ExtendedProviderHolder.extendedProviders;

 450         for (CharsetProvider cp : ecps) {
 451             Charset cs = cp.charsetForName(charsetName);
 452             if (cs != null)
 453                 return cs;
 454         }
 455         return null;
 456     }
 457 
 458     private static Charset lookup(String charsetName) {
 459         if (charsetName == null)
 460             throw new IllegalArgumentException("Null charset name");
 461         Object[] a;
 462         if ((a = cache1) != null && charsetName.equals(a[0]))
 463             return (Charset)a[1];
 464         // We expect most programs to use one Charset repeatedly.
 465         // We convey a hint to this effect to the VM by putting the
 466         // level 1 cache miss code in a separate method.
 467         return lookup2(charsetName);
 468     }
 469 


   1 /*
   2  * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 376                     throw new UnsupportedOperationException();
 377                 }
 378 
 379             };
 380     }
 381 
 382     // Thread-local gate to prevent recursive provider lookups
 383     private static ThreadLocal<ThreadLocal<?>> gate =
 384             new ThreadLocal<ThreadLocal<?>>();
 385 
 386     private static Charset lookupViaProviders(final String charsetName) {
 387 
 388         // The runtime startup sequence looks up standard charsets as a
 389         // consequence of the VM's invocation of System.initializeSystemClass
 390         // in order to, e.g., set system properties and encode filenames.  At
 391         // that point the application class loader has not been initialized,
 392         // however, so we can't look for providers because doing so will cause
 393         // that loader to be prematurely initialized with incomplete
 394         // information.
 395         //
 396         // We must also guard against beeing called from the sun.misc.Launcher
 397         // class initializer because in that case the bootstrap URLClassPath in
 398         // the Launcher isn't initialized which is required by the ServiceLoader
 399         // we use.
 400         if (!sun.misc.VM.isBooted() ||
 401             sun.misc.Launcher.getBootstrapClassPath() == null)
 402             return null;
 403 
 404         if (gate.get() != null)
 405             // Avoid recursive provider lookups
 406             return null;
 407         try {
 408             gate.set(gate);
 409 
 410             return AccessController.doPrivileged(
 411                 new PrivilegedAction<>() {
 412                     public Charset run() {
 413                         for (Iterator<CharsetProvider> i = providers();
 414                              i.hasNext();) {
 415                             CharsetProvider cp = i.next();
 416                             Charset cs = cp.charsetForName(charsetName);
 417                             if (cs != null)
 418                                 return cs;
 419                         }
 420                         return null;
 421                     }


 432         // returns ExtendedProvider, if installed
 433         private static CharsetProvider[] extendedProviders() {
 434             return AccessController.doPrivileged(new PrivilegedAction<>() {
 435                     public CharsetProvider[] run() {
 436                         CharsetProvider[] cps = new CharsetProvider[1];
 437                         int n = 0;
 438                         ServiceLoader<CharsetProvider> sl =
 439                             ServiceLoader.loadInstalled(CharsetProvider.class);
 440                         for (CharsetProvider cp : sl) {
 441                             if (n + 1 > cps.length) {
 442                                 cps = Arrays.copyOf(cps, cps.length << 1);
 443                             }
 444                             cps[n++] = cp;
 445                         }
 446                         return n == cps.length ? cps : Arrays.copyOf(cps, n);
 447                     }});
 448         }
 449     }
 450 
 451     private static Charset lookupExtendedCharset(String charsetName) {
 452         if (!sun.misc.VM.isBooted() ||             // see lookupViaProviders()
 453             sun.misc.Launcher.getBootstrapClassPath() == null)
 454             return null;
 455         CharsetProvider[] ecps = ExtendedProviderHolder.extendedProviders;
 456         if (ecps == null) return null; // protect against recursive invocation
 457         for (CharsetProvider cp : ecps) {
 458             Charset cs = cp.charsetForName(charsetName);
 459             if (cs != null)
 460                 return cs;
 461         }
 462         return null;
 463     }
 464 
 465     private static Charset lookup(String charsetName) {
 466         if (charsetName == null)
 467             throw new IllegalArgumentException("Null charset name");
 468         Object[] a;
 469         if ((a = cache1) != null && charsetName.equals(a[0]))
 470             return (Charset)a[1];
 471         // We expect most programs to use one Charset repeatedly.
 472         // We convey a hint to this effect to the VM by putting the
 473         // level 1 cache miss code in a separate method.
 474         return lookup2(charsetName);
 475     }
 476 


< prev index next >