Wie erhalte ich Zugriff auf ein nicht exportiertes Java-Modul?
Ich muss die in JavaFX integrierten Steuerelemente lokalisieren. Vor Jigsaw gab es Möglichkeiten, dies zu erreichen:
- Über eine zusätzliche Eigenschaftendatei , die in das
com.sun.javafx...Paket gestellt werden muss - Ü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
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.