Monday, 6 November 2017

How to get past "InaccessibleObjectException" while running a JavaFX application in Java 9?

When you run a JavaFX project, that was perfectly running fine in Java 8, now in Java 9, you are faced with "InaccessibleObjectException" exception  that is thrown by the Java runtime. It complains that the variables and/or methods that you have declared as private (albeit annotated with @FXML) in your "controller" classes are inaccessible as your project's Java module has not made "open" the containing package to the JDK module "javafx.fxml". Here is the full text of the exception thrown by the runtime in my sample JavaFX project:
java.lang.reflect.InaccessibleObjectException: Unable to make field private javafx.scene.control.Label sample.Controller.nameLabel accessible: module LearningJavaModules does not "opens sample" to module javafx.fxml

I have declared the "nameLabel" Label variable as follows in the controller class:
 @FXML
 private Label nameLabel;

And it has been declared in the corresponding fxml file as below:
<Label fx:id="nameLabel" />

In order to remove this exception, one needs to add the following line to the "module-info.java" file of your project's Java Module:
opens sample to javafx.fxml;

Here is the complete "module-info.java" file of my sample JavaFX project:
module LearningJavaModules {
    requires javafx.graphics;
    requires javafx.fxml;
    requires javafx.controls;
    opens sample to javafx.fxml;
    exports sample;
}

Please note that it has been given in the "JavaFX: New & Notworthy" presentation by Oracle dated September 19, 2016 that one needs to add the following line to the "module-info.java" file:
exports private my.pkg to javafx.fxml;

However, this doesn't work. It seems that the implementation has changed since the above-mentioned presentation by Oracle was released. One now needs to use "opens" instead of "exports" to make private fields accessible to JavaFX runtime.

Trust that you find this useful. :-)