Об этой проблеме уже сообщалось в системе отслеживания проблем JFoenix:
Для начала, JFoenix не совсем готов к Java 11+. Выпущенная версия предназначена для Java 9, но она по-прежнему работает с Java 11 и JavaFX 11, при условии добавления зависимостей JavaFX.
Однако в JDK 12 он не запускается, и проблема не связана с JavaFX: даже с JavaFX 11.0.2 все равно происходит сбой.
Эта проблема связана с использованием отражение для доступа к узлу Text
из TextFieldSkin
:
textNode = ReflectionHelper.getFieldContent(TextFieldSkin.class, this, "textNode");
java.lang.IllegalAccessException: class com.jfoenix.adapters.ReflectionHelper (in module com.jfoenix) cannot access a member of class javafx.scene.control.skin.TextFieldSkin (in module javafx.controls) with modifiers "private"
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:355)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:639)
at java.base/java.lang.reflect.Field.checkAccess(Field.java:1075)
at java.base/java.lang.reflect.Field.get(Field.java:416)
at com.jfoenix/com.jfoenix.adapters.ReflectionHelper.getFieldContent(ReflectionHelper.java:98)
at com.jfoenix/com.jfoenix.skins.JFXTextFieldSkin.<init>(JFXTextFieldSkin.java:59)
Хотя это работало нормально вплоть до Java 11.0.2, с Java 12 a регрессия недавние изменения в unsafe
мешают этому работать и вызывают textNode = null
.
Как @AlanBateman упоминает в своих комментариях ниже:
[Сопровождающим JFoenix] следует заменить свой метод setAccessible
на вызов obj.setAccessible(true)
, чтобы пользователь получал правильные исключения, когда библиотека пытается взломать внутренние компоненты, которые ей недоступны. Если вы сделаете это, пользователь сможет обойти эти проблемы с опциями --add-exports
или --add-opens
, пока сопровождающие библиотеки не исправят свои проблемы.
Пока это будет означать придерживаться JDK 11.
В качестве альтернативы, вы можете попытаться создать свою собственную версию JFoenix, клонировать репозиторий (ветка 9.0.0) и внести необходимые изменения, чтобы он работал с JavaFX 11+ (выходит за рамки этого ответа ...), и по возможности исключая использование отражения.
Например, textNode
можно напрямую получить с помощью:
textNode = textPane.getChildren().get(1);
или, по-прежнему полагайтесь на рефлексию, но с соответствующими упомянутыми изменениями:
try {
Field field = cls.getDeclaredField(fieldName);
field.setAccessible(true); // <-- Use this.
return (T) field.get(obj);
} catch (Throwable ex) { }
в сочетании с:
--add-exports=javafx.controls/javafx.scene.control.skin=$moduleName