Como obter acesso ao módulo Java não exportado?

Aug 27 2020

Preciso localizar os controles integrados do JavaFX. Antes do Jigsaw, havia maneiras de fazer isso:

  1. Via arquivo de propriedades adicionais que deve ser colocado no com.sun.javafx...pacote
  2. Via API de reflexão, como mostrado aqui

Ambos os métodos não são compatíveis com módulos Java, pois com/sun/javafx/scene/control/*não fazem parte da API pública e não há como criar dois pacotes com nome idêntico mesmo que pertençam a projetos diferentes.

Alguma chance de hackear esse problema para obter acesso ao pacote interno? Mais especificamente, carregador de classe ControlResources .

Perguntas relacionadas:

Localizando controles JavaFx

Respostas

Evan Aug 28 2020 at 13:00

Ok, perdi o dia inteiro cavando esse tópico.

Resposta curta: não é possível.

Resposta longa

Você pode usar add-exportse add-openspara obter acesso ao com.sun.javafx.scene.control.skin.resources, mas só funcionará se você não estiver usando módulos nomeados, ou seja, seu aplicativo não deve ser modularizado.

<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 seu aplicativo for modularizado, você conseguirá isso.

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)

Isso ocorre porque a única maneira de obter acesso aos recursos que estão localizados em outro módulo é o SPI ( docs aqui ). OpenJFX não implementa ResourceBundleProviderpara fornecer acesso à internacionalização de controles, pois faz parte da API interna.

Portanto, esse problema só pode ser resolvido por desenvolvedores OpenJFX, mas, a julgar pelos últimos changelogs do OpenJFX, eles estão altamente concentrados em corrigir erros de digitação, não em recursos.