Come accedere a un modulo Java non esportato?
Ho bisogno di localizzare i controlli integrati di JavaFX. Prima di Jigsaw c'erano dei modi per ottenere questo risultato:
- Tramite un file delle proprietà aggiuntivo che deve essere inserito nel
com.sun.javafx...pacchetto - Tramite l'API di riflessione, come mostrato qui
Entrambi i metodi non sono compatibili con i moduli Java, perché com/sun/javafx/scene/control/*non fanno parte dell'API pubblica e non c'è modo di creare due pacchetti con lo stesso nome anche se appartengono a progetti diversi.
Qualche possibilità di hackerare questo problema per ottenere l'accesso al pacchetto interno? Più specificamente, il classloader ControlResources .
Domande correlate:
Localizzazione dei controlli JavaFx
Risposte
Ok, ho perso l'intera giornata a scavare su questo argomento.
Risposta breve: non è possibile.
Risposta lunga
Puoi usare add-exportse add-opensper accedere a com.sun.javafx.scene.control.skin.resources, ma funzionerà solo se non stai usando moduli con nome, in altre parole, la tua app non deve essere modularizzata.
<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>
Se la tua app è modularizzata, otterrai questo.
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)
Questo perché l'unico modo per ottenere l'accesso alle risorse che si trovano in un altro modulo è SPI ( documenti qui ). OpenJFX non implementa ResourceBundleProviderper fornire l'accesso ai controlli di internazionalizzazione, perché fa parte dell'API interna.
Quindi, questo problema può essere risolto solo dagli sviluppatori di OpenJFX, ma a giudicare dagli ultimi changelog di OpenJFX, sono altamente concentrati sulla correzione di errori di battitura, non sulle funzionalità.