Переход с 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.

Надеюсь, кому-то поможет этот мой опыт.

→ Ссылка