Tho*_*ehr 9 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//...
Run Code Online (Sandbox Code Playgroud)
通过install4j创建exe文件启动应用程序时.通过反射创建javafx.embed.swing.JFXPanel实例来触发错误:
Class.forName("javafx.embed.swing.JFXPanel").newInstance();
Run Code Online (Sandbox Code Playgroud)
我们目前怀疑由于某种原因加载了不兼容的DLL(glass.dll似乎包含stacktrace中提到的本机方法).
有谁知道如何防止这个错误?例如,是否有办法将通过install4j生成的exe执行应用程序时使用的java.library.path限制为嵌入在安装程序中并随应用程序本地安装的Java运行时环境?根据一个用户,如果使用"手动"启动应用程序,则不会发生错误
java -jar app.jar
Run Code Online (Sandbox Code Playgroud)
命令.所以似乎问题在于install4j创建的可执行文件.
解决此问题的方法似乎是从系统 %PATH% 中删除所有出现的“glass.dll”。
不过,我相信必须在其他地方实施修复;在 Java 运行时或 Install4j 代码中,但不能在实际应用程序的 Java 代码中实现:
出于某种原因,Install4j 中的 Java 运行时版本在定位库时最后检查捆绑的 JRE 。在这种情况下,有问题的本机库glass.dll应该包含所请求的<init>方法,但是如果您的任何地方%PATH%有一个较旧的、不兼容的版本glass.dll(例如,来自以前的 Java 8 安装)该文件将以更高的优先级加载,然后应用程序将本地崩溃。
这不是应用程序代码(java 代码)的问题,也不是捆绑的 JDK 的问题,这是 install-4j 生成的 exe 文件(或 Java 内部)如何尝试解析本机 dll 的问题. 与其先检查所有路径元素,不如先检查捆绑的 JRE 目录。
使用 Procmon,您可以看到它加载glass.dll了路径中任意放置的文件,首先:我将 JDK 1.8 中的一个添加到我的路径元素之一中并得到了这个(加上崩溃):