> On Jun 10, 2015, at 9:23 AM, Volker Simonis <volker.simo...@gmail.com> wrote: > > 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/
ClassLoader.java It should have done that. Nit: Can you move line 1693 to 1868 closer to loadLibrary0 (the caller of findBuiltinLib)? Also make it private. Same applies to jdk9. Otherwise looks good. No need to generate a webrev as long as you make the change before the push. > 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. > Thanks for taking it out. > 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). Yes this is a harder problem that have to investigate further. > > So are you OK now with pushing this change to jdk9 and requesting a > downport to 8u-dev afterwards? > Yes. Approved. Mandy > Thank you and best regards, > Volker > > > On Wed, Jun 10, 2015 at 5:14 PM, Mandy Chung <mandy.ch...@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.simo...@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.ch...@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.ch...@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.simo...@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 >>>>>>>> >>>>>>>> >>>> >>