Módulos
Módulos
• A partir de Java 9 disponemos de un mecanismo para
restringir en tiempo de compilación el acceso a un conjunto
de paquetes.
• Antes de Java 9 esto no se podía impedir, ya que aunque el
programador utilizara el modificador de acceso private, a
través del API Reflection era posible acceder.
• Por tanto, los módulos son otro nivel de acceso adicional,
para favorecer el encapsular y segregar responsabilidades.
2
Módulos
• Los módulos forman parte del proyecto Jigsaw, el cual ha
tardo 10 años en materializarse.
• Ha sido todo un hito, puesto que ha permitido modularizar la
JDK, haciéndola más flexible, lo cual es fundamental para
adaptarse a las plataformas de hoy en día: cloud, móviles,
etc.
• Antes de Java 9 existía un problema conocido como
classpath hell: dado que los JAR’s no tenían versioning
nos podíamos encontrar en el classpath con dos versiones
distintas de una misma clase, con lo que no se podía
garantizar cuál de ellas funcionaría en runtime.
3
Módulos
• Los módulos tienen versioning.
• Si quisiéramos crear un módulo para una librería,
entendiendo una librería como un conjunto de paquetes
jerarquizados, tendríamos que crear un fichero llamado
module-info.java en la raíz del código fuente.
• En este fichero tendríamos que indicar:
– Nuestra API pública: qué es accesible externamente.
– Nuestra API privada: realmente no hay que indicarlo ya que por
omisión todo lo que no se explicite público es privado.
– Dependencias que tiene nuestra librería.
4
Módulos
Ejemplo de fichero module-info.java:
• Nombre del módulo: org.infinispan.multimap
• API pública: org.infinispan.multimap.api.embedded
• Dependencias:
– org.infinispan.common
– org.infinispan.core
5
Módulos
• El resto de paquetes, por el hecho de no estar aquí
declarados como exportables, no serían ni visibles ni
accesibles.
• Si se intentase acceder daría un error en el modulepath
(que no es lo mismo que el classpath).
6
Módulos
• Podemos indicar dependencias transitivas para escribir
menos.
• Por ejemplo si org.infinispan.core depende de
org.infinispan.common, podemos indicar que se requiere
de manera transitiva de org.infinispan.core
7
Módulos
• También podemos afinar en cuanto a quién se exporta qué.
• Por ejemplo, lasiguiente figura indica que
org.infinispan.manager.impl solo es accesible para el
módulo org.infinispan.multimap.impl y para nadie más.
8
Módulos
• Una cosa que tenemos que tener muy clara es que lo
anterior solo funciona si utilizamos el modulepath.
• Si ponemos la librería en el classpath, entonces todo lo
visto no aplica, esto es, tendremos acceso directo a todo lo
que no sea private (y con el API Reflection) incluso a lo
private).