IllegalAccessException for JFXTextField with java sdk 12

回眸只為那壹抹淺笑 提交于 2019-12-10 05:33:41

问题


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 com.jfoenix) cannot access a member of class javafx.scene.control.skin.TextFieldSkin (in module javafx.controls) with modifiers "private"

Controller :

package sample;

import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTextField;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;

import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {

@FXML
private Button clickMe;


@FXML
private JFXButton materialButton;

@FXML
private JFXTextField textField;


@Override
public void initialize(URL url, ResourceBundle resourceBundle) {

    materialButton.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent actionEvent)
        {
            String text = textField.getText().trim();
            System.out.println(text);
        }
    });

}
}

Sample.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXTextField?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: #fcda;" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <children>
      <Button fx:id="clickMe" layoutX="198.0" layoutY="188.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="225.0" style="-fx-background-color: #fffe;" text="Click Me" textFill="#722929" />
      <JFXButton fx:id="materialButton" layoutX="231.0" layoutY="82.0" prefHeight="54.0" prefWidth="139.0" style="-fx-background-color: #ffff;" textFill="#280c0c">
         <font>
            <Font size="25.0" />
         </font></JFXButton>
      <JFXTextField fx:id="textField" layoutX="233.0" layoutY="24.0" promptText="Enter UserName" />
   </children>
</AnchorPane>

回答1:


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


来源:https://stackoverflow.com/questions/55889654/illegalaccessexception-for-jfxtextfield-with-java-sdk-12

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!