NoSuchMethodError:com.sun.glass.ui.win.WinApplication.staticScreen_getScreens

时间:2018-06-29 12:12:28

标签: java windows javafx install4j java-10

自从升级到install4j 7.0.5和Java 10以来,在Windows上运行我们的应用程序的用户越来越多地报告该应用程序抛出了

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 java.base@10.0.1/jdk.internal.misc.Unsafe.park(Native Method)
    at java.base@10.0.1/java.util.concurrent.locks.LockSupport.park(Unknown Source)
    at java.base@10.0.1/java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(Unknown Source)
    at java.base@10.0.1/java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(Unknown Source)
    at java.base@10.0.1/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(Unknown Source)
    at java.base@10.0.1/java.util.concurrent.CountDownLatch.await(Unknown Source)
    at platform/javafx.graphics@10.0.1/com.sun.javafx.tk.quantum.QuantumToolkit.startup(Unknown Source)
    at platform/javafx.graphics@10.0.1/com.sun.javafx.application.PlatformImpl.startup(Unknown Source)
    at platform/javafx.graphics@10.0.1/com.sun.javafx.application.PlatformImpl.startup(Unknown Source)
    at platform/javafx.swing@10.0.1/javafx.embed.swing.JFXPanel.initFx(Unknown Source)
    at platform/javafx.swing@10.0.1/javafx.embed.swing.JFXPanel.<init>(Unknown Source)
    at java.base@10.0.1/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base@10.0.1/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at java.base@10.0.1/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.base@10.0.1/java.lang.reflect.Constructor.newInstance(Unknown Source)
    at java.base@10.0.1/java.lang.Class.newInstance(Unknown Source)
    at app//...

通过install4j创建的exe文件启动应用程序时。通过反射创建javafx.embed.swing.JFXPanel的实例触发该错误:

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

我们目前怀疑由于某种原因加载了不兼容的DLL(glass.dll似乎包含stacktrace中提到的本机方法)。

有人知道如何防止此错误吗?例如。有什么方法可以将通过install4j生成的exe执行应用程序时使用的java.library.path限制为嵌入在安装程序中并随应用程序本地安装的Java运行时环境? 根据一位用户的说法,如果使用

“手动”启动应用程序,则不会发生该错误。
java -jar app.jar

命令。看来问题出在install4j创建的可执行文件上。

1 个答案:

答案 0 :(得分:3)

此问题的解决方法似乎是从系统%PATH%中删除所有出现的“ glass.dll”。

我相信修复必须在其他地方实现;在Java运行时或Install4j代码中,但无法在实际应用程序的Java代码中实现:

由于某种原因,Install4j中的Java运行时版本在查找库时会检查捆绑的JRE last 。在这种情况下,有问题的本机库是glass.dll,该库应包含请求的<init>方法,但是如果您的%PATH%中的任何地方都有glass.dll的较旧且不兼容的版本(例如,以前的Java 8安装),该文件将以更高的优先级加载,然后应用程序将自然崩溃。

这不是应用程序代码(java代码)中的问题,也不是捆绑的JDK的问题,这是install-4j生成的exe文件的问题(或内部Java)尝试解析本机dll。与其先检查 all 路径元素,不如先检查捆绑的JRE目录。

使用Procmon,您可以看到它在路径中任意放置了glass.dll个文件,首先:我将JDK 1.8中的一个添加到我的一个路径元素中,并得到了它(还有崩溃):

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