Jak uzyskać dostęp do niewyeksportowanego modułu Java?
Muszę zlokalizować wbudowane kontrolki JavaFX. Przed Jigsawa były sposoby na osiągnięcie tego:
- Poprzez dodatkowy plik właściwości, który należy umieścić w
com.sun.javafx...pakiecie - Poprzez odbicie API, jak pokazano tutaj
Obie metody nie są kompatybilne z modułami Java, ponieważ com/sun/javafx/scene/control/*nie są częścią publicznego API i nie ma możliwości utworzenia dwóch pakietów o identycznej nazwie, nawet jeśli należą do różnych projektów.
Jest jakaś szansa na włamanie się do tego problemu, aby uzyskać dostęp do pakietu wewnętrznego? Dokładniej, moduł ładujący klasy ControlResources .
Powiązane pytania:
Lokalizowanie kontrolek JavaFx
Odpowiedzi
Ok, straciłem cały dzień kopiąc ten temat.
Krótka odpowiedź: to niemożliwe.
Długa odpowiedź
Możesz używać add-exportsi, add-opensaby uzyskać dostęp do com.sun.javafx.scene.control.skin.resources, ale będzie to działać tylko wtedy, gdy nie używasz nazwanych modułów, innymi słowy, twoja aplikacja nie może być modularyzowana.
<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>
Jeśli Twoja aplikacja jest zmodularyzowana, otrzymasz to.
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)
Dzieje się tak, ponieważ jedynym sposobem uzyskania dostępu do zasobów znajdujących się w innym module jest SPI ( dokumentacja tutaj ). OpenJFX nie jest implementowany w ResourceBundleProvidercelu zapewnienia dostępu do internacjonalizacji kontroli, ponieważ jest częścią wewnętrznego API.
Tak więc ten problem mogą rozwiązać tylko deweloperzy OpenJFX, ale sądząc po ostatnich dziennikach zmian OpenJFX, są oni bardzo skoncentrowani na poprawianiu literówek, a nie funkcji.