Se ha denunciado esta presentación.

Java 9 - Módulos

0

Compartir

Próximo SlideShare
Presentacion Java
Presentacion Java
Cargando en…3
×
1 de 60
1 de 60

Java 9 - Módulos

0

Compartir

Descargar para leer sin conexión

Una primera revisión de los módulos incluidos en Java 9. Desde el planteamiento del problema inicial y su sintaxis con algún ejemplo de uso. Esta ponencia se ha impartido como parte de las charlas de la Semana de la Ingeniería Informática 2018 en la Escuela Politécnica Superior de la Universidad de Burgos.

Una primera revisión de los módulos incluidos en Java 9. Desde el planteamiento del problema inicial y su sintaxis con algún ejemplo de uso. Esta ponencia se ha impartido como parte de las charlas de la Semana de la Ingeniería Informática 2018 en la Escuela Politécnica Superior de la Universidad de Burgos.

Más Contenido Relacionado

Audiolibros relacionados

Gratis con una prueba de 14 días de Scribd

Ver todo

Java 9 - Módulos

  1. 1. JAVA 9 - MÓDULOS DEL INFIERNO DE LOS JAR,AL INFIERNO DE LOS MÓDULOS Raúl Marticorena Sánchez Área de Lenguajes y Sistemas Informáticos Depto. Ingeniería Civil Grupo de Investigación Admirable Grupo de Innovación Docente DIGIT y eNOL Semana de la Ingeniería Informática 8 de febrero de 2018, Escuela Politécnica Superior, CampusVena
  2. 2. TABLA DE CONTENIDOS •Planteamiento del problema •Módulos •Otras cuestiones adicionales (*) •Ejemplos 2
  3. 3. PLANTEAMIENTO DEL PROBLEMA De dónde venimos y a dónde vamos en Java
  4. 4. PRECEDENTES HISTÓRICOS • 1991 como Oak, luego Green y finalmente Java • Java 1.0 (mayo,1995, Sun Microsystems) presentación en SunWorld – JDK 1.0 enero 1996 • Inspirado en C++ • Write Once, Run Anywhere • Máquina virtual Año Versión Febrero, 1997 JDK 1.1 Diciembre, 1998 J2SE 1.2 Mayo, 2000 J2SE 1.3 Febrero, 2002 J2SE 1.4 Septiembre, 2004 J2SE 5.0 Diciembre, 2006 Java SE 6 Julio, 2011 Java SE 7 Marzo, 2014 Java SE 8 Septiembre, 2017 Java SE 9 Genericidad Anotaciones Enumeraciones Módulos Lambdas Inner classes Reflexión Asertos Abril, 2009 4
  5. 5. COMPILACIÓNY GENERACIÓN DE BINARIOS • Compilación: de código fuente (texto) a código “binario” (bytecodes) • Del concepto de clases (¿módulos?) en fichero fuente (.java) al concepto de clase (.class) • “Uno a uno” o “Uno a varios” 5
  6. 6. ORGANIZACIÓN LÓGICA/FÍSICA EN PAQUETES/DIRECTORIOS • Al igual que los ficheros de un disco duro… Ficheros .class (binarios) java lang util paquete subpaquete subpaquete clase 6
  7. 7. DISTRIBUCIÓN DE BINARIOS: FICHEROS .JAR • La estructura de paquetes y clases (directorios y ficheros .class) se “comprime” en un fichero .jar • Más simple de distribuir y “controlar” (no tanto ;)) java lang util java lang util “empaquetado” biblioteca 1.0.jar 7
  8. 8. ¿CÓMO BUSCAR LAS CLASES? • Concepto fundamental del CLASSPATH • Lista de directorios de búsqueda de clases (.class) • Ficheros .jar contenedores de paquetes y clases • Definido como: 1. Variable de entorno del S.O 2. Como argumento al comando del JDK biblioteca_A 1.0.jar biblioteca_B 2.0.jar bblioteca_C 2.3.jar NoSuchFieldError, NoSuchMethodError ClassNotFoundException NoClassDefFoundError 8
  9. 9. ¡Java es guay! 9
  10. 10. REALMENTE HAY UN INFIERNO… Artista: Hieronymus Bosch (El Bosco) El jardín de las Delicias Museo del Prado 10
  11. 11. EL INFIERNO DE LOS JAR • Si buscas en Google “jar hell” hay 17.900.000 resultados… • Curiosidad: si buscas en Google “dll hell” sólo hay 1.100.000 resultados • Problemas • Dependencias no públicas (no explícitas) • Dependencias transitivas • Quizás sólo se necesita una parte del jar • Sombreado de clases • Conflicto de versiones • Complicaciones con la carga dinámica de clase • Etc. biblioteca_X 1.0.0.jar biblioteca_X 1.0.0.jar biblioteca_X 1.0.0.jar biblioteca_X 1.0.0.jar biblioteca_X 1.0.0.jar biblioteca_X 1.0.0.jar biblioteca_X 1.0.0.jar biblioteca_X 1.0.0.jar biblioteca_X 1.0.0.jar biblioteca_X 1.0.0.jar biblioteca_X 1.0.0.jar En ejecución puede haber “sorpresas” con código compilado correctamente 11
  12. 12. ENCAPSULACIÓN DÉBIL • Acceso a paquetes públicos entre bibliotecas indiscriminadamente java lang util Biblioteca_X 1.0.jar public class java lang util Biblioteca_Y 1.0.jar Paquete “interno” Acceso permitido a detalles de implementación 12
  13. 13. ENCAPSULACIÓN DÉBIL • Se ha “abusado” del acceso a paquetes “no abstractos” vinculados a la implementación concreta (JDK-internal APIs) • Ej: com.sun.* o sun.* • Incluso usando bibliotecas “peligrosas”: • Ej: Uso de sun.misc.Unsafe para “cosas raras” (bajo nivel) en Java: • Crear un objeto sin usar un constructor • Acceso a memoria nativa • Lanzar excepciones comprobables no declaradas • Concurrencia nativa, etc. • Se pueden detectar esos usos peligrosos con el comando jdeps • Ej: jdeps --jdk-internals -R –cp lib/* mi-fichero.jar 13
  14. 14. HERRAMIENTAS AL RESCATE • Descarga bibliotecas (.jar) y gestiona dependencias • A partir de una declaración en formato XML • Ej: utilizamos JUnit 4.8.2 <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> <scope>test</scope> </dependency> </dependencies> 14
  15. 15. HERRAMIENTAS AL RESCATE • Tomando Ant y Maven como antecedentes • Descarga bibliotecas (.jar) y gestiona dependencias • A partir de una declaración en lenguaje Groovy • Estándar “de facto” en entornos como Android Studio • Ej: bibliotecas commons-collections y JUnit dependencies { compile group: 'commons-collections', name: 'commons-collections', version: '3.2.2' testCompile group: 'junit', name: 'junit', version: '4.+' } 15
  16. 16. Y OTROS PROBLEMAS ADICIONALES… EL ELEFANTE EN LA HABITACIÓN • Distribución de las aplicaciones depende del “pequeño” JDK / JRE • Excesivo tamaño del JDK/JRE • Dificultando la distribución • En particular para dispositivos con pocos recursos (pensando en IoT…) • Solución parcial con los Compact Profiles de la versión 8 de Java SE Embedded 8 • ¿A sustituir por los módulos de Java 9? • Curiosidad: problema en Android resuelto parcialmente con su propia MáquinaVirtual Java • Dalvik y ART Aplicación Java JDK/JRE 16
  17. 17. MÓDULOS Objetivos Sintaxis.Tipos y acceso Encapsulación fuerte ¿Y qué ocurre con la reflexión? Migración Pros y contras… con temas pendientes 17
  18. 18. • Proyecto Jigsaw • Inicialmente se iba a incluir en Java 8, pero se retrasó a Java 9… (complicaciones en su inclusión… ¡6 años!) • Objetivos • Encapsulación más fuerte • Definición más precisa de dependencias • Intento de escapar del infierno de la definición del CLASSPATH (“brittle classpath”) • Evitar errores en ejecución (NotClassDefFoundError) pese a tener código “bien compilado” • Java SE Platform, JDK y JRE más fácilmente escalable para dispositivos con menos recursos • Mejora de seguridad y mantenibilidad • Permitir mejoras de rendimiento. • Facilitar a los desarrolladores la construcción y mantenimiento de bibliotecas y aplicaciones de mayor tamaño para Java SE y EE • Etc. MÓDULOS 18
  19. 19. MÓDULOS • Se define DECLARATIVAMENTE un fichero module-info.java que indica: • 1) Nombre único del modulo (Ej: java.base, java.xml, java.logging, etc.) • 2) Módulos de los que depende • 3) Paquetes exportados para su uso por otros módulos • Y alguna otra cosa… • Al compilarse se generará el correspondiente module-info.class. • Aparece otro elemento externo muy importante… el MODULE-PATH Pero el CLASSPATH también sigue existiendo… 19
  20. 20. MÓDULOS Imágenes extraídas de: http://www.codenuclear.com/java-9-modularity-and-jigsaw-project/ 20
  21. 21. MÓDULOS • A) Exportan paquetes (exports) • Sólo las clases públicas de paquetes exportados son visibles en compilación y ejecución • El resto de clases públicas del modulo ya NO son accesibles • B) Declararan dependencias de uso (requires) de paquetes exportados de otros módulos (en compilación y ejecución) 21
  22. 22. CREANDO UN MÓDULO • Convención de nombres similar a los paquetes (nombre de dominio inverso) • Pero sin correspondencia con directorios y subdirectorios • Ej: es.ubu.lsi  se corresponde con un directorio raíz de nombre es.ubu.lsi • NO con una estructura de árbol de directorio es, subdirectorio ubu y subdirectorio lsi. • En el directorio raíz se incluye un fichero module-info.java • El nombre del módulo debe coincidir con el nombre del directorio “raíz” que lo contiene • Curiosidad: similar al caso de los package-info.java por paquete, aunque estos sólo cumplen un papel de documentación • Dentro de dicho directorio raíz tendremos una estructura de paquetes: • Normalmente se corresponde parcialmente a su vez con lo indicado en el nombre de módulo • NO es obligatoria esa correspondencia (aunque algunas fuentes bibliográficas lo recomiendan para evitar colisiones de nombres) • En concreto se dice que coincida con el “principal exported API package,” Esto puede crear una cierta confusión… +- es.ubu.lsi +- es +- ubu +- lsi 22
  23. 23. CREANDO UN MÓDULO • Ejemplo: src +- es.ubu.lsi +- module-info.java +- es +- ubu +- lsi +- util +- Log.java Nombre del módulo Estructura de paquetes, en correspondencia con el nombre de módulo. NO es obligatorio que coincida. Fichero con el nombre de módulo, módulos requeridos y exportaciones de paquetes Otros paquetes y ficheros fuente del módulo 23 OJO, ejemplo pensado para multimódulo
  24. 24. CONTENIDO DE MODULE-INFO.JAVA • Ejemplo: module-info.java module es.ubu.lsi { exports es.ubu.lsi.control; exports es.ubu.lsi.control.impl to es.ubu.comp; requires es.ubu.ingciv; } Requiere acceso a este módulo. Permite acceder a paquetes exportados de dicho módulo. Otros módulos que dependan de éste NO tienen acceso (NO transitivo) Nombre del módulo Exportación de paquetes. Necesario exportar subpaquetes, explícitamente Exportación calificada de subpaquete a un único módulo, es.ubu.comp en el ejemplo. 24
  25. 25. COMPILACIÓN: JAVAC • Para compilar se indica el directorio de destino del módulo: • Se puede indicar la localización de directorios contenedores de módulos: • Con el parámetro --module-path o –p. • Si son varios directorios se usa el separador (; o :) igual que con el classpath. javac –d bin/nombre.modulo @listaFicheros javac –-module-path bin –d bin/nombre.modulo @listaFicheros 25
  26. 26. MODOS DE COMPILACIÓN • A) Legado: usando básicamente el classpath, sin módulos explícitos (Java 8 o anteriores) • Todo el código en el unnamed module • B) Módulo simple • Sólo existe un módulo en el directorio de fuentes (src) • Puede ser necesario utilizar --module-path para compilar y ejecutar • C) Multi módulo • Varios módulos (directorios) en el directorio de fuentes (src) • Indicando en compilación el directorio con --module-source-path | ---src | module-info.java | ---ubu ---lsi MiClase.java ---src +---data.access | | module-info.java | | | ---data | Util.java | ---ui.app | module-info.java | ---app Main.java 26
  27. 27. EJECUCIÓN: JAVA • Se indica además la clase raíz en el módulo correspondiente con la opción –m (o --module): • Ej: • Se puede indicar la localización de módulos con el parámetro --module-path o –p • Si el módulo está contenido en un fichero .jar creado con la opción --main-class no es necesario indicar la clase raíz • Ej: java –-module-path bin –m nombre.modulo/paquete.subpaquete.ClaseRaiz java –-module-path bin –-module nombre.modulo/paquete.subpaquete.ClaseRaiz java –-module-path bin –-module nombre.modulo 27
  28. 28. EMPAQUETADO: JAR • Como en versiones previas, se sigue utilizando el comando jar • Necesario empaquetar cada módulo en su .jar • Incluso con solución multimódulo • Ej: • Podemos ver su contenido (ficheros contenidos) con la opción --list • Podemos ver su dependencias y exportaciones con --describe-module • Ej: jar -c -f mlibhola.mundo.proveedor.jar -C outputhola.mundo.proveedor . jar --describe-module --file mlibhola.mundo.proveedor.jar hola.mundo.proveedor jar:file:///C:/directorio/HolaMundo/mlib/hola.mundo.proveedor.jar/!module-info.class exports es.ubu.lsi requires java.base mandated 28 Ahora con un parámetro --module-version simplemente informativo
  29. 29. JDK API EN JAVA 9 • El propio JDK 9 tiene ahora una estructura modular • Sus clases se organizan en paquetes y módulos • TODOS los módulos importan implícitamente el módulo java.base. • Se recomienda revisar en <jdk-home>/src.zip la estructura actual. • Documentación en línea: • https://docs.oracle.com/javase/9/docs/api/overview-summary.html 29
  30. 30. JDK API EN JAVA 9 Módulo por defecto para todos 30
  31. 31. TIPOS DE MÓDULOS • 1) Módulo de aplicación con nombre (Named Application Module) • Contienen un fichero module-info.class con su definición • Incluidos en el MODULE-PATH • Exportan paquetes explícitamente • Requieren (leen) módulos explícitamente • No pueden requerir (leer) del módulo unnamed (no tiene nombre… evitamos depender del CLASSPATH) • 2) Automáticos • Ficheros .jar NO modularizados (sin module-info.class) que se incluyen al MODULE-PATH • Necesarios para permitir la migración de bibliotecas pre-Java 9 • ExportanTODOS sus paquetes implícitamente (también abiertos para reflexión…) • Requieren (leen)TODOS los módulos implícitamente • Java 9 genera un nombre de módulo automático: • A partir del nombre del fichero .jar o del Automatic-Module-Name en el MANIFEST.MF • Eliminando los números de versión (si existen) y reemplazando otros caracteres no alfanuméricos por puntos: • Ej: mongo-java-driver-3.3.0.jar  mongo.java.driver .jar Pre-Java 9 en MODULE_PATH Módulo Java 9 en MODULE_PATH 31
  32. 32. TIPOS DE MÓDULOS • 3) Módulo sin nombre (Unnamed Module) • Todos los .jar (modulares o no) y clases directamente en el CLASSPATH (estarán contenidos en un “Unnamed Module”) • Exportan TODOS sus paquetes implícitamente (también abiertos para reflexión…) • Requieren (leen) TODOS los módulos implícitamente • Al NO tener nombre, NO puede ser requerido en otros módulos. • 4) De plataforma (Platform Module) • Módulos propios del JDK • Resultado de la propia reestructuración de Java 9 en módulos • Ej: java.base como módulo básico Módulo Java 9 o .jar Pre-Java 9 y clases en el CLASSPATH Módulos JDK 32
  33. 33. ACCESO ENTRE TIPOS DE MÓDULOS Tipo Origen Exporta (exports) paquetes Puede leer (requires) módulos de.. Módulo de aplicación con nombre Cualquier JAR conteniendo un module-info.class en el module-path Explícitamente Aplicación con nombre Automático Plataforma Automáticos Cualquier JAR sin module-info.class en el module-path Implícitamente todos Aplicación con nombre Automático Sin nombre (unnamed) Plataforma Sin nombre Todos los JAR y clases en el classpath Implícitamente todos Aplicación con nombre Automáticos Plataforma De plataforma Dentro del JDK Explícitamente - 33
  34. 34. EL MÓDULO “SIN NOMBRE”: UNNAMED MODULE • Similar al paquete por defecto (default package) • Formado por clases y paquetes NO contenidos en módulos (módulo por defecto) sino en el CLASSPATH • Ej: todo el código Java 8 o previo que no se ha migrado (ni se migrará) a módulos Java 9 • Requiere: • Implícitamente todo módulo con nombre (bajo demanda, si lo necesitan) • Pueden leer cualquier módulo (con o sin nombre) • Clases Java 8 (o anteriores) pueden leer cualquier módulo Java 9 • Continuarán “funcionando” en Java 9 tanto en compilación como ejecución • Exporta: • Todos los paquetes implícitamente • Accesibles sólo para el módulo sin nombre • No se puede “requerir” desde otros módulos con nombre, porque NO tiene nombre 34 Java sigue cuidando mucho la ejecución de código “antiguo” sobre la nueva versión (backward)…no al revés
  35. 35. EL MÓDULO “SIN NOMBRE”: UNNAMED MODULE • Con el comando jdeps se pueden mostrar las dependencias de clases en el unnamed module • Nota o curiosidad: con una variante jdepscan para detectar uso de APIs deprecated (análisis estático) jdeps –s .bin 35
  36. 36. OTRA RAREZA: MÓDULOS RAÍZ (ROOT MODULE) • Módulos sin clases ni paquetes, sólo module-info.java… • Ej: módulo java.se • Indica dependencias TRANSITIVAS • Hace disponibles esos módulos para aquellos que requieren de java.se • NO es lo mismo que exportar paquetes • Al compilar el unnamed module, suele estar disponible un módulo raíz por defecto: • En JDK 9, el módulo java.se • Para cargar clases fuera de este grafo de módulos añadimos al compilar o ejecutar: • --add-modules nombre.modulo module java.se { requires transitive java.compiler; requires transitive java.datatransfer; requires transitive java.desktop; requires transitive java.instrument; requires transitive java.logging; requires transitive java.management; requires transitive java.management.rmi; requires transitive java.naming; requires transitive java.prefs; requires transitive java.rmi; requires transitive java.scripting; requires transitive java.security.jgss; requires transitive java.security.sasl; requires transitive java.sql; requires transitive java.sql.rowset; requires transitive java.xml; requires transitive java.xml.crypto; } 36
  37. 37. EL PROBLEMA DE LA ENCAPSULACIÓN DÉBIL PUBLIC ES DEMASIADO PUBLIC • ¿Qué teníamos hasta ahora? • Clases e interfaces de nivel superior: public o “amigable” (privado a nivel de paquete) • Nota: en clases e interfaces anidadas (dentro de otras) se puede usar además private o protected como con el resto de miembros de la clase • Encapsulación débil (Weak Encapsulation) • Los módulos introducen el concepto de encapsulación fuerte (Strong Encapsulation) • Clases públicas ya NO son accesibles desde otros módulos (y desde sus paquetes) • Ahora: • Sólo los tipos y propiedades públicas de los paquetes exportados son accesibles • Sólo son accesibles a los módulos que requieren dicho modulo • Otro nuevo nivel de acceso y encapsulación en Java 37
  38. 38. PROBLEMAS DEL USO DE MÓDULOS • Ahora NO todos los paquetes de los módulos de Java 9 son accesibles • Tip: --jdk-internals con jdeps… • Pero se puede “puentear” el sistema en línea de comandos: • Ejemplo: supongamos que usamos clases del paqute sun.security.util y sun.security.x509 desde un .jar pre-Java 9 (no modular) java -jar miaplicacion.jar ^ --add-exports java.base/sun.security.util=ALL-UNNAMED ^ --add-exports java.base/sun.security.x509=ALL-UNNAMED módulo Todos los módulos en el grafo de módulos y clases/jar del CLASSPATH paquete 38 Por el momento se permite con “avisos” pero en un futuro…
  39. 39. ¿Y QUÉ OCURRE CON LA “REFLEXIÓN”? • Java Reflection API permite la inspección y manipulación de clases e interfaces (métodos y atributos) en tiempo de ejecución • Sin conocer a priori (en tiempo de compilación) los tipos y/o nombres de las clases (con sus riesgos) • Fundamento de muchas bibliotecas muy útiles (Ej: Hibernate, JUnit,, Spring, etc.) • Uso avanzado que permite también “saltar barreras” (Ej: ¿acceso a private?, ¿modificar un final? Etc.) • Ejemplo: Integer dos = 2; // auto-boxing, inmutable Field value = Integer.class.getDeclaredField("value"); value.setAccessible(true); // "eliminamos" el final value.set(dos, 3); // cambiamos el valor if (1 + 1 != dos) { System.out.println("¡La hemos liado!"); } 39
  40. 40. ¿Y QUÉ OCURRE CON LA “REFLEXIÓN”? • Por defecto:AHORA la reflexión está “cerrada” entre módulos. • Sólo cuestiones básicas: Ej: Class.forName(…), Class.getDeclaredFields(), etc. • No uso de métodos sobre clase Field, Constructor, etc. (en java.lang.reflect) • Se puede “abrir” el acceso (total) sobre: • Módulo (open) • Paquete (opens) • Paquete para módulos concretos (opens to) • Adicionalmente desde línea de comandos con. • Finalmente con opción (deprecated) open module client.module{ requires framework.module; } module client.module{ opens some.client.package; requires framework.module; } module client.module{ opens some.client.package to framework.module; requires framework.module; } Ejemplo –-add-opens modulo/paquete=modulo --permit-illegal-access paquete.Clase 40
  41. 41. ROMPIENDO LA ENCAPSULACIÓN FUERTE • Opciones en compilación y ejecución: • --add-exports $module/$package=$readingmodule • Exporta el paquete al modulo indicado. • Si se establece $readingmodule a ALL-UNNAMED, todos los módulos en el grafo de módulos, y el código del CLASSPATH puede accede al paquete. Disponible en compilación y ejecución. • --add-opens $module/$package=$readingmodule • Abre el acceso completo con reflexión del paquete al módulo indicado. • Abre el paquete para reflexión profunda (deep reflection), todos sus tipos y miembros son accesibles con independencia de su modificador de acceso (incluso privados). 41
  42. 42. MIGRACIÓN DE FICHERO JAR NO MODULARIZADO A MÓDULO • Recordemos: módulos “automáticos” • Facilitar la migración de ficheros.jar NO modularizados “sin tocarlos mucho” • Modificando el fichero MANIFEST.MF se puede “extender” para comportarse como un módulo • Atributos nuevos: • Automatic-Module-Name: module.name – declara un nombre de módulo para un .jar no modularizado • Add-Exports: module/package – exporta el paquete de dicho módulo a todos los módulos sin nombre (unnamed modules) • Add-Opens: module/package – abre el paquete de dicho módulo a todos los módulos sin nombre (unnamed modules) 42
  43. 43. SITUACIÓN PARA LA MIGRACIÓN • Transición de Java pre-9  Java 9 con: • .class, • .jar NO modularizados • .jar semi-modularizados, • .jar modularizados • .jmod • Etc. • Con dos “infiernos” a manejar: • --class-path • --module-path 43
  44. 44. PROSY CONTRAS DE LOS MÓDULOS • Configuración “fiable” • Búsqueda de módulos frente a búsqueda individual de clases con el CLASSPATH: • En tiempo de lanzamiento, NO en tiempo de ejecución (Launch-time vs. Runtime) • Resolución transitiva de dependencias entre módulos • Frente al problema de las dependencias no explícitas y transitivas sin fin, con el CLASSPATH • Detección de sombreado de paquetes inmediata entre módulos • Mejora importante en la encapsulación • Mínimas dependencias entre módulos facilitando su evolución • NO se especifica número de versión de módulo: • ¡NO RESUELVE LOS PROBLEMAS DELVERSIONADO! (¿MODULE-HELL?) • Nota: OSGI sí que resuelve esto… 44
  45. 45. SE DEJA PENDIENTE EL PROBLEMA DE LAS VERSIONES… • The State of the Module System (2016) Mark Reinhold. http://openjdk.java.net/projects/jigsaw/spec/sotms/ “A module’s declaration does not include a version string, nor constraints upon the version strings of the modules upon which it depends.This is intentional: It is not a goal of the module system to solve the version- selection problem, which is best left to build tools and container applications.” 45
  46. 46. SE DEJA PENDIENTE EL PROBLEMA DE LAS VERSIONES… • Java Platform Module System: Requirements. DRAFT 2 (2015) Mark Reinhold • http://openjdk.java.net/projects/jigsaw/spec/reqs/02 “In other words, this specification need not define yet another dependency-management mechanism. Maven, Ivy, and Gradle have all tackled this difficult problem.We should leave it to these and other build tools, and container applications, to discover and select a set of candidate modules for a given library or application. The module system need only validate that the set of selected modules satisfies each module’s dependences.” 46
  47. 47. ¿REACCIONES? • IBM y RedHat no están contento (y Oracle responde) – mayo, 2017 • https://www.infoq.com/news/2017/05/no-jigsaw • https://www.infoworld.com/article/3194367/java/java-module-system-may-stall-platforms-next-release.html • https://www.infoworld.com/article/3194759/java/oracle-hits-back-at-modular-java-critics.html • Con una “tibia” acogida –mayo-abril, 2017 • http://mydailyjava.blogspot.com.es/2017/05/yet-another-jigsaw-opinion-piece.html • https://www.infoworld.com/article/3188454/java/the-true-impact-of-modular-java.html • O muy “tibia” – julio, 2017 • https://jaxenter.com/java-influencers-interview-2-135720.html • http://blog.joda.org/2017/05/java-se-9-jpms-automatic-modules.html • Y alguna ligera “bienvenida” – noviembre, 2017 • https://www.darwinrecruitment.com/blog/2017/11/java-9-review-what-was-all-the-fuss-about# 47
  48. 48. OTRAS CUESTIONES ADICIONALES Servicios Detección de Split Packages Enlazado (Link) 48
  49. 49. SERVICIOSY PROVEEDORES DE SERVICIO • Módulos desarrollados como Servicios y Proveedores de servicios: • A) Un modulo consumidor de servicio declara que usa (uses) una o más interfaces de servicio • Su implementación concreta será proporcionada en tiempo de ejecución por un modulo proveedor • B) Un modulo proveedor de servicio declara qué implementación concreta de la interfaz de servicio proporciona (provides … with…) • El cliente NO declara nada respecto al proveedor: • En tiempo de ejecución se indica el proveedor, como módulo adicional, en el module-path. • En el código del cliente se usa la API (ServiceLoader#load(AnInterface.class)) para obtener la implementación concreta disponible 49 Proveedor Cliente
  50. 50. SERVICIOSY PROVEEDORES DE SERVICIO • Otra opción: en el módulo proveedor de servicio se proporciona una clase proveedora que implementa un método público estático de nombre 'provider()’ • Dicho método retorna una instancia de la implementación del servicio • La clase proveedora NO implementa directamente la interfaz • Su método provider retorna un objeto de ese tipo • En el fichero module-info.java del proveedor, en la cláusula provides … with… • Se cambia en el with el nombre de la clase de implementación, por la clase proveedora. • Ventajas: • Más control sobre la inicialización de la implementación del servicio 50
  51. 51. SERVICIOS DESACOPLADOS: USO DE SERVICE LOADER • Ejemplo: module-info.java module es.ubu.lsi.log.service { requires es.ubu.lsi.service; exports es.ubu.lsi.log.service; provides es.ubu.lsi.service.LogService with es.ubu.lsi.log.service.LogService; } Módulo proveedor: provee la implementación de un servicio module es.ubu.lsi.consumer { requires es.ubu.lsi.service; uses es.ubu.lsi.service.LogService; } // Carga del proveedor en código… ServiceLoader.load(EventService.class); // load retorna un Iterable<T> con la lista de proveedores de dicha interfaz dada por los módulos disponibles Módulo consumidor: sin conocer el módulo ni la clase que provee la implementación del servicio 51
  52. 52. SPLIT PACKAGES • Paquetes con mismo nombre en distintas aplicaciones/librerías (.jar) • En Java pre-9 se permite • NO se permiten en los módulos (ni siquiera con paquetes no exportados) • Error generado en ejecución (en lanzamiento) NO en compilación • SÍ se permite con el unnamed module (por compatibilidad hacia atrás) 52
  53. 53. VOLVIENDO AL ELEFANTE EN LA HABITACIÓN • La distribución y ejecución de las aplicaciones depende del JRE (Java Runtime Environment) • Reducción del tamaño de los “ejecutables” • Previamente en Java: enlazado (“linkado”) dinámico • En Java 9 se puede enlazar estáticamente: • A) Herramientas de enlazado estático • Creando “imágenes” ejecutables • B) Herramientas de creación de jmod • Módulos en formato jmod JRE Java App 53
  54. 54. NUEVAS HERRAMIENTAS: JLINK • ¡En Java 9 se puede “linkar” ! • Fase posterior a la compilación generando una “imagen “ejecutable” • OJO: NO genera un “ejecutable” (.exe, .bin, etc.) • Genera una estructura de directorios “ejecutable” • TODOS los ficheros necesarios (JRE “customizado”) • Ejemplo: generar y ejecutar un “Hola mundo” jlink [options] --module-path modulepath --add-modules module [,module...] ├───bin │ └───server ├───conf │ └───security │ └───policy │ ├───limited │ └───unlimited ├───include │ └───win32 ├───legal │ └───java.base └───lib ├───security └───server jlink --module-path %JAVA_HOME%jmods;.mlib --add-modules hola.mundo.simple --output app // nos movemos al directorio .appbin y ejecutamos java -m hola.mundo.simple/es.ubu.lsi.HolaMundo Windows 54
  55. 55. NUEVAS HERRAMIENTAS: JLINK • Ejemplo: generar y ejecutar un “Hola mundo” con un lanzador jlink --module-path %JAVA_HOME%jmods;.mlib --add-modules hola.mundo.simple --output app --launcher launch= hola.mundo.simple/es.ubu.lsi.HolaMundo // nos movemos al directorio .appbin y ejecutamos launch ├───bin │ └───server ├───conf │ └───security │ └───policy │ ├───limited │ └───unlimited ├───include │ └───win32 ├───legal │ └───java.base └───lib ├───security └───server Imagen de unos 36 MB en Windows… 55
  56. 56. NUEVAS HERRAMIENTAS: JMOD • Nuevo formato de fichero JMOD • Creados con el comando jmod: • Pensados para: • Módulos con bibliotecas nativas u otros ficheros de configuración (no adecuados o compatibles en un .jar) • Módulos para enlazar (linkar) a una imagen ejecutable • NO sustituye al formato .jar • El propio JDK distribuye ficheros jmod: • Ver: %JAVA_HOME/jmods • Se pueden crear y distribuir nuestros propios módulos en este formato • Ej: jmod (create|extract|list|describe|hash) [options] jmod-file jmod create --class-path mods/com.greetings --cmds commands --config configfiles --header-files src/h --libs lib --main-class com.greetings.Main --man-pages man --module-version 1.0 --os-arch "x86_x64" --os-name "Mac OS X" --os-version "10.10.5" greetingsmod 56
  57. 57. BIBLIOGRAFÍA • Documentación en línea de Java 9 (2017) Oracle © https://docs.oracle.com/javase/9/index.html • Getting Started with Java 9 Modules - ConSol Labs. (2017) Jens Klingen. 13 de febreo de 2017. https://labs.consol.de/development/2017/02/13/getting-started-with-java9-modules.html#how-to-declare-a-java-9-module • Java 9 Modules Quick Start Example (2017) http://www.logicbig.com/tutorials/core-java-tutorial/modules/quick-start/ • Musings about Jigsaw – The Java 9 Module System (2017) Sebastian Zarnekow. https://blogs.itemis.com/en/musings-about-jigsaw- the-java-9-module-system • Reflection vs Encapsulation - blog@CodeFX (2017) https://blog.codefx.org/java/reflection-vs-encapsulation/ • The State of the Module System (2016) Mark Reinhold. http://openjdk.java.net/projects/jigsaw/spec/sotms/ • Nota: deprecated, aunque los conceptos fundamentales no han cambiado, la sintaxis sí. • Understanding Java 9 Modules (2017) Paul Deitel. https://www.oracle.com/corporate/features/understanding-java-9-modules.html • WillThere Be Module Hell? (2017) https://blog.codefx.org/java/dev/will-there-be-module-hell/ 57
  58. 58. ALGUNOS RECURSOS DE INTERÉS • Java 9:The Modular Java Platform and Project Jigsaw • https://www.youtube.com/watch?v=y8bpKYDrF5I • Java Platform Module System Cheat Sheet (2017) Oleg Shelajev. ZeroTurnaround. Disponible en https://zeroturnaround.com/rebellabs/java-9- modules-cheat-sheet/ • PDF descargable: http://files.zeroturnaround.com/pdf/RebelLabs-Java-9-modules-cheat-sheet.pdf • Java Platform, Standard Edition Oracle JDK 9 Migration Guide (2018) Oracle • Disponible en: https://docs.oracle.com/javase/9/migrate/toc.htm • Modular Development with JDK 9 • https://www.youtube.com/watch?v=gtcTftvj0d0 • Modules in One Lesson by Mark Reinhold • https://www.youtube.com/watch?v=rFhhLXcOBsk • Project Jigsaw in JDK 9: Modularity ComesTo Java - Simon Ritter • https://www.youtube.com/watch?v=Ks7J_qQVR7Y 58
  59. 59. ¡MUCHAS GRACIAS POR SU ATENCIÓN! 59
  60. 60. CRÉDITOS 60 Autor: Raúl Marticorena Sánchez Reconocimiento – NoComercial – CompartirIgual (by-nc-sa): No se permite un uso comercial de la obra original ni de las posibles obras derivadas, la distribución de las cuales se debe hacer con una licencia igual a la que regula la obra original. Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial- CompartirIgual 4.0 Internacional.

×