lundi 25 mai 2020

How to access private/package protected fields and methods in Java module system?

I'm trying to access the horizontal ScrollBar for the VirtualFlow that is internal control for a TableView. My working environment:

  • OS - Windows 10
  • IDE - Eclipse v. 2020-03 (4.15.0)
  • JDK - jdk-10.0.2
  • Compiler - maven-compiler-plugin 3.8.1 (m2E for Eclipse)

The code below attempts to access the VirtualFlow (which is a field named flow in TableViewSkinBase, the parent for the skin for the TableView), and then to access the horizontal ScrollBar:

private void xxx() {
      final TableView<R> tableView = new TableView<>();
      final TableViewSkin<R> skin = (TableViewSkin<R>) tableView.getSkin();
      try {
           final Field flowField = TableViewSkinBase.class.getDeclaredField("flow");
           flowField.setAccessible(true);
           final Method hbarMethod = VirtualFlow.class.getDeclaredMethod("getHbar");
           hbarMethod.setAccessible(true);

           final VirtualFlow<IndexedCell<R>> flow = (VirtualFlow<IndexedCell<R>>) flowField.get(skin);
           ScrollBar hbar = (ScrollBar) flowField.get(flow);
      }
      catch (NoSuchMethodException | SecurityException | NoSuchFieldException | IllegalArgumentException | IllegalAccessException ex) {
           ex.printStackTrace();
      }
 }

The snippet below is from the entry in the .pom file for the compiler plugin:

<plugin>
            <!-- http://maven.apache.org/plugins/maven-compiler-plugin/ -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>10</source>
                <target>10</target>
                <compilerArgs>
                    <arg>--add-opens=javafx.scene.control=ALL-UNNAMED</arg>
                    <arg>--add-opens=javafx.scene.control.skin=ALL-UNNAMED</arg>
                </compilerArgs>
            </configuration>
</plugin>

An InaccessibleObjectException is thrown at the flowField.setAccessible(true) line in the try/catch block with the message:

Unable to make field javafx.scene.control.skin.VirtualFlow javafx.scene.control.skin.TableViewSkinBase.flow accessible: module javafx.controls does not "opens javafx.scene.control.skin" to unnamed module @418e9723

I'm pretty sure there's more than one error here and would be grateful to have them pointed out; an example based on the working environment described above would be useful.

Thanks in advance.





Aucun commentaire:

Enregistrer un commentaire