RFR(M): 8081674: EmptyStackException at startup if running with extended or unsupported charset

Volker Simonis volker.simonis at gmail.com
Wed Jun 10 16:23:47 UTC 2015


Hy Mandy,

that's a real good proposal and it only requires changes in the jdk
repository which makes it even more attractive.

I've just checked and it does indeed solve the initial
EmptyStackException problem in both jdk8 and jdk9. Here are the
corresponding webrevs:

http://cr.openjdk.java.net/~simonis/webrevs/2015/8081674.jdk8/
http://cr.openjdk.java.net/~simonis/webrevs/2015/8081674.jdk9/

The only difference between 8 and 9 is the different location of the
source files.
Compared to your proposal I've only updated the copyright years where
necessary and removed one comment in
Java_java_lang_ClassLoader_findBuiltinLib() which seemed unnecessary
to me now that findBuiltinLib() isn't located in NativeLibrary
anymore.

On jdk9 we are now running in another problem which is caused by the
fact that the extended charsets are now being loaded by ServiceLoader
(I've detailed that already in the bug report). But I think we can
leave the fix of that problem to another change as this seems to
require some more reasoning (see Alan's comments in the bug report).

So are you OK now with pushing this change to jdk9 and requesting a
downport to 8u-dev afterwards?

Thank you and best regards,
Volker


On Wed, Jun 10, 2015 at 5:14 PM, Mandy Chung <mandy.chung at oracle.com> wrote:
> Have you checked out this patch moving out findBuiltinLib from NativeLibrary class?
>    http://cr.openjdk.java.net/~mchung/jdk9/webrevs/8081674/webrev.00/
>
> Mandy
>
>> On Jun 10, 2015, at 12:34 AM, Volker Simonis <volker.simonis at gmail.com> wrote:
>>
>> Mandy, the example/stacktrace I sent was with 8u.
>>
>> The problem isn't related to libzip, it is only the first library
>> which gets loaded with System.loadLibrary().
>>
>> The problem will occur with every library which gets loaded by
>> System.loadLibrary() because
>> java.lang.ClassLoader$NativeLibrary.findBuiltinLib() always calls
>> jni_FindClass() if we're running on a unsupported locale.
>>
>> On Tue, Jun 9, 2015 at 8:03 PM, Mandy Chung <mandy.chung at oracle.com> wrote:
>>> Does my patch work fine on 8u?    If it works fine, I prefer to get that
>>> simple fix in 8u and take the time to have a better fix in 9 (jdk9 is still
>>> under development and I have assumed that it's not a show stopper to you.
>>> Let me know if it blocks you).
>>>
>>> A question to Sherman - do we have adequate tests to verify the move of
>>> System.loadLibrary("zip") from system initialization to ZipFile
>>> initialization for 8u?
>>>
>>> Mandy
>>>
>>>
>>> On 06/09/2015 10:09 AM, Volker Simonis wrote:
>>>>
>>>> Hi Mandy,
>>>>
>>>> thanks for looking into this.
>>>> Uunfortunately your fix only helps to fix "java -version" :(
>>>>
>>>> Running even a minimal HelloWorld will still fail with the following
>>>> stack trace which is still caused by the same EmptyStackException:
>>>>
>>>> Error: A JNI error has occurred, please check your installation and try
>>>> again
>>>> Exception in thread "main" java.lang.ExceptionInInitializerError
>>>>     at sun.misc.Unsafe.ensureClassInitialized(Native Method)
>>>>     at
>>>> sun.misc.SharedSecrets.getJavaUtilZipFileAccess(SharedSecrets.java:158)
>>>>     at sun.misc.URLClassPath$JarLoader.<clinit>(URLClassPath.java:765)
>>>>     at sun.misc.URLClassPath$3.run(URLClassPath.java:530)
>>>>     at sun.misc.URLClassPath$3.run(URLClassPath.java:520)
>>>>     at java.security.AccessController.doPrivileged(Native Method)
>>>>     at sun.misc.URLClassPath.getLoader(URLClassPath.java:519)
>>>>     at sun.misc.URLClassPath.getLoader(URLClassPath.java:492)
>>>>     at sun.misc.URLClassPath.getNextLoader(URLClassPath.java:457)
>>>>     at sun.misc.URLClassPath.access$100(URLClassPath.java:64)
>>>>     at sun.misc.URLClassPath$1.next(URLClassPath.java:239)
>>>>     at sun.misc.URLClassPath$1.hasMoreElements(URLClassPath.java:250)
>>>>     at java.net.URLClassLoader$3$1.run(URLClassLoader.java:601)
>>>>     at java.net.URLClassLoader$3$1.run(URLClassLoader.java:599)
>>>>     at java.security.AccessController.doPrivileged(Native Method)
>>>>     at java.net.URLClassLoader$3.next(URLClassLoader.java:598)
>>>>     at java.net.URLClassLoader$3.hasMoreElements(URLClassLoader.java:623)
>>>>     at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
>>>>     at
>>>> sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
>>>>     at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
>>>>     at
>>>> sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
>>>>     at
>>>> java.util.ServiceLoader$LazyIterator.hasNextService(ServiceLoader.java:354)
>>>>     at
>>>> java.util.ServiceLoader$LazyIterator.hasNext(ServiceLoader.java:393)
>>>>     at java.util.ServiceLoader$1.hasNext(ServiceLoader.java:474)
>>>>     at java.nio.charset.Charset$1.getNext(Charset.java:350)
>>>>     at java.nio.charset.Charset$1.hasNext(Charset.java:365)
>>>>     at java.nio.charset.Charset$2.run(Charset.java:410)
>>>>     at java.nio.charset.Charset$2.run(Charset.java:407)
>>>>     at java.security.AccessController.doPrivileged(Native Method)
>>>>     at java.nio.charset.Charset.lookupViaProviders(Charset.java:406)
>>>>     at java.nio.charset.Charset.lookup2(Charset.java:477)
>>>>     at java.nio.charset.Charset.lookup(Charset.java:464)
>>>>     at java.nio.charset.Charset.isSupported(Charset.java:505)
>>>>     at
>>>> sun.launcher.LauncherHelper.makePlatformString(LauncherHelper.java:580)
>>>> Caused by: java.util.EmptyStackException
>>>>     at java.util.Stack.peek(Stack.java:102)
>>>>     at
>>>> java.lang.ClassLoader$NativeLibrary.getFromClass(ClassLoader.java:1759)
>>>>     at java.lang.ClassLoader$NativeLibrary.findBuiltinLib(Native Method)
>>>>     at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1870)
>>>>     at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1843)
>>>>     at java.lang.Runtime.loadLibrary0(Runtime.java:870)
>>>>     at java.lang.System.loadLibrary(System.java:1122)
>>>>     at java.util.zip.ZipFile.<clinit>(ZipFile.java:86)
>>>>     ... 34 more
>>>>
>>>> It's obvious that the way jni_FindClass is looking for the class
>>>> context by calling the NativeLibrary::getFromClass method is hacky but
>>>> I think that the proposed fix is the quite simple and non-intrusive.
>>>> And we probably don't want a complete rework of this code for 8
>>>> anyway. So why not fix it the proposed way in 8 and 9 for now? That
>>>> will still leave us time to come up with a better clean-up at least
>>>> for 9.
>>>>
>>>> What do you think?
>>>>
>>>> Regards,
>>>> Volker
>>>>
>>>> On Tue, Jun 9, 2015 at 1:35 AM, Mandy Chung <mandy.chung at oracle.com>
>>>> wrote:
>>>>>
>>>>> Hi Volker,
>>>>>
>>>>> Your patch reminds me the question I have about loading zip library.
>>>>>
>>>>> In JDK 9 (and earlier release), zip library is loaded by the VM during
>>>>> startup (see ClassLoader::load_zip_library).  I think loadLibrary("zip")
>>>>> is
>>>>> no longer needed to be called from System::initializeSystemClass method
>>>>> and
>>>>> instead it can be loaded by java.util.zip.ZipFile static initializer.
>>>>>
>>>>> Do you mind to try the patch (below)?  That may be a simpler fix.
>>>>>
>>>>> I never like the way jni_FindClass to look for the class context by
>>>>> calling
>>>>> the NativeLibrary::getFromClass method.  I will have to look deeper other
>>>>> alternative to clean that up.  If taking out loadLibrary("zip") resolves
>>>>> your issue, this will give us time to come up with a better clean-up in
>>>>> the
>>>>> future.
>>>>>
>>>>> Mandy
>>>>> [1] https://bugs.openjdk.java.net/browse/JDK-4429040
>>>>>
>>>>> diff --git a/src/share/classes/java/lang/System.java
>>>>> b/src/share/classes/java/lang/System.java
>>>>> --- a/src/share/classes/java/lang/System.java
>>>>> +++ b/src/share/classes/java/lang/System.java
>>>>> @@ -1192,10 +1192,6 @@
>>>>>          setOut0(newPrintStream(fdOut,
>>>>> props.getProperty("sun.stdout.encoding")));
>>>>>          setErr0(newPrintStream(fdErr,
>>>>> props.getProperty("sun.stderr.encoding")));
>>>>>
>>>>> -        // Load the zip library now in order to keep
>>>>> java.util.zip.ZipFile
>>>>> -        // from trying to use itself to load this library later.
>>>>> -        loadLibrary("zip");
>>>>> -
>>>>>          // Setup Java signal handlers for HUP, TERM, and INT (where
>>>>> available).
>>>>>          Terminator.setup();
>>>>>
>>>>> diff --git a/src/share/classes/java/util/zip/ZipFile.java
>>>>> b/src/share/classes/java/util/zip/ZipFile.java
>>>>> --- a/src/share/classes/java/util/zip/ZipFile.java
>>>>> +++ b/src/share/classes/java/util/zip/ZipFile.java
>>>>> @@ -83,6 +83,7 @@
>>>>>
>>>>>      static {
>>>>>          /* Zip library is loaded from System.initializeSystemClass */
>>>>> +        System.loadLibrary("zip");
>>>>>          initIDs();
>>>>>
>>>>>      }
>>>>>
>>>>>
>>>>>
>>>>> On 06/08/2015 07:23 AM, Volker Simonis wrote:
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> can I please get a review at least for the part of this fix which is
>>>>>> common for jdk8 and jdk9. It's only a few lines in
>>>>>> src/share/vm/prims/jni.cpp for the hotspot repository and one line
>>>>>> src/java.base/share/classes/java/lang/ClassLoader.java for the jdk
>>>>>> repository.
>>>>>>
>>>>>> Thanks,
>>>>>> Volker
>>>>>>
>>>>>>
>>>>>> On Tue, Jun 2, 2015 at 6:12 PM, Volker Simonis
>>>>>> <volker.simonis at gmail.com>
>>>>>> wrote:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> can I please have review (and a sponsor) for these changes:
>>>>>>>
>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8081674
>>>>>>> http://cr.openjdk.java.net/~simonis/webrevs/2015/8081674.jdk
>>>>>>> http://cr.openjdk.java.net/~simonis/webrevs/2015/8081674.hs
>>>>>>>
>>>>>>> Please notice that the fix requires synchronous changes in the jdk and
>>>>>>> the
>>>>>>> hotspot forest.
>>>>>>>
>>>>>>> The changes themselves are by far not that big as this explanation but
>>>>>>> I
>>>>>>> found the problem to be quite intricate so I tried to explain it as
>>>>>>> good
>>>>>>> as
>>>>>>> I could. I'd suggest to read the HTML-formatted explanation in the
>>>>>>> webrev
>>>>>>> although the content is equal to the one in this mail:
>>>>>>>
>>>>>>> Using an unsupported character encoding (e.g. vi_VN.TCVN on Linux)
>>>>>>> results
>>>>>>> in an immediate VM failure with jdk 8 and 9:
>>>>>>>
>>>>>>> export LANG=vi_VN.TCVN
>>>>>>> java -version
>>>>>>> Error occurred during initialization of VM
>>>>>>> java.util.EmptyStackException
>>>>>>>         at java.util.Stack.peek(Stack.java:102)
>>>>>>>         at
>>>>>>> java.lang.ClassLoader$NativeLibrary.getFromClass(ClassLoader.java:1751)
>>>>>>>         at java.lang.ClassLoader$NativeLibrary.findBuiltinLib(Native
>>>>>>> Method)
>>>>>>>         at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1862)
>>>>>>>         at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1835)
>>>>>>>         at java.lang.Runtime.loadLibrary0(Runtime.java:870)
>>>>>>>         at java.lang.System.loadLibrary(System.java:1119)
>>>>>>>         at java.lang.System.initializeSystemClass(System.java:1194)
>>>>>>>
>>>>>>> This is a consequence of "8005716: Enhance JNI specification to allow
>>>>>>> support of static JNI libraries in Embedded JREs".
>>>>>>>
>>>>>>> With jdk 9 we get this error even if we're running with a supported
>>>>>>> charset
>>>>>>> which is in the ExtendedCharsets (as opposed to being in the
>>>>>>> StandardCharsets) class which is a consequence of delegating the
>>>>>>> loading
>>>>>>> of
>>>>>>> the ExtendedCharsets class to the ServiceLoader in jdk 9.
>>>>>>>
>>>>>>> export LANG=eo.iso-8859-3
>>>>>>> output-jdk9/images/jdk/bin/java -version
>>>>>>> Error occurred during initialization of VM
>>>>>>> java.util.EmptyStackException
>>>>>>>         at java.util.Stack.peek(Stack.java:102)
>>>>>>>         at
>>>>>>> java.lang.ClassLoader$NativeLibrary.getFromClass(ClassLoader.java:1737)
>>>>>>>         at java.lang.ClassLoader$NativeLibrary.findBuiltinLib(Native
>>>>>>> Method)
>>>>>>>         at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1866)
>>>>>>>         at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1840)
>>>>>>>         at java.lang.Runtime.loadLibrary0(Runtime.java:874)
>>>>>>>         at java.lang.System.loadLibrary(System.java:1111)
>>>>>>>         at java.lang.System.initializeSystemClass(System.java:1186)
>>>>>>>
>>>>>>> Here's why the exception happens for an unsupported charset (see the
>>>>>>> mixed
>>>>>>> stack trace below for the full details):
>>>>>>>
>>>>>>> java.lang.System.loadLibrary() wants to load libzip.so. It calls
>>>>>>> java.lang.Runtime.loadLibrary0() which at the very beginning calls the
>>>>>>> native method ClassLoader$NativeLibrary.findBuiltinLib() which checks
>>>>>>> if
>>>>>>> the
>>>>>>> corresponding library is already statically linked into the VM
>>>>>>> (introduced
>>>>>>> by 8005716).
>>>>>>> Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib(),
>>>>>>> the native implementation of findBuiltinLib() in Classloader.c calls
>>>>>>> GetStringPlatformChars() to convert the library name into the native
>>>>>>> platform encoding. GetStringPlatformChars() calls the helper function
>>>>>>> jnuEncodingSupported() to check if the platform encoding which is
>>>>>>> stored
>>>>>>> in
>>>>>>> the property "sun.jnu.encoding" is supported by Java.
>>>>>>> jnuEncodingSupported()
>>>>>>> is implemented as follows:
>>>>>>>
>>>>>>> static jboolean isJNUEncodingSupported = JNI_FALSE;
>>>>>>> static jboolean jnuEncodingSupported(JNIEnv *env) {
>>>>>>>      jboolean exe;
>>>>>>>      if (isJNUEncodingSupported == JNI_TRUE) {
>>>>>>>          return JNI_TRUE;
>>>>>>>      }
>>>>>>>      isJNUEncodingSupported = (jboolean) JNU_CallStaticMethodByName (
>>>>>>>                                      env, &exe,
>>>>>>>                                      "java/nio/charset/Charset",
>>>>>>>                                      "isSupported",
>>>>>>>                                      "(Ljava/lang/String;)Z",
>>>>>>>                                      jnuEncoding).z;
>>>>>>>      return isJNUEncodingSupported;
>>>>>>> }
>>>>>>>
>>>>>>> Once the function finds that the platform encoding is supported (by
>>>>>>> calling
>>>>>>> java.nio.charset.Charset.isSupported()) it caches this value and always
>>>>>>> returns it on following calls. However if the platform encoding is not
>>>>>>> supported, it ALWAYS calls java.nio.charset.Charset.isSupported() an
>>>>>>> every
>>>>>>> subsequent invocation.
>>>>>>>
>>>>>>> In order to call the Java method Charset.isSupported() (in
>>>>>>> JNU_CallStaticMethodByName() in file jni_util.c), we have to call
>>>>>>> jni_FindClass() to convert the symbolic class name
>>>>>>> "java.nio.charset.Charset" into a class reference.
>>>>>>>
>>>>>>> But unfortunately, jni_FindClass() (from jni.cpp in libjvm.so) has a
>>>>>>> special
>>>>>>> handling if called from java.lang.ClassLoader$NativeLibrary to ensure
>>>>>>> that
>>>>>>> JNI_OnLoad/JNI_OnUnload are executed in the correct class context:
>>>>>>>
>>>>>>>    instanceKlassHandle k (THREAD,
>>>>>>> thread->security_get_caller_class(0));
>>>>>>>    if (k.not_null()) {
>>>>>>>      loader = Handle(THREAD, k->class_loader());
>>>>>>>      // Special handling to make sure JNI_OnLoad and JNI_OnUnload are
>>>>>>> executed
>>>>>>>      // in the correct class context.
>>>>>>>      if (loader.is_null() &&
>>>>>>>          k->name() ==
>>>>>>> vmSymbols::java_lang_ClassLoader_NativeLibrary()) {
>>>>>>>        JavaValue result(T_OBJECT);
>>>>>>>        JavaCalls::call_static(&result, k,
>>>>>>>                                        vmSymbols::getFromClass_name(),
>>>>>>>
>>>>>>> vmSymbols::void_class_signature(),
>>>>>>>                                        thread);
>>>>>>>        if (HAS_PENDING_EXCEPTION) {
>>>>>>>          Handle ex(thread, thread->pending_exception());
>>>>>>>          CLEAR_PENDING_EXCEPTION;
>>>>>>>          THROW_HANDLE_0(ex);
>>>>>>>        }
>>>>>>>
>>>>>>> So if that's the case and jni_FindClass() was reallycalled from
>>>>>>> ClassLoader$NativeLibrary, then jni_FindClass() calles
>>>>>>> ClassLoader$NativeLibrary().getFromClass() to find out the
>>>>>>> corresponding
>>>>>>> context class which is supposed to be saved there in a field of type
>>>>>>> java.util.Stack named "nativeLibraryContext":
>>>>>>>
>>>>>>> // Invoked in the VM to determine the context class in
>>>>>>> // JNI_Load/JNI_Unload
>>>>>>> static Class<?> getFromClass() {
>>>>>>>      return ClassLoader.nativeLibraryContext.peek().fromClass;
>>>>>>> }
>>>>>>>
>>>>>>> Unfortunately, "nativeLibraryContext" doesn't contain any entry at this
>>>>>>> point and the invocation of Stack.peek() will throw the exception shown
>>>>>>> before. In general, the "nativeLibraryContext" stack will be filled
>>>>>>> later
>>>>>>> on
>>>>>>> in Runtime.loadLibrary0() like this:
>>>>>>>
>>>>>>> NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin);
>>>>>>> nativeLibraryContext.push(lib);
>>>>>>> try {
>>>>>>>      lib.load(name, isBuiltin);
>>>>>>> } finally {
>>>>>>>      nativeLibraryContext.pop();
>>>>>>> }
>>>>>>>
>>>>>>> such that it always contains at least one element later when
>>>>>>> jni_FindClass()
>>>>>>> will be invoked.
>>>>>>>
>>>>>>> So in summary, the problem is that the implementors of 8005716 didn't
>>>>>>> took
>>>>>>> into account that calling ClassLoader$NativeLibrary.findBuiltinLib()
>>>>>>> may
>>>>>>> trigger a call to jni_FindClass() if we are running on a system with an
>>>>>>> unsupported character encoding.
>>>>>>>
>>>>>>> I'd suggest the following fix for this problem:
>>>>>>>
>>>>>>> Change ClassLoader$NativeLibrary().getFromClass() to return null if the
>>>>>>> stack is empty instead of throwing an exception:
>>>>>>>
>>>>>>> static Class<?> getFromClass() {
>>>>>>>      return ClassLoader.nativeLibraryContext.empty() ?
>>>>>>>          null : ClassLoader.nativeLibraryContext.peek().fromClass;
>>>>>>> }
>>>>>>>
>>>>>>> Unfortunately this also requires a HotSpot change in jni_FindClass() in
>>>>>>> order to properly handle the new 'null' return value:
>>>>>>>
>>>>>>>    if (k.not_null()) {
>>>>>>>      loader = Handle(THREAD, k->class_loader());
>>>>>>>      // Special handling to make sure JNI_OnLoad and JNI_OnUnload are
>>>>>>> executed
>>>>>>>      // in the correct class context.
>>>>>>>      if (loader.is_null() &&
>>>>>>>          k->name() ==
>>>>>>> vmSymbols::java_lang_ClassLoader_NativeLibrary()) {
>>>>>>>        JavaValue result(T_OBJECT);
>>>>>>>        JavaCalls::call_static(&result, k,
>>>>>>>                                        vmSymbols::getFromClass_name(),
>>>>>>>
>>>>>>> vmSymbols::void_class_signature(),
>>>>>>>                                        thread);
>>>>>>>        if (HAS_PENDING_EXCEPTION) {
>>>>>>>          Handle ex(thread, thread->pending_exception());
>>>>>>>          CLEAR_PENDING_EXCEPTION;
>>>>>>>          THROW_HANDLE_0(ex);
>>>>>>>        }
>>>>>>>        oop mirror = (oop) result.get_jobject();
>>>>>>>        if (oopDesc::is_null(mirror)) {
>>>>>>>          loader = Handle(THREAD,
>>>>>>> SystemDictionary::java_system_loader());
>>>>>>>        } else {
>>>>>>>          loader = Handle(THREAD,
>>>>>>>
>>>>>>>
>>>>>>> InstanceKlass::cast(java_lang_Class::as_Klass(mirror))->class_loader());
>>>>>>>          protection_domain = Handle(THREAD,
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> InstanceKlass::cast(java_lang_Class::as_Klass(mirror))->protection_domain());
>>>>>>>        }
>>>>>>>      }
>>>>>>>    } else {
>>>>>>>      // We call ClassLoader.getSystemClassLoader to obtain the system
>>>>>>> class
>>>>>>> loader.
>>>>>>>      loader = Handle(THREAD, SystemDictionary::java_system_loader());
>>>>>>>    }
>>>>>>>
>>>>>>> These changes are sufficient to solve the problem in Java 8.
>>>>>>> Unfortunately,
>>>>>>> that's still not enough in Java 9 because there the loading of the
>>>>>>> extended
>>>>>>> charsets has been delegated to ServiceLoader. But ServiceLoader calls
>>>>>>> ClassLoader.getBootstrapResources() which calls
>>>>>>> sun.misc.Launcher.getBootstrapClassPath(). This leads to another
>>>>>>> problem
>>>>>>> during class initialization of sun.misc.Launcher if running on an
>>>>>>> unsupported locale.
>>>>>>>
>>>>>>> The first thing done in sun.misc.Launcher.<clinit> is the
>>>>>>> initialisation
>>>>>>> of
>>>>>>> the bootstrap URLClassPath in the Launcher. However this initialisation
>>>>>>> will
>>>>>>> eventually call Charset.isSupported() and if we are running on an
>>>>>>> unsupported locale this will inevitably end in another recursive call
>>>>>>> to
>>>>>>> ServiceLoader. But as explained below, ServiceLoader will query the
>>>>>>> Launcher's bootstrap URLClassPath which will be still uninitialized at
>>>>>>> that
>>>>>>> point.
>>>>>>>
>>>>>>> So we'll have to additionally guard guard against this situation on JDK
>>>>>>> 9
>>>>>>> like this:
>>>>>>>
>>>>>>> private static Charset lookupExtendedCharset(String charsetName) {
>>>>>>>      if (!sun.misc.VM.isBooted() ||             // see
>>>>>>> lookupViaProviders()
>>>>>>>          sun.misc.Launcher.getBootstrapClassPath() == null)
>>>>>>>          return null;
>>>>>>>
>>>>>>> This fixes the crashes, but still at the price of not having the
>>>>>>> extended
>>>>>>> charsets available during initialization until
>>>>>>> Launcher.getBootstrapClassPath is set up properly. This may be still a
>>>>>>> problem if the jdk is installed in a directory which contains
>>>>>>> characters
>>>>>>> specific to an extended encoding or if we have such characters in the
>>>>>>> command line arguments.
>>>>>>>
>>>>>>> Thank you and best regards,
>>>>>>> Volker
>>>>>>>
>>>>>>>
>>>>>>> Mixed stack trace of the initial EmptyStackException for unsupported
>>>>>>> charsets described before:
>>>>>>>
>>>>>>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code,
>>>>>>> C=native
>>>>>>> code)
>>>>>>> j  java.util.Stack.peek()Ljava/lang/Object;+1
>>>>>>> j
>>>>>>> java.lang.ClassLoader$NativeLibrary.getFromClass()Ljava/lang/Class;+3
>>>>>>> v  ~StubRoutines::call_stub
>>>>>>> V  [libjvm.so+0x9d279a]  JavaCalls::call_helper(JavaValue*,
>>>>>>> methodHandle*,
>>>>>>> JavaCallArguments*, Thread*)+0x6b4
>>>>>>> V  [libjvm.so+0xcad591]  os::os_exception_wrapper(void (*)(JavaValue*,
>>>>>>> methodHandle*, JavaCallArguments*, Thread*), JavaValue*, methodHandle*,
>>>>>>> JavaCallArguments*, Thread*)+0x45
>>>>>>> V  [libjvm.so+0x9d20cf]  JavaCalls::call(JavaValue*, methodHandle,
>>>>>>> JavaCallArguments*, Thread*)+0x8b
>>>>>>> V  [libjvm.so+0x9d1d3b]  JavaCalls::call_static(JavaValue*,
>>>>>>> KlassHandle,
>>>>>>> Symbol*, Symbol*, JavaCallArguments*, Thread*)+0x139
>>>>>>> V  [libjvm.so+0x9d1e3f]  JavaCalls::call_static(JavaValue*,
>>>>>>> KlassHandle,
>>>>>>> Symbol*, Symbol*, Thread*)+0x9d
>>>>>>> V  [libjvm.so+0x9e6588]  jni_FindClass+0x428
>>>>>>> C  [libjava.so+0x20208]  JNU_CallStaticMethodByName+0xff
>>>>>>> C  [libjava.so+0x21cae]  jnuEncodingSupported+0x61
>>>>>>> C  [libjava.so+0x22125]  JNU_GetStringPlatformChars+0x125
>>>>>>> C  [libjava.so+0xedcd]
>>>>>>> Java_java_lang_ClassLoader_00024NativeLibrary_findBuiltinLib+0x8b
>>>>>>> j
>>>>>>>
>>>>>>>
>>>>>>> java.lang.ClassLoader$NativeLibrary.findBuiltinLib(Ljava/lang/String;)Ljava/lang/String;+0
>>>>>>> j
>>>>>>> java.lang.ClassLoader.loadLibrary0(Ljava/lang/Class;Ljava/io/File;)Z+4
>>>>>>> j
>>>>>>>
>>>>>>>
>>>>>>> java.lang.ClassLoader.loadLibrary(Ljava/lang/Class;Ljava/lang/String;Z)V+228
>>>>>>> j
>>>>>>> java.lang.Runtime.loadLibrary0(Ljava/lang/Class;Ljava/lang/String;)V+54
>>>>>>> j  java.lang.System.loadLibrary(Ljava/lang/String;)V+7
>>>>>>> j  java.lang.System.initializeSystemClass()V+113
>>>>>>> v  ~StubRoutines::call_stub
>>>>>>> V  [libjvm.so+0x9d279a]  JavaCalls::call_helper(JavaValue*,
>>>>>>> methodHandle*,
>>>>>>> JavaCallArguments*, Thread*)+0x6b4
>>>>>>> V  [libjvm.so+0xcad591]  os::os_exception_wrapper(void (*)(JavaValue*,
>>>>>>> methodHandle*, JavaCallArguments*, Thread*), JavaValue*, methodHandle*,
>>>>>>> JavaCallArguments*, Thread*)+0x45
>>>>>>> V  [libjvm.so+0x9d20cf]  JavaCalls::call(JavaValue*, methodHandle,
>>>>>>> JavaCallArguments*, Thread*)+0x8b
>>>>>>> V  [libjvm.so+0x9d1d3b]  JavaCalls::call_static(JavaValue*,
>>>>>>> KlassHandle,
>>>>>>> Symbol*, Symbol*, JavaCallArguments*, Thread*)+0x139
>>>>>>> V  [libjvm.so+0x9d1e3f]  JavaCalls::call_static(JavaValue*,
>>>>>>> KlassHandle,
>>>>>>> Symbol*, Symbol*, Thread*)+0x9d
>>>>>>> V  [libjvm.so+0xe3cceb]  call_initializeSystemClass(Thread*)+0xb0
>>>>>>> V  [libjvm.so+0xe44444]
>>>>>>> Threads::initialize_java_lang_classes(JavaThread*,
>>>>>>> Thread*)+0x21a
>>>>>>> V  [libjvm.so+0xe44b12]  Threads::create_vm(JavaVMInitArgs*,
>>>>>>> bool*)+0x4a6
>>>>>>> V  [libjvm.so+0xa19bd7]  JNI_CreateJavaVM+0xc7
>>>>>>> C  [libjli.so+0xa520]  InitializeJVM+0x154
>>>>>>> C  [libjli.so+0x8024]  JavaMain+0xcc
>>>>>>>
>>>>>>>
>>>
>


More information about the hotspot-dev mailing list