Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NoSuchMethodError: <init> in com.sun.glass.ui.win.WinApplication.staticScreen_getScreens

Since upgrading to install4j 7.0.5 and Java 10, users that run our application on Windows more and more often report that the application throws

java.lang.NoSuchMethodError: <init>
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.staticScreen_getScreens(Native Method)
    at javafx.graphics/com.sun.glass.ui.Screen.initScreens(Unknown Source)
    at javafx.graphics/com.sun.glass.ui.Application.lambda$run$1(Unknown Source)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(Unknown Source)
    at java.base/java.lang.Thread.run(Unknown Source)


UiLauncher (WAITING)
    at [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
    at [email protected]/java.util.concurrent.locks.LockSupport.park(Unknown Source)
    at [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(Unknown Source)
    at [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(Unknown Source)
    at [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(Unknown Source)
    at [email protected]/java.util.concurrent.CountDownLatch.await(Unknown Source)
    at platform/[email protected]/com.sun.javafx.tk.quantum.QuantumToolkit.startup(Unknown Source)
    at platform/[email protected]/com.sun.javafx.application.PlatformImpl.startup(Unknown Source)
    at platform/[email protected]/com.sun.javafx.application.PlatformImpl.startup(Unknown Source)
    at platform/[email protected]/javafx.embed.swing.JFXPanel.initFx(Unknown Source)
    at platform/[email protected]/javafx.embed.swing.JFXPanel.<init>(Unknown Source)
    at [email protected]/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at [email protected]/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at [email protected]/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at [email protected]/java.lang.reflect.Constructor.newInstance(Unknown Source)
    at [email protected]/java.lang.Class.newInstance(Unknown Source)
    at app//...

when starting the application though the install4j created exe file. The error is triggered by creating an instance of javafx.embed.swing.JFXPanel through reflection:

Class.forName("javafx.embed.swing.JFXPanel").newInstance();

We currently suspect that for some reason an incompatible DLL is loaded (glass.dll seems to contain the native method mentioned in the stacktrace).

Does anyone know how to prevent this error? E.g. is there are way to restrict the java.library.path used when executing the application through the install4j-generated exe to the Java runtime environment that was embedded in the installer and installed locally with the application? According to one user, the error does not occur if the application is started "manually" using the

java -jar app.jar

command. So it seems the problem lies with the install4j created executable.

like image 999
Thomas Behr Avatar asked Jun 29 '18 12:06

Thomas Behr


1 Answers

The workaround to this problem seems to be to remove all occurences of "glass.dll" from your system %PATH%.

I believe a fix must be implemented somewhere else, though; either in the Java runtime or in the Install4j code, but cannot be implemented in the Java code of the actual app:

For some reason the Java runtime version in Install4j checks the bundled JRE last when locating the libraries. In this case the problematic native library is glass.dll which should contain the requested <init> method but if anywhere in your %PATH% there is an older, incompatible version of glass.dll (e.g. from a previous Java 8 installation) that file will be loaded with a higher precedence and then the application will crash natively.

This is not a problem in the code of the application (the java code), nor a problem with the bundled JDK, this is a problem of how the install-4j-generated exe files (or maybe Java internally) tries to resolve native dlls. Instead of checking all path elements first, it should be checking the bundled JRE directory, first.

With Procmon you can see that it loads arbitrarily placed glass.dll files in the path, first: I added one from JDK 1.8 into one of my path elements and got this (plus the crash):

procmon log showing java loading the first glass.dll it can find

like image 158
Sebastian Avatar answered Nov 16 '22 00:11

Sebastian