On Wednesday, June 10, 2015, Mandy Chung <mandy.ch...@oracle.com> wrote:
> > > On Jun 10, 2015, at 9:23 AM, Volker Simonis <volker.simo...@gmail.com > <javascript:;>> 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. > > Sure, I'll do that. Otherwise looks good. No need to generate a webrev as long as you make the > change before the push. > > Thanks for the review! Regards, Volker > > 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 > <javascript:;>> 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 > <javascript:;>> 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 > <javascript:;>> 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 > <javascript:;>> > >>>>> 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 <javascript:;>> > >>>>>>> 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 > >>>>>>>> > >>>>>>>> > >>>> > >> > >