Wie erhalte ich Zugriff auf ein nicht exportiertes Java-Modul?

Aug 27 2020

Ich muss die in JavaFX integrierten Steuerelemente lokalisieren. Vor Jigsaw gab es Möglichkeiten, dies zu erreichen:

  1. Über eine zusätzliche Eigenschaftendatei , die in das com.sun.javafx...Paket gestellt werden muss
  2. Über Reflection API, wie hier gezeigt

Beide Methoden sind nicht mit Java-Modulen kompatibel, da sie com/sun/javafx/scene/control/*nicht Teil der öffentlichen API sind und es keine Möglichkeit gibt, zwei Pakete mit identischem Namen zu erstellen, selbst wenn sie zu den verschiedenen Projekten gehören.

Gibt es eine Möglichkeit, dieses Problem zu hacken, um Zugriff auf das interne Paket zu erhalten? Genauer gesagt ControlResources Classloader.

Verwandte Fragen:

Lokalisieren von JavaFx-Steuerelementen

Antworten

Evan Aug 28 2020 at 13:00

Ok, ich habe den ganzen Tag verloren, dieses Thema zu graben.

Kurze Antwort: Es ist nicht möglich.

Lange Antwort

Sie können add-exportsund verwenden add-opens, um Zugriff auf das zu erhalten com.sun.javafx.scene.control.skin.resources, aber es funktioniert nur, wenn Sie keine benannten Module verwenden. Mit anderen Worten, Ihre App darf nicht modularisiert werden.

<plugin>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-maven-plugin</artifactId>
    <configuration>
        <mainClass>${bld.mainClass}</mainClass> <executable>${java.home}/bin/java</executable>
        <options>
            <option>--add-exports</option>
            <option>javafx.controls/com.sun.javafx.scene.control.skin.resources=app.module</option>
            <option>--add-opens</option>
            <option>javafx.controls/com.sun.javafx.scene.control.skin.resources=app.module</option>
        </options>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <compilerArgs>
            <arg>--add-exports</arg>
            <arg>javafx.controls/com.sun.javafx.scene.control.skin.resources=app.module</arg>
            <arg>--add-opens</arg>
            <arg>javafx.controls/com.sun.javafx.scene.control.skin.resources=app.module</arg>
        </compilerArgs>
    </configuration>
</plugin>

Wenn Ihre App modularisiert ist, erhalten Sie dies.

Caused by: java.lang.UnsupportedOperationException: ResourceBundle.Control not supported in named modules
    at java.base/java.util.ResourceBundle.checkNamedModule(ResourceBundle.java:1547)
    at java.base/java.util.ResourceBundle.getBundle(ResourceBundle.java:1508)

Dies liegt daran, dass der einzige Weg, um auf die Ressourcen zuzugreifen, die sich in einem anderen Modul befinden, SPI ist ( Dokumente hier ). OpenJFX implementiert ResourceBundleProviderkeinen Zugriff auf die Internationalisierung von Steuerelementen, da es Teil der internen API ist.

Dieses Problem kann also nur von OpenJFX-Entwicklern gelöst werden. Nach den letzten OpenJFX-Änderungsprotokollen konzentrieren sie sich jedoch stark auf das Beheben von Tippfehlern und nicht auf Funktionen.