Переход с java 8 на openJDK 24
Решил перенести некоторые свои наработки с java 8 на openJDK 24. Немного продвинулся, но столкнулся с проблемой, в которой не получается разобраться.
Суть такова: есть библиотека, для которой я создал тестовый проект со структурой приведённой ниже:
Описание модуля проекта выглядит следующим образом:
module libraryfx
{
requires javafx.controls;
requires javafx.fxml;
requires javafx.graphics;
requires java.sql;
requires java.desktop;
exports libraryfx.utils.guiutils;
opens libraryfx.utils.guiutils to javafx.fxml, javafx.graphics;
exports libraryfx.utils;
opens libraryfx.utils to javafx.fxml, javafx.graphics;
exports libraryfx.decoration;
opens libraryfx.decoration to javafx.fxml, javafx.graphics;
exports libraryfx.controls;
opens libraryfx.controls to javafx.fxml, javafx.graphics;
exports libraryfx.layout;
opens libraryfx.layout to javafx.fxml, javafx.graphics;
}
Сразу скажу, что не совсем уверен в правильности и оптимальности этого описания.
При компиляции используются следующие настройки, находящиеся в файле проекта compiler.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<excludeFromCompile>
<directory url="file://$PROJECT_DIR$/src/main/resources/archetype-resources" includeSubdirectories="true" />
</excludeFromCompile>
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="libraryfx" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="libraryfx" options="--add-exports javafx.graphics/com.sun.javafx.scene.text=libraryfx
--add-exports javafx.graphics/com.sun.javafx.tk=libraryfx
--add-exports javafx.graphics/com.sun.javafx.geom=libraryfx
--add-exports javafx.graphics/com.sun.javafx.util=libraryfx" />
</option>
</component>
</project>
Эта библиотека компилируется и собирается при помощи maven.
Далее я её подключаю к другому тестовому проекту.
Так вот, когда я использую элементы управления, которые не обращаются к классу com.sun.javafx.tk.Toolkit, тестовый проект работает, как и ожидается. Но, как только я включаю в него элементы управления, обращающиеся к классу com.sun.javafx.tk.Toolkit на этапе исполнения вылетает следующая ошибка:
Exception in Application start method
Exception in thread "JavaFX Application Thread" java.lang.NoClassDefFoundError: Could not initialize class libraryfx.utils.guiutils.GUIUtils
at libraryfx/libraryfx.controls.skin.DecorableLabelSkin.computePrefWidth(DecorableLabelSkin.java:135)
at [email protected]/javafx.scene.control.Control.computePrefWidth(Control.java:571)
at [email protected]/javafx.scene.Parent.prefWidth(Parent.java:1085)
at [email protected]/javafx.scene.layout.Region.prefWidth(Region.java:1536)
at [email protected]/javafx.scene.layout.Region.computeChildPrefAreaWidth(Region.java:1959)
at [email protected]/javafx.scene.layout.Region.getMaxAreaWidth(Region.java:2228)
at [email protected]/javafx.scene.layout.Region.computeMaxPrefAreaWidth(Region.java:2097)
at [email protected]/javafx.scene.layout.StackPane.computePrefWidth(StackPane.java:303)
at [email protected]/javafx.scene.Parent.prefWidth(Parent.java:1085)
at [email protected]/javafx.scene.layout.Region.prefWidth(Region.java:1536)
at libraryfx/libraryfx.layout.FramePane.computeMinHeight(FramePane.java:1576)
at [email protected]/javafx.scene.Parent.minHeight(Parent.java:1127)
at [email protected]/javafx.scene.layout.Region.minHeight(Region.java:1518)
at [email protected]/javafx.scene.layout.Region.computeChildPrefAreaHeight(Region.java:1993)
at [email protected]/javafx.scene.layout.VBox.getAreaHeights(VBox.java:451)
at [email protected]/javafx.scene.layout.VBox.layoutChildren(VBox.java:572)
at [email protected]/javafx.scene.Parent.layout(Parent.java:1272)
at [email protected]/javafx.scene.Scene.doLayoutPass(Scene.java:641)
at [email protected]/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2655)
at [email protected]/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:380)
at [email protected]/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:401)
at [email protected]/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:592)
at [email protected]/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:572)
at [email protected]/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:565)
at [email protected]/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$6(QuantumToolkit.java:346)
at [email protected]/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at [email protected]/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at [email protected]/com.sun.glass.ui.win.WinApplication.lambda$runLoop$0(WinApplication.java:168)
at java.base/java.lang.Thread.run(Thread.java:1447)
Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.IllegalAccessError: class libraryfx.utils.guiutils.GUIUtils (in module libraryfx) cannot access class com.sun.javafx.tk.Toolkit (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.tk to module libraryfx [in thread "JavaFX Application Thread"]
at libraryfx/libraryfx.utils.guiutils.GUIUtils.<clinit>(GUIUtils.java:89)
at libraryfx/libraryfx.controls.skin.DecorableLabelSkin.computePrefWidth(DecorableLabelSkin.java:135)
at [email protected]/javafx.scene.control.Control.computePrefWidth(Control.java:571)
at [email protected]/javafx.scene.Parent.prefWidth(Parent.java:1085)
at [email protected]/javafx.scene.layout.Region.prefWidth(Region.java:1536)
at [email protected]/javafx.scene.layout.Region.computeChildPrefAreaWidth(Region.java:1959)
at [email protected]/javafx.scene.layout.Region.getMaxAreaWidth(Region.java:2228)
at [email protected]/javafx.scene.layout.Region.computeMaxPrefAreaWidth(Region.java:2097)
at [email protected]/javafx.scene.layout.StackPane.computePrefWidth(StackPane.java:303)
at [email protected]/javafx.scene.Parent.prefWidth(Parent.java:1085)
at [email protected]/javafx.scene.layout.Region.prefWidth(Region.java:1536)
at libraryfx/libraryfx.layout.FramePane.computeMinHeight(FramePane.java:1576)
at [email protected]/javafx.scene.Parent.minHeight(Parent.java:1127)
at [email protected]/javafx.scene.layout.Region.minHeight(Region.java:1518)
at [email protected]/javafx.scene.layout.Region.computeChildPrefAreaHeight(Region.java:1993)
at [email protected]/javafx.scene.layout.VBox.getAreaHeights(VBox.java:451)
at [email protected]/javafx.scene.layout.VBox.computeContentHeight(VBox.java:539)
at [email protected]/javafx.scene.layout.VBox.computePrefHeight(VBox.java:428)
at [email protected]/javafx.scene.Parent.prefHeight(Parent.java:1105)
at [email protected]/javafx.scene.layout.Region.prefHeight(Region.java:1552)
at [email protected]/javafx.scene.Scene.getPreferredHeight(Scene.java:1896)
at [email protected]/javafx.scene.Scene.resizeRootToPreferredSize(Scene.java:1865)
at [email protected]/javafx.scene.Scene.preferredSize(Scene.java:1832)
at [email protected]/javafx.scene.Scene$2.preferredSize(Scene.java:423)
at [email protected]/com.sun.javafx.scene.SceneHelper.preferredSize(SceneHelper.java:73)
at [email protected]/javafx.stage.Window$12.invalidated(Window.java:1159)
at [email protected]/javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110)
at [email protected]/javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:145)
at [email protected]/javafx.stage.Window.setShowing(Window.java:1235)
at [email protected]/javafx.stage.Window.show(Window.java:1250)
at [email protected]/javafx.stage.Stage.show(Stage.java:272)
at org.example.demo/org.example.demo1.HelloApplication.start(HelloApplication.java:17)
at [email protected]/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$7(LauncherImpl.java:840)
at [email protected]/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$5(PlatformImpl.java:444)
at [email protected]/com.sun.javafx.application.PlatformImpl.lambda$runLater$4(PlatformImpl.java:419)
... 4 more
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
at java.base/java.lang.reflect.Method.invoke(Method.java:565)
at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:465)
at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:365)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:565)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1180)
Caused by: java.lang.RuntimeException: Exception in Application start method
at [email protected]/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:894)
at [email protected]/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$0(LauncherImpl.java:197)
at java.base/java.lang.Thread.run(Thread.java:1447)
Caused by: java.lang.IllegalAccessError: class libraryfx.utils.guiutils.GUIUtils (in module libraryfx) cannot access class com.sun.javafx.tk.Toolkit (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.tk to module libraryfx
at libraryfx/libraryfx.utils.guiutils.GUIUtils.<clinit>(GUIUtils.java:89)
at libraryfx/libraryfx.controls.skin.DecorableLabelSkin.computePrefWidth(DecorableLabelSkin.java:135)
at [email protected]/javafx.scene.control.Control.computePrefWidth(Control.java:571)
at [email protected]/javafx.scene.Parent.prefWidth(Parent.java:1085)
at [email protected]/javafx.scene.layout.Region.prefWidth(Region.java:1536)
at [email protected]/javafx.scene.layout.Region.computeChildPrefAreaWidth(Region.java:1959)
at [email protected]/javafx.scene.layout.Region.getMaxAreaWidth(Region.java:2228)
at [email protected]/javafx.scene.layout.Region.computeMaxPrefAreaWidth(Region.java:2097)
at [email protected]/javafx.scene.layout.StackPane.computePrefWidth(StackPane.java:303)
at [email protected]/javafx.scene.Parent.prefWidth(Parent.java:1085)
at [email protected]/javafx.scene.layout.Region.prefWidth(Region.java:1536)
at libraryfx/libraryfx.layout.FramePane.computeMinHeight(FramePane.java:1576)
at [email protected]/javafx.scene.Parent.minHeight(Parent.java:1127)
at [email protected]/javafx.scene.layout.Region.minHeight(Region.java:1518)
at [email protected]/javafx.scene.layout.Region.computeChildPrefAreaHeight(Region.java:1993)
at [email protected]/javafx.scene.layout.VBox.getAreaHeights(VBox.java:451)
at [email protected]/javafx.scene.layout.VBox.computeContentHeight(VBox.java:539)
at [email protected]/javafx.scene.layout.VBox.computePrefHeight(VBox.java:428)
at [email protected]/javafx.scene.Parent.prefHeight(Parent.java:1105)
at [email protected]/javafx.scene.layout.Region.prefHeight(Region.java:1552)
at [email protected]/javafx.scene.Scene.getPreferredHeight(Scene.java:1896)
at [email protected]/javafx.scene.Scene.resizeRootToPreferredSize(Scene.java:1865)
at [email protected]/javafx.scene.Scene.preferredSize(Scene.java:1832)
at [email protected]/javafx.scene.Scene$2.preferredSize(Scene.java:423)
at [email protected]/com.sun.javafx.scene.SceneHelper.preferredSize(SceneHelper.java:73)
at [email protected]/javafx.stage.Window$12.invalidated(Window.java:1159)
at [email protected]/javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110)
at [email protected]/javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:145)
at [email protected]/javafx.stage.Window.setShowing(Window.java:1235)
at [email protected]/javafx.stage.Window.show(Window.java:1250)
at [email protected]/javafx.stage.Stage.show(Stage.java:272)
at org.example.demo/org.example.demo1.HelloApplication.start(HelloApplication.java:17)
at [email protected]/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$7(LauncherImpl.java:840)
at [email protected]/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$5(PlatformImpl.java:444)
at [email protected]/com.sun.javafx.application.PlatformImpl.lambda$runLater$4(PlatformImpl.java:419)
at [email protected]/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at [email protected]/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at [email protected]/com.sun.glass.ui.win.WinApplication.lambda$runLoop$0(WinApplication.java:168)
... 1 more
Exception running application org.example.demo1.HelloApplication
Извиняюсь, что длинно.
Меня смущает вот эта строчка:
Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.IllegalAccessError: class libraryfx.utils.guiutils.GUIUtils (in module libraryfx) cannot access class com.sun.javafx.tk.Toolkit (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.tk to module libraryfx [in thread "JavaFX Application Thread"]
Подскажите, что у меня не так?
Ответы (1 шт):
Итак, вот решение:
необходимо было установить параметры виртуальной машины Java. Для IntelliJ IDEA 2024 это делается так:
открываем диалоговое окно редактирования конфигурации исполнения
Menu > Run > Edit Configurations...
в этом окне жмём на Modify options и в ниспадающем окошке выбираем Add VM options
- в диалоговом окне появляется соответствующее поле;
в это поле вносим все наши инструкции --add-exports
, которые мы использовали при компиляции;
жмём на OK и видим, что всё в порядке!
Примечание: если выпадает ошибка о том, что что-то не открыто для чего-то, то сюда же добавляем соответствующую инструкцию --add-opens
.
Надеюсь, кому-то поможет этот мой опыт.