NoSuchMethodError: <init>в com.sun.glass.ui.win.WinApplication.staticScreen_getScreens - PullRequest
0 голосов
/ 29 июня 2018

После обновления до 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 создал исполняемый файл. Ошибка вызвана созданием экземпляра javafx.embed.swing.JFXPanel через отражение:

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

В настоящее время мы подозреваем, что по какой-то причине загружена несовместимая DLL-библиотека (кажется, что glass.dll содержит собственный метод, упомянутый в трассировке стека).

Кто-нибудь знает, как предотвратить эту ошибку? Например. Есть ли способ ограничить java.library.path, используемый при выполнении приложения через exe-файл, сгенерированный install4j, к среде выполнения Java, которая была встроена в установщик и установлена ​​локально с приложением? По словам одного пользователя, ошибка не возникает, если приложение запускается «вручную» с помощью

java -jar app.jar

команда. Так что, похоже, проблема заключается в исполняемом файле install4j.

1 Ответ

0 голосов
/ 16 июля 2018

Обходной путь к этой проблеме, по-видимому, заключается в удалении всех случаев появления «glass.dll» из вашей системы% PATH%.

Я считаю, что fix должно быть реализовано где-то еще; либо во время выполнения Java, либо в коде Install4j, но не может быть реализовано в коде Java реального приложения:

Почему-то версия времени выполнения Java в Install4j проверяет связанный JRE last при поиске библиотек. В этом случае проблемной собственной библиотекой является glass.dll, которая должна содержать запрошенный метод <init>, но если где-то в вашем %PATH% есть более старая несовместимая версия glass.dll (например, из предыдущей установки Java 8), этот файл будет загружен с более высоким приоритетом, а затем приложение будет аварийно завершать работу.

Это , а не проблема в коде приложения (код Java), ни проблема в комплекте JDK, это проблема того, как исполняемые install-4j исполняемые файлы (или возможно Java внутренне) пытается разрешить родные dll. Вместо того, чтобы сначала проверять все элементов пути, сначала следует проверить связанный каталог JRE.

С Procmon вы можете видеть, что он загружает произвольно помещенные glass.dll файлы в путь, во-первых: я добавил один из JDK 1.8 в один из моих элементов пути и получил это (плюс сбой):

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

...