Saltar al contenido

Introducción al Sistema de Módulos de la Plataforma Java Parte 2

Añadamos una simple interfaz gráfica a nuestro generador de citas como otro módulo.

Crear otro directorio de nivel superior com.example.gui con la siguiente clase:

Introducción al Sistema de Módulos de la Plataforma Java Parte 2
Introducción al Sistema de Módulos de la Plataforma Java Parte 2
1234567891011121314151617181920212223packagecom.example.gui;importjavafx.application.Application;importjavafx.scene.*;importjavafx.stage.Stage;publicclassQuoteFxAppextendsApplication{@Overridepublicvoidstart(Stage primaryStage)throwsException{ primaryStage. setTitle("Citas");Etiqueta etiqueta =newLabel("Una cita");Escena escena =newScene(label,500,200); primaryStage.setScene(scene); primaryStage.show();}publicstaticvoidmain(String[] args){Application.launch(args);}}

java

Y el siguiente archivo module-info.java:

12module com.example.gui {}

Cuando ejecutas a Javac para compilar los archivos:

1javac -d out module-info.java com/example/gui/QuoteFxApp.java

Estos errores aparecerán:

1234567891011121314151617181920comejemploguiNQuoteFxApp.java:3: error: el paquete javafx.application no es visibleimport javafx.application.Application; ^ (el paquete javafx.application se declara en el módulo javafx.graphics, pero el módulo com.example. gui no lo lee)comejemploguiQuoteFxApp.java:4: error: package javafx.scene no es visibleimport javafx.scene.Scene; ^ (el paquete javafx.scene se declara en el módulo javafx.graphics, pero el módulo com.ejemplo.gui no lo lee)comejemploguiQuoteFxApp.java:5: error: package javafx. scene.control no es visibleimport javafx.scene.control.Label; ^ (el paquete javafx.scene.control se declara en el módulo javafx.controls, pero el módulo com.example.gui no lo lee)comejemploguiNQuoteFxApp.java:6: error: paquete javafx.stage no es visibleimportar javafx. stage.Stage; ^ (el paquete javafx.stage se declara en el módulo javafx.graphics, pero el módulo com.example.gui no lo lee)comejemploguiQuoteFxApp.java:10: error: el método no anula o implementa un método de un supertipo @Override ^5 errores

Los paquetes de JavaFX no son visibles. Necesitamos hacer referencia a los módulos javafx.graphics y javafx.controls. ¿Pero por qué?

La razón de esto es que el JDK se ha modularizado y nuestra aplicación necesita declarar qué módulos del JDK necesita.

Pero, ¿por qué no hemos obtenido ningún error en el ejemplo anterior? No obtuvimos ningún error porque las clases que usamos estaban incluidas en el módulo java.base, que se añade por defecto a todas las aplicaciones modulares.

Fíjese que esto sólo ocurre en aplicaciones modulares. Java 9 es compatible con versiones anteriores; si no incluye un archivo module-info.java en su aplicación, todo funcionará como en las versiones anteriores de Java. Si compila la aplicación sin module-info.java, verá que no se producen errores:

1javac -d out com/example/gui/QuoteFxApp.java

Pero cuando trabajamos con módulos, necesitamos requerir los módulos JavaFX que nuestra aplicación necesita en module-info.java:

123module com.example.gui { requiere javafx.controls;}

Esta vez, Javac se ejecutará con éxito.

Sin embargo, note que sólo requerimos javafx.controls, no javafx.graphics como los mensajes de error mencionados.

Esto se debe a que si utilizas el módulo javafx.controls, lo más probable es que también utilices el javafx.graphics, por lo que javafx.controls declara este módulo como una dependencia transitiva :

12345modulo javafx.controls { ... requiere gráficos javafx.graphics transitivos; ...}

Por supuesto, puedes añadir explícitamente requires javafx.graphics a tu archivo module-info.java pero no es obligatorio, lo obtienes automáticamente.

Por cierto, si quieres ver todos los módulos del JDK, el directorio de instalación del JDK contiene un subdirectorio llamado jmods. Convenientemente, podemos usar la herramienta jmod para listar el contenido de estos archivos JMOD.

En mi máquina de Windows, para ver los detalles del módulo javafx.controls, ejecuto:

1jmod describe "C:\N- Archivos de ProgramaN-JavaN-jdk-9N-jmodsNjavafx.controls.jmod"

Siguiendo adelante, nuestros problemas no han terminado. Si ejecutamos el programa con:

1java --modulo-path out --modul com.example.gui/com.example.gui.QuoteFxApp

Nos dará el siguiente error:

1java.lang.IllegalAccesoExcepción: class com.sun.javafx.application.LauncherImpl (en módulo javafx.graphics) no puede acceder a class com.example.gui.QuoteFxApp (en módulo com.example.gui) porque el módulo com.example.gui no exporta com.example.gui al módulo javafx.graphics

JavaFX necesita acceso a nuestra clase QuoteFxApp, así que tenemos que conceder el acceso explícitamente exportando el paquete com.example.gui de esta manera:

12345modulo com.example.gui { ... exporta com.example.gui;}

Sin embargo, así es como funciona JavaFX y probablemente no queremos que ningún otro módulo acceda a nuestro paquete. Para casos como este, podemos usar una exportación cualificada :

12345module com.example.gui { ... exporta com.example.gui a javafx.graphics;}

De esta manera, sólo los módulos listados (en este caso sólojavafx.graphics) pueden acceder al paquete com.example.gui. Nuestra aplicación debería funcionar ahora:

Habiendo aprendido a requerir/exportar otros módulos, la integración del módulo de citas de programación y el módulo GUI debería ser fácil.

Primero, en el módulo com.example.programming, exporta su paquete:

123modulecom.example.programming{exportscom.example.programming;}

java

Compilar las clases y empaquetarlas como un archivo JAR una vez más. Podemos copiar este JAR a un directorio de acceso fácil.

A continuación, modifique la clase QuoteFxApp para usar ProgrammingQuotes:

123456789101112131415...importcom ejemplo.de.programación.ProgramaciónQuotes;...publicclassQuoteFxAppextendsApplication{@Overridepublicvoidstart(Stage primaryStage)throwsException{...Label label =newLabel(newProgrammingQuotes().getQuote());...}...}

java

Requiere el módulo de programación com.example.programming:

12345module com.example.gui { ... ...}

Compilar el módulo com.example.gui con la opción module path para que pueda localizar el módulo de programación com.example.programming (que en este caso, se encuentra en el directorio lib):

1javac -d out --module-path ../lib module-info.java com/example/gui/QuoteFxApp.java

Finalmente, ejecute la aplicación usando, una vez más, la ruta de módulos (recuerde, el carácter separador de rutas para Windows es ;. Use : para Linux/Mac):

1java --modulo-path out;../lib --modulo-com.example.gui/com.example.gui.QuoteFxApp

Fíjese que si omite el directorio lib en la ruta del módulo, la aplicación no se ejecutará:

123java --module-path out --module com.example.gui/com.example.gui.QuoteFxAppError ocurrió durante la inicialización de la capa de arranquejava.lang.module.FindException: Módulo com.example.programación no encontrada, requerido por com.example.gui

Esto resuelve, en parte, el problema del infierno de JAR/classpath.