– Lembra daquela história de módulo sem nome do Java 9?
– O módulo criado automaticamente pelo Java 9 ao executar um JAR não modularizado?
– Isso. Um “módulo sem nome” depende do módulo java.se
, que tem como dependências os módulos java.logging
, java.sql
, java.rmi
e mais uma penca, né?
– Mas não puxa o módulo java.se.ee
, que teria o JAXB no módulo javax.xml.bind
e o JAX-WS no java.xml.ws
e mais alguns…
– Exato. Conversamos sobre isso daquela outra vez quando deu o NoClassDefFoundError
de JAXBException
, né?
– Isso mesmo!
– O que você acha que aconteceria com esse código?
import javafx.application.Application; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.ButtonType; import javafx.stage.Stage; public class OlaMundo extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { Alert alerta = new Alert(AlertType.INFORMATION, "Funcionou?", ButtonType.OK); alerta.setHeaderText("Janelinha do JavaFX"); alerta.setResizable(true); alerta.showAndWait(); } }
– Usa o JavaFX, né? Tem declaração de módulo?
– Não. Tá no “módulo sem nome”.
– Então acho que não compilaria no Java 9.
E, se compilado no Java 8, ao rodar com Java 9 daria NoClassDefFoundError
já nesse primeiro import
, da classe javafx.application.Application
.
Acho que teria que colocar --add-modules javafx.controls
, pra rodar no Java 9…
– E por que você acha isso?
– Porque o “módulo sem nome” depende do módulo java.se
mas não dos módulos do JavaFX, como o javafx.controls
que mencionei…
– Pois compila e roda no Java 9 sim! E, se compilado no Java 8, roda no Java 9 sim! Veja só:
– Eita! Que surpreendente!
– Pois é!
– E porque acontece isso?
– No fim das contas, o “módulo sem nome” não puxa só o java.se
.
A grande questão é o mecanismo de module resolution do Java 9.
Essa resolução de módulos é feita pelo JDK/JRE 9 pra descobrir qual módulo depende de qual, em compilação e também em execução.
A primeira coisa é descobrir quais são os módulos iniciais, ou os root modules. Depois, a partir desses root modules, são verificadas suas dependências, as dependências das dependências e assim por diante, recursivamente…
Pra um “módulo sem nome”, um dos root modules é o java.se
. Mas há também os systems modules. Entre esses, os do JavaFX.
– Mas não o java.se.ee
…
– Exato! O módulos do JAXB e do JAX-WS não ficam disponíveis, por exemplo…
– Tem algum comando pra você ver quais os módulos disponíveis?
– Tem! É só você mandar um:
java --show-module-resolution
Vai ter como resultado algo como:
root jdk.management.jfr jrt:/jdk.management.jfr root jdk.jdi jrt:/jdk.jdi root javafx.web jrt:/javafx.web root jdk.xml.dom jrt:/jdk.xml.dom root jdk.jfr jrt:/jdk.jfr root jdk.packager.services jrt:/jdk.packager.services root jdk.httpserver jrt:/jdk.httpserver root javafx.base jrt:/javafx.base root jdk.net jrt:/jdk.net root javafx.controls jrt:/javafx.controls root jdk.management.resource jrt:/jdk.management.resource root java.se jrt:/java.se root jdk.compiler jrt:/jdk.compiler root jdk.jconsole jrt:/jdk.jconsole root jdk.attach jrt:/jdk.attach ...
Na real, tem bem mais coisa na saída desse comando…
– Ó lá no meio o javafx.controls
e o java.se
.
– Isso mesmo!
– Na verdade, a coisa é bem mais complicada que isso. Dá pra ter uma ideia dos detalhes na documentação do pacote java.lang.module.
– Esse pacote é pra quê?
– Pra manipular módulos programaticamente.
– Melhor deixar isso pra depois, né?
– Ô se é!
O livro The Java Module System, de Nicolei Parlog, tem uma descrição mais aprofundada na seção “8.2.2 Module resolution for the unnamed module”.
Lá tem a seguinte figura:
