¿Cómo acceder al módulo Java no exportado?

Aug 27 2020

Necesito localizar los controles integrados de JavaFX. Antes de Jigsaw había varias formas de lograrlo:

  1. A través de un archivo de propiedades adicional que debe colocarse en el com.sun.javafx...paquete
  2. A través de la API de reflexión, como se muestra aquí

Ambos métodos no son compatibles con los módulos de Java, porque com/sun/javafx/scene/control/*no es parte de la API pública y no hay forma de crear dos paquetes con el mismo nombre, incluso si pertenecen a los diferentes proyectos.

¿Alguna posibilidad de piratear este problema para obtener acceso al paquete interno? Más específicamente ControlResources classloader.

Preguntas relacionadas:

Localización de controles JavaFx

Respuestas

Evan Aug 28 2020 at 13:00

Ok, he perdido todo el día investigando este tema.

Respuesta corta: no es posible.

Respuesta larga

Puede usar add-exportsy add-openspara obtener acceso a com.sun.javafx.scene.control.skin.resources, pero solo funcionará si no está usando módulos con nombre, en otras palabras, su aplicación no debe ser modular.

<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 su aplicación está modularizada, obtendrá esto.

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)

Esto se debe a que la única forma de obtener acceso a los recursos que se encuentran en otro módulo es SPI ( docs aquí ). OpenJFX no se implementa ResourceBundleProviderpara proporcionar acceso a la internacionalización de controles, porque es parte de la API interna.

Por lo tanto, este problema solo puede ser resuelto por los desarrolladores de OpenJFX, pero a juzgar por los últimos registros de cambios de OpenJFX, están muy concentrados en corregir errores tipográficos, no en funciones.