IllegalAccessException for JFXTextField with java sdk 12

前端 未结 1 1084
无人及你
无人及你 2020-12-10 15:30

I added JFXTextField in my javafx application but I got this error with no clue how to solve it

class com.jfoenix.skins.JFXTextFieldSkin (in module

相关标签:
1条回答
  • 2020-12-10 16:07

    This issue has already been reported at the JFoenix's issue tracker:

    • JDK 12 incompatible
    • IllegalAccessException for JFXTextField / JFXPasswordField with JDK12

    For starters, JFoenix is not really ready for Java 11+. The released version is intended for Java 9, but it still works with Java 11 and JavaFX 11, providing you add the JavaFX dependencies.

    However, under JDK 12 it fails to run, and the issue is not JavaFX related: even with JavaFX 11.0.2 it still fails.

    The issue is related to the use of reflection to access the Text node of 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)
    

    While this worked fine up until Java 11.0.2, with Java 12 a regression recent changes in unsafe prevents this from working, and causes textNode = null.

    As @AlanBateman mentions in his comments below:

    [The JFoenix maintainers] should replace their setAccessible method to call obj.setAccessible(true) so that the user gets the right exceptions when the library tries to hack internals that are not accessible to it. If you do that then the user can workaround those issues with --add-exports or --add-opens options until the maintainers of the library fix their issues.

    For now this will mean sticking to JDK 11.

    Alternatively, you could try to build your own JFoenix version, cloning the repo (branch 9.0.0) and making the necessary changes to make it work with JavaFX 11+ (out of scope of this answer...), and removing the use of reflection where possible.

    For instance, the textNode can be directly retrieved with:

    textNode = textPane.getChildren().get(1);
    

    or, still rely on reflection, but with the proper changes mentioned:

    try {
        Field field = cls.getDeclaredField(fieldName);
        field.setAccessible(true); // <-- Use this.
        return (T) field.get(obj);
    } catch (Throwable ex) { }
    

    combined with:

    --add-exports=javafx.controls/javafx.scene.control.skin=$moduleName
    
    0 讨论(0)
提交回复
热议问题