JavaFX WebView in plugin and ClassLoader
I'm trying to embed an JavaFX WebView into my plugin. (using oracle jre 8u181)
I found that the jfxrt.jar is loaded by com.intellij.util.lang.UrlClassLoader but not Launcher$ExtClassLoader (maybe this is intended), while in the handle of DataURLDecoder::decode, it would try to callback to JavaVM using callOnMainThread. The callOnMainThread would use WTF::scheduleDispatchFunctionsOnMainThread then AttachThreadToJavaEnv::AttachThreadToJavaEnv and eventually jvm->AttachCurrentThread to enter the java world (it is a new thread created in native code).
static JGClass jMainThreadCls(env->FindClass("com/sun/webkit/MainThread"));
static jmethodID mid = env->GetStaticMethodID(
jMainThreadCls,
"fwkScheduleDispatchFunctions",
"()V");
Now the env->FindClass in the scheduleDispatchFunctionsOnMainThread would use java.lang.ClassLoader.getSystemClassLoader() which is Launcher$AppClassLoader but not com.intellij.util.lang.UrlClassLoader (MISMATCH!!)
So if you add some image using data protocol like <img src="data:image/png;base64,..."> would trigger this bug.
val mainPanel = JFXPanel()
val img = "iVBORw0KGgoAAAANSUhEUgAAAGQAAAAKCAYAAABCHPt+AAAAKUlEQVR42u3RAQ0AAAgDIG1u81vDTahAZyrFGS1ECEKEIEQIQoQg5LcF678Y92/zlF8AAAAASUVORK5CYII="
Platform.runLater {
val webView = WebView("<img src=\"data:image/png;base64,$img\">")
webView.engine.loadContent()
myWebView = webView
mainPanel.scene = Scene(webView)
}
this code could reproduce the bug, and you would see in console
internal base64
Exception in thread "Thread-64" java.lang.NullPointerException
at com.sun.webkit.MainThread.fwkScheduleDispatchFunctions(MainThread.java:34)
Please sign in to leave a comment.
Hi, did you find any way to fix this? I'm trying something similiar.
I've opened an issue here https://youtrack.jetbrains.com/issue/IDEA-199701 and https://github.com/javafxports/openjdk-jfx/issues/220
It is definitely a bug, possible fixes I could image are:
a) set system classloader (the result of ClassLoader.getSystemClassLoader) to intellij's com.intellij.util.lang.UrlClassLoader
b) change the parent of com.intellij.util.lang.UrlClassLoader to Launcher$ExtClassLoader, and let the latter load javafx
c) inside javafx provide a functionality to set class loader or just cache the classid of com.sun.webkit.MainThread before call fwkScheduleDispatchFunctions
Unfortunately, I think a) and b) should be done (and only could be done) in idea side other than our plugin side, and c) could only be fixed in javafx.
It is a BUG when use javafx in idea! Not only about base64 data resources, all the thread created in native code in javafx webkit (and maybe other packages) would affected by the BUG. (There're so many cases in the javafx's native code and I could not check them one by one: search AttachThreadToJavaEnv/callOnMainThread)
@Melek Kalyoncu, workaround for images with base64 data resources: just save them on disk and use the "file://" protocol, the code path of url encoded resource is different and won't trigger the bug.