Comment accéder au module Java non exporté?

Aug 27 2020

J'ai besoin de localiser les contrôles intégrés JavaFX. Avant Jigsaw, il y avait plusieurs moyens d'y parvenir:

  1. Via un fichier de propriétés supplémentaire qui doit être placé dans le com.sun.javafx...package
  2. Via l'API de réflexion, comme illustré ici

Les deux méthodes ne sont pas compatibles avec les modules Java, car com/sun/javafx/scene/control/*ne font pas partie de l'API publique et il n'y a aucun moyen de créer deux packages avec un nom identique même s'ils appartiennent à des projets différents.

Avez-vous une chance de pirater ce problème pour accéder au package interne? Plus spécifiquement, le chargeur de classe ControlResources .

Questions connexes:

Localisation des contrôles JavaFx

Réponses

Evan Aug 28 2020 at 13:00

Ok, j'ai perdu toute la journée à creuser ce sujet.

Réponse courte: ce n'est pas possible.

Longue réponse

Vous pouvez utiliser add-exportset add-openspour accéder au com.sun.javafx.scene.control.skin.resources, mais cela ne fonctionnera que si vous n'utilisez pas de modules nommés, en d'autres termes, votre application ne doit pas être modularisée.

<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>

Si votre application est modulaire, vous l'obtiendrez.

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)

C'est parce que le seul moyen d'accéder aux ressources qui se trouvent dans un autre module est SPI ( docs ici ). OpenJFX ne met pas en œuvre ResourceBundleProviderpour fournir l'accès à l'internationalisation des contrôles, car il fait partie de l'API interne.

Donc, ce problème ne peut être résolu que par les développeurs OpenJFX, mais à en juger par les derniers journaux de modifications OpenJFX, ils sont très concentrés sur la correction des fautes de frappe, pas sur les fonctionnalités.