Hi again, I experimented some more and I think this:
https://github.com/matthiasblaesing/reproduce-openjfx-crash2 shows, that the problem also exists when used from named modules. The above sample can be run by: - clone the referenced sources - build the project with "mvn package" - run it with mvn -Dexec.args="-classpath %classpath eu.doppel_helix.dev.jdk.reproducecrash.TestBrowser" -Dexec.executable=java org.codehaus.mojo:exec-maven-plugin:3.0.0:exec I get an instant segfault on Ubuntu with OpenJDK 11.0.9. >From my interpretation this is caused by the behaviour of FindClass. Quote from the docs of JDK 11: ====================================================================== Since JDK 1.2, the Java security model allows non-system classes to load and call native methods. FindClass locates the class loader associated with the current native method; that is, the class loader of the class that declared the native method. If the native method belongs to a system class, no class loader will be involved. Otherwise, the proper class loader will be invoked to load and link the named class. Since JDK 1.2, when FindClass is called through the Invocation Interface, there is no current native method or its associated class loader. In that case, the result of ClassLoader.getSystemClassLoader is used. This is the class loader the virtual machine creates for applications, and is able to locate classes listed in the java.class.path property. ====================================================================== My take on this is, that in the common case OpenJFX hits the first assumption. Classes are loaded with the classloader of the native method, which should be able to load the necessary classes. In the case where Webkit calls back into the JVM, the second paragraph becomes important. OpenJFX is not loaded from the system class loader and loading of MainThread class fails. Based on this and my observation that isMainThread is successfully called multiple time before the crash, I added this hack to the last tag of OpenJFX 13 and rebuild: --- a/modules/javafx.web/src/main/native/Source/WTF/wtf/java/MainThreadJava.cpp +++ b/modules/javafx.web/src/main/native/Source/WTF/wtf/java/MainThreadJava.cpp @@ -30,20 +30,21 @@ #include <wtf/MainThread.h> namespace WTF { +static JGClass jMainThreadCls2; + void scheduleDispatchFunctionsOnMainThread() { AttachThreadAsNonDaemonToJavaEnv autoAttach; JNIEnv* env = autoAttach.env(); - static JGClass jMainThreadCls(env->FindClass("com/sun/webkit/MainThread")); static jmethodID mid = env->GetStaticMethodID( - jMainThreadCls, + jMainThreadCls2, "fwkScheduleDispatchFunctions", "()V"); ASSERT(mid); - env->CallStaticVoidMethod(jMainThreadCls, mid); + env->CallStaticVoidMethod(jMainThreadCls2, mid); WTF::CheckAndClearException(env); } @@ -61,7 +62,7 @@ AttachThreadAsNonDaemonToJavaEnv autoAttach; JNIEnv* env = autoAttach.env(); static JGClass jMainThreadCls(env->FindClass("com/sun/webkit/MainThread")); - + jMainThreadCls2 = jMainThreadCls; static jmethodID mid = env->GetStaticMethodID( jMainThreadCls, "fwkIsMainThread", The idea is, that I retain the reference to the class and use that in scheduleDispatchFunctionsOnMainThread. I'm sure, that that is not the right approach, but it works and proves, that the class is accessible. Greetings Matthias Am Samstag, den 21.11.2020, 22:42 +0100 schrieb Matthias Bläsing: Hi, I found JDK-8242361, because I observed a segfault when running a web application of medium complexity in a WebView, that was embedded in NetBeans. Before you say it: NetBeans loads the openjfx jars via the classpath. I'm aware that OpenJFX should be loaded as a named module, but that is far from trivial to realize inside the environment, so at this point in time I'd like to try to fix the problem at hand. I managed to get a core dump from the crash and running it through gdb with debug symbols I get: ============================================================ #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:49 #1 0x00007f93c40e5864 in __GI_abort () at abort.c:79 #2 0x00007f93c30603e7 in os::abort(bool, void*, void const*) (dump_core=<optimized out>, siginfo=<optimized out>, context=<optimized out>) at ./src/hotspot/os/linux/os_linux.cpp:1503 #3 0x00007f93c3c58798 in VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long) (id=<optimized out>, message=message@entry=0x0, detail_fmt=<optimized out>, detail_args=detail_args@entry=0x7f9189ffe368, thread=thread@entry=0x7f925c314000, pc=pc@entry=0x7f93c3348804 <AccessInternal::PostRuntimeDispatch<G1BarrierSet::AccessBarrier<109784 4ul, G1BarrierSet>, (AccessInternal::BarrierType)2, 1097844ul>::oop_access_barrier(void*)+4> "H\213\a\303\017\037\204", siginfo=0x7f9189ffe6f0, context=0x7f9189ffe5c0, filename=<optimized out>, lineno=0, size=0) at ./src/hotspot/share/utilities/vmError.cpp:1603 #4 0x00007f93c3c590cf in VMError::report_and_die(Thread*, unsigned int, unsigned char*, void*, void*, char const*, ...) (thread=thread@entry=0x7f925c314000, sig=sig@entry=11, pc=pc@entry=0x7f93c3348804 <AccessInternal::PostRuntimeDispatch<G1BarrierSet::AccessBarrier<109784 4ul, G1BarrierSet>, (AccessInternal::BarrierType)2, 1097844ul>::oop_access_barrier(void*)+4> "H\213\a\303\017\037\204", siginfo=siginfo@entry=0x7f9189ffe6f0, context=context@entry=0x7f9189ffe5c0, detail_fmt=detail_fmt@entry=0x7f93c3d1348e "%s") at ./src/hotspot/share/utilities/vmError.cpp:1270 #5 0x00007f93c3c59102 in VMError::report_and_die(Thread*, unsigned int, unsigned char*, void*, void*) (thread=thread@entry=0x7f925c314000, sig=sig@entry=11, pc=pc@entry=0x7f93c3348804 <AccessInternal::PostRuntimeDispatch<G1BarrierSet::AccessBarrier<109784 4ul, G1BarrierSet>, (AccessInternal::BarrierType)2, 1097844ul>::oop_access_barrier(void*)+4> "H\213\a\303\017\037\204", siginfo=siginfo@entry=0x7f9189ffe6f0, context=context@entry=0x7f9189ffe5c0) at ./src/hotspot/share/utilities/vmError.cpp:1276 #6 0x00007f93c39b0d02 in JVM_handle_linux_signal(int, siginfo_t*, void*, int) (sig=sig@entry=11, info=info@entry=0x7f9189ffe6f0, ucVoid=ucVoid@entry=0x7f9189ffe5c0, abort_if_unrecognized=abort_if_unrecognized@entry=1) at ./src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp:616 #7 0x00007f93c39a3fdc in signalHandler(int, siginfo_t*, void*) (sig=11, info=0x7f9189ffe6f0, uc=0x7f9189ffe5c0) at ./src/hotspot/os/linux/os_linux.cpp:4693 #8 0x00007f93c4100950 in <signal handler called> () at /lib/x86_64- linux-gnu/libc.so.6 #9 AccessInternal::PostRuntimeDispatch<G1BarrierSet::AccessBarrier<1097844 ul, G1BarrierSet>, (AccessInternal::BarrierType)2, 1097844ul>::oop_access_barrier(void*) (addr=0x0) at ./src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp:66 #10 0x00007f93c36b0073 in AccessInternal::RuntimeDispatch<1097812ul, oopDesc*, (AccessInternal::BarrierType)2>::load(void*) (addr=0x7f91cd491060) at ./src/hotspot/share/oops/accessBackend.hpp:1325 #11 AccessInternal::PreRuntimeDispatch::load<1097812ul, oopDesc*>(void*) (addr=0x7f91cd491060) at ./src/hotspot/share/oops/accessBackend.hpp:779 #12 AccessInternal::load_reduce_types<1097812ul, oopDesc*>(oopDesc**) (addr=0x7f91cd491060) at ./src/hotspot/share/oops/accessBackend.hpp:1110 #13 AccessInternal::load<1048580ul, oopDesc*, oopDesc*>(oopDesc**) (addr=0x7f91cd491060) at ./src/hotspot/share/oops/accessBackend.hpp:1211 #14 AccessInternal::OopLoadProxy<oopDesc*, 1048576ul>::operator oopDesc*() (this=<optimized out>) at ./src/hotspot/share/oops/accessBackend.hpp:1326 #15 JNIHandles::resolve_impl<0ul, false>(_jobject*) (handle=0x7f91cd491060) at ./src/hotspot/share/runtime/jniHandles.inline.hpp:60 #16 JNIHandles::resolve_non_null(_jobject*) (handle=0x7f91cd491060) at ./src/hotspot/share/runtime/jniHandles.inline.hpp:92 #17 get_method_id(jclass, char const*, char const*, bool, Thread*, JNIEnv*) (clazz=clazz@entry=0x0, name_str=name_str@entry=0x7f915c3d3e8a "fwkScheduleDispatchFunctions", sig=sig@entry=0x7f915c396304 "()V", is_static=is_static@entry=true, __the_thread__=__the_thread__@entry=0x7f925c314000, env=<optimized out>) at ./src/hotspot/share/prims/jni.cpp:1336 #18 0x00007f93c36b040b in jni_GetStaticMethodID(JNIEnv*, jclass, char const*, char const*) (env=<optimized out>, clazz=0x0, name=0x7f915c3d3e8a "fwkScheduleDispatchFunctions", sig=0x7f915c396304 "()V") at ./src/hotspot/share/prims/jni.cpp:1382 #19 0x00007f915c0869e6 in WTF::scheduleDispatchFunctionsOnMainThread() () at /home/matthias/.openjfx/cache/13/libjfxwebkit.so #20 0x00007f915b2a745b in WTF::Function<void ()>::CallableWrapper<WebCore::DataURLDecoder::decode(WTF::URL const&, WebCore::DataURLDecoder::ScheduleContext const&, WTF::Function<void (WTF::Optional<WebCore::DataURLDecoder::Result>)>&&)::{lambda()#1}>::ca ll() () at /home/matthias/.openjfx/cache/13/libjfxwebkit.so #21 0x00007f915c089150 in WTF::Function<void ()>::CallableWrapper<WTF::WorkQueue::dispatch(WTF::Function<void ()>&&)::{lambda()#1}>::call() () at /home/matthias/.openjfx/cache/13/libjfxwebkit.so #22 0x00007f915c02215b in WTF::RunLoop::performWork() () at /home/matthias/.openjfx/cache/13/libjfxwebkit.so #23 0x00007f915c088190 in WTF::RunLoop::runImpl(WTF::RunLoop::RunMode) () at /home/matthias/.openjfx/cache/13/libjfxwebkit.so #24 0x00007f915c023867 in WTF::Thread::entryPoint(WTF::Thread::NewThreadContext*) () at /home/matthias/.openjfx/cache/13/libjfxwebkit.so #25 0x00007f915c08a00d in WTF::wtfThreadEntryPoint(void*) () at /home/matthias/.openjfx/cache/13/libjfxwebkit.so #26 0x00007f93c4083590 in start_thread (arg=0x7f9189fff640) at pthread_create.c:463 #27 0x00007f93c41d8223 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95 ============================================================ What I also found is, that this is not a general problem of the WebView on netbeans. I inserted seveal printf statements into the MainThreadJava.cpp and JavaEnv.h files and found, that there are several successful calls to isMainThread, but if fails for scheduleDispatchFunctionsOnMainThread. What I observe is, that the jclasses and jmethodID are resolved on each invocation. The few times I work with JNI, the correspoding libraries resolve the classids and methods at load time once and cache the results for the lifetime of the library. Wouldn't this also be an option for OpenJFX? From my observation, the jclasses can be found, just not for the schedule. Greetings Matthias
