No se han encontrado resultados

Su búsqueda no coincide con ningún resultado.

Le sugerimos que pruebe lo siguiente para poder encontrar lo que está buscando:

  • Verifique la ortografía de su búsqueda de palabras clave.
  • Utilice sinónimos para la palabra clave que escribió; por ejemplo, intente con “aplicación” en lugar de “software”.
  • Pruebe con una de las búsquedas populares que se muestran a continuación.
  • Comience una nueva búsqueda.
Tendencias de preguntas

 

Java 9 | Extracto

Descripción de Java 9 Modules

Qué son y cómo utilizarlos

Por Paul Deitel


Paul Deitel

Paul Deitel

En este artículo, presento el sistema Java 9 Platform Module System (JPMS), la nueva tecnología de ingeniería de software más importante en Java desde su creación. La modularidad, el resultado de Project Jigsaw, ayuda a los desarrolladores de todos los niveles a ser más productivos a medida que crean, mantienen y evolucionan sistemas de software, especialmente sistemas de gran tamaño.

¿Qué es un módulo?

Modularity agrega un mayor nivel de agregación por encima de los paquetes. El nuevo elemento de idioma clave es el módulo, un grupo reutilizable con nombre único de paquetes relacionados, así como recursos (como imágenes y archivos XML) y un descriptor de módulo que especifica

  • el nombre del módulo
  • las dependencias del módulo (es decir, de otros módulos de los que depende este módulo)
  • los paquetes que pone explícitamente a disposición de otros módulos (todos los demás paquetes del módulo no están disponibles implícitamente para otros módulos)
  • los servicios que ofrece
  • los servicios que consume
  • a qué otros módulos permite reflexión

Historial

La plataforma Java SE abarca desde 1995. Ahora hay aproximadamente 10 millones de desarrolladores que lo utilizan para crear todo, desde aplicaciones pequeñas para dispositivos restringidos por recursos, como los del Internet de las cosas (IdC) y otros dispositivos incrustados, hasta sistemas esenciales para el negocio y críticos a gran escala. Existe una gran cantidad de código antiguo, pero hasta ahora, la plataforma Java ha sido principalmente una solución monolítica única para todos. A lo largo de los años, se han realizado varios esfuerzos encaminados a modularizar Java, pero ninguno se utiliza mucho, y ninguno se podría utilizar para modularizar la plataforma Java.

La modularización de la plataforma Java SE ha supuesto un reto de implantación y el esfuerzo se ha prolongado durante muchos años. JSR 277: Java Module System se propuso originalmente en 2005 para Java 7. Este JSR fue reemplazado posteriormente por JSR 376: Java Platform Module System y dirigido a Java 8. La plataforma Java SE ahora está modularizada en Java 9, pero solo después de que Java 9 se retrasara hasta septiembre de 2017.

Objetivos

Cada módulo debe indicar explícitamente sus dependencias.

Según JSR 376, los objetivos clave de la modularización de la plataforma Java SE son

  • COnfiguración confiable: Modularity proporciona mecanismos para declarar explícitamente dependencias entre módulos de una manera que se reconoce tanto en tiempo de compilación como en tiempo de ejecución. El sistema puede realizar un recorrido virtual por estas dependencias para determinar el subjuego de todos los módulos necesarios para soportar la aplicación.
  • Encapsulación fuerte: los paquetes de un módulo son accesibles para otros módulos solo si el módulo los exporta explícitamente. Incluso entonces, otro módulo no puede utilizar esos paquetes a menos que indique explícitamente que requiere las capacidades del otro módulo. Esto mejora la seguridad de la plataforma porque los posibles atacantes pueden acceder a menos clases. Puedes darte cuenta de que la modularidad te ayuda a dar con diseños más limpios y más lógicos.
  • Plataforma Java escalable: antes, la plataforma Java era un monolito formado por un gran número de paquetes, lo que dificultaba el desarrollo, el mantenimiento y la evolución. No se podía subajustar fácilmente. La plataforma ahora está dividida en 95 módulos (este número puede cambiar a medida que evoluciona Java). Puedes crear tiempos de ejecución personalizados que incluyan únicamente los módulos que necesitas para tus aplicaciones o los dispositivos a los que te diriges. Por ejemplo, si un dispositivo no admite GUI, puede crear un tiempo de ejecución que no incluya los módulos de GUI y reducir significativamente el tamaño del tiempo de ejecución.
  • Mayor integridad de la plataforma: antes de Java 9, era posible utilizar muchas clases en la plataforma que no estaban diseñadas para ser utilizadas por las clases de una aplicación. Con una encapsulación sólida, estas API internas se encapsulan y ocultan verdaderamente a las aplicaciones que utilizan la plataforma. Esto puede hacer que la migración de código heredado a Java 9 modularizado sea problemática si tu código depende de API internas.
  • Rendimiento mejorado: JVM utiliza varias técnicas de optimización para mejorar el rendimiento de la aplicación. JSR 376 indica que estas técnicas son más eficaces cuando se sabe de antemano que los tipos requeridos están ubicados solo en módulos específicos.

Listado de los módulos de JDK

Un aspecto crucial de Java 9 es dividir JDK en módulos para admitir varias configuraciones. (Consulte "JEP 200: El JDK modular". Todos los JEP y JSR de modularidad Java se muestran en la Tabla 1.) Mediante el comando java de la carpeta bin de JDK con la opción --list-modules, como en: 

java --list-modules

muestra el juego de módulos de JDK, que incluye los módulos estándar que implementan la especificación de Java Language SE (nombres que comienzan con java), módulos JavaFX (nombres que comienzan con javafx), módulos específicos de JDK (nombres que comienzan con jdk) y módulos específicos de Oracle (nombres que comienzan con oracle). Cada nombre de módulo va seguido de una cadena de versión: @9 indica que el módulo pertenece a Java 9.

Declaraciones de módulo

Como hemos mencionado, un módulo debe proporcionar su descriptor: metadatos que especifiquen las dependencias del módulo, los paquetes que el módulo pone a disposición de otros módulos, y mucho más. Un descriptor de módulo es la versión compilada de una declaración de módulo que se define en un archivo denominado module-info.java. Cada declaración de módulo comienza con la palabra clave module, seguida de un nombre de módulo único y un cuerpo de módulo entre llaves, como se muestra en:

Una motivación clave del sistema de módulos es la encapsulación fuerte.

módulo modulename {
}

El cuerpo de la declaración del módulo puede estar vacío o puede contener varias directivas de módulo, comorequires, exports, provides…with, uses y opens (nos detendremos en cada una de ellas). Como verá más adelante, la compilación de la declaración del módulo crea el descriptor del módulo, que se almacena en un archivo denominado module-info.class en la carpeta raíz del módulo. Aquí presentamos brevemente cada directiva de módulo. Después de eso, presentaremos declaraciones de módulos reales.

Las palabras clave exports, module, open, opens, provides, requires, uses, with, así como to y transitive, que introducimos más adelante, son palabras clave restringidas. Son palabras clave solo en declaraciones de módulo y se pueden utilizar como identificadores en cualquier otro lugar del código.

requieres. Una directiva de módulo requires especifica que este módulo depende de otro módulo: esta relación se denomina dependencia de módulo. Cada módulo debe indicar explícitamente sus dependencias. Cuando el módulo A requires módulo B, se dice que el módulo A read módulo B y el módulo B es read by módulo A. Para especificar una dependencia en otro módulo, utilice requires, como en:

requiere modulename;

También hay una directiva requires static para indicar que un módulo es necesario en tiempo de compilación, pero es opcional en tiempo de ejecución. Esto se conoce como una dependencia opcional y no se tratará en esta introducción.

requiere legibilidad implícita transitiva. Para especificar una dependencia en otro módulo y para asegurarse de que otros módulos que leen el módulo también lean esa dependencia, conocida como lectura implícita, utilice requires transitive, como en el siguiente ejemplo:

requiere modulename transitivo;

TeN en cuenta la siguiente directiva en la declaración del módulo java.desktop:

requiere java.xml transitivo; 

En este caso, cualquier módulo que lee java.desktop también lee de forma implícita java.xml. Por ejemplo, si un método del módulo java.desktop devuelve un tipo del módulo java.xml, el código de los módulos que leen java.desktop depende de java.xml. Sin la directiva requires transitive en la declaración del módulo de java.desktop, dichos módulos dependientes no se compilarán a menos que lean explícitamente java.xml.

Según JSR 379, los módulos estándar de Java SE deben otorgar legibilidad implícita en todos los casos, como el que se describe aquí. Además, aunque un módulo estándar Java SE puede depender de módulos no estándar, no debe otorgarles legibilidad implícita. Esto garantiza que el código, dependiendo solo de los módulos estándar Java SE, se pueda transportar en las implantaciones de Java SE.

exports and exports…to. Una directiva de módulo exports especifica uno de los paquetes del módulo cuyos tipos public (y sus tipos public y protected anidados) deben ser accesibles para el código en todos los demás módulos. Una directiva exports…to permite especificar en una lista separada por comas exactamente qué código de módulo o módulos puede acceder al paquete exportado, lo que se conoce como exportación calificada

uses. Una directiva de módulo uses especifica un servicio utilizado por este módulo, lo que convierte el módulo en un consumidor de servicio. Un servicio es un objeto de una clase que implementa la interfaz o amplía la clase abstract especificada en la directiva uses.

proporciona... con. Una directiva de módulo provides…with especifica que un módulo proporciona una implementación de servicio, lo que hace que el módulo sea un proveedor de servicios. La parte provides de la directiva especifica una interfaz o clase abstract que se muestra en la directiva uses de un módulo y la parte with de la directiva especifica el nombre de la clase de proveedor de servicios que implements la interfaz o extends la clase abstract.

open, opens, and opens…to. Antes de Java 9, se podría utilizar la reflexión para obtener información sobre todos los tipos de un paquete y todos los miembros de un tipo, incluso sus miembros private, tanto si deseara permitir o no esta capacidad. Por lo tanto, nada estaba realmente encapsulado.

Una motivación clave del sistema de módulos es la encapsulación fuerte. De manera predeterminada, un tipo de un módulo no es accesible para otros módulos a menos que sea de tipo público y exporte su paquete. Solo expone los paquetes que desea exponer. Con Java 9, esto también se aplica a la reflexión.

Permitir acceso de solo tiempo de ejecución a un paquete. Una directiva de módulo de apertura del formulario

opens package

indica que los tipos public de un paquete específico (y sus tipos public y protected anidados) son accesibles para codificar en otros módulos sólo en tiempo de ejecución. Además, se puede acceder a todos los tipos del paquete especificado (y todos los miembros de los tipos) mediante la reflexión.

Permitir el acceso solo de tiempo de ejecución a un paquete por módulos específicos. Una directiva de módulo opens…to del formulario

abre el paquete a una lista de módulos separada por comas

indica que los tipos public de un paquete específico (y sus tipos public y protected anidados) son accesibles para codificar en los módulos enumerados sólo en tiempo de ejecución. Se puede acceder a todos los tipos del paquete especificado (y todos los miembros de los tipos) mediante el reflejo del código en los módulos especificados.

Permitir acceso de solo tiempo de ejecución a todos los paquetes de un módulo. Si se debe poder acceder a todos los paquetes de un módulo determinado en tiempo de ejecución y mediante el reflejo de todos los demás módulos, puede open todo el módulo, como en:

módulo abierto modulename {
// directivas de módulo

Valores predeterminados de reflexión

Por defecto, un módulo con acceso reflexivo en tiempo de ejecución a un paquete puede ver los tipos public del paquete (y sus tipos public y protected anidados). Sin embargo, el código de otros módulos puede acceder a todos los tipos del paquete expuesto y todos los miembros dentro de esos tipos, incluidos los miembros private a través de setAccessible, como en versiones anteriores de Java.

Para obtener más información sobre setAccessible y el reflejo, consulta la documentación de Oracle.


Paul Deitel, CEO y director técnico de Deitel & Associates, es un graduado de MIT con 35 años de experiencia en computación. Es campeón de Java y ha estado programando en Java durante más de 22 años. Él y su coautor, el Dr. Harvey M. Deitel, son los autores de contenidos sobre lenguaje de programación más vendidos del mundo. Paul ha impartido cursos de programación en Java, Android, iOS, C#, C++, C e Internet a clientes del sector, del gobierno y del mundo académico.


NOTA: Este artículo se ha extraído de la Revista Java de septiembre a octubre de 2017.

Más información