EIN GEDULDSSPIEL! DAS 1000-MODULEPUZZLE FÜR ENTWICKLER. DAS NEUE MODULSYSTEM JIGSAW IN JAVA 9 17. FEBRUAR 2017 | DR. RÜDIGER GRAMMES, MARTIN LEHMANN, DR. KRISTINE SCHAAL | FRANKFURTER ENTWICKLERTAG 1 Copyright © Accso – Accelerated Solutions GmbH 2 Copyright © Accso – Accelerated Solutions GmbH Abstract https://entwicklertag.de/frankfurt/2017/ein-geduldsspiel-das-1000-module-puzzle-f%C3%BCr-entwickler-das-neue-modulsystem-jigsaw-java-9 Mit Java 9 kommt das lange angekündigte Modulsystem Jigsaw. Jigsaw ist eine grundlegende Strukturänderung von Java-Plattform und Sprache, mit deren Auswirkungen man sich möglichst früh beschäftigen sollte. Eine erste Jigsaw-Version im September 2015 hatte für so viele Diskussionen gesorgt, dass Java9-Roadmap und Feature-Freeze um ein halbes Jahr auf 2017 verschoben wurden. In diesem Tutorial erläutern wir Grundlagen von Jigsaw. Wir zeigen Motive und Ziele für die Einführung eines Modulsystems. Anhand von Code-Beispielen lernen die Teilnehmer, wie das Modulsystem aussieht und welche wichtigen Designentscheidungen getroffen wurden: • Warum braucht Java überhaupt ein Modulsystem? Was will man erreichen? Wie profitieren Entwickler davon? • Was ist ein Modul? Wie definiere ich Module und Abhängigkeiten? Welche Sichtbarkeiten gibt es zwischen Modulen? • Module sind sowohl Compiler-Erweiterung als auch Teil des Laufzeitsystems. Wie wirkt sich das aus? • Wie vertragen sich Module mit generischen Ansätzen wie Reflection oder Callbacks, auf denen bekannte Frameworks basieren? • Welche anderen Konstrukte gibt es (Beispiel: Services)? • Wie sehen Tools aus? IDE? Build/Dependency-Management? Frühere Java-Versionen waren immer abwärtskompatibel. Jigsaw ist eine tiefgreifende strukturelle Veränderung: • Wie geht man mit externen Bibliotheken um? • Welche Ansätze gibt es zu Migrationspfaden sowie zu Architektur und Design? Wir bieten diese Einführung als Tutorial in Form eines interaktiven Entwicklerworkshops an. Wir zeigen die Grundlagen mit Folien und führen interaktiv durch Beispiele und Code, u.a. zu Module-Info, requires, exports, uses/provides, Interface/Implementierung, Exceptions, Reflection, Module-API und -Finder usw. Alle Beispiele können die Teilnehmer selber auf ihrem Laptop mitmachen und somit alles lokal nachvollziehen. Sourcecode und SEU/Entwicklungsumgebung mit JDK, Eclipse stellen wir (mindestens) für Windows zur Verfügung (verteilen wir als ZIP-Paket auf USB-Stick) bzw. legen wir nach Github. 3 Copyright © Accso – Accelerated Solutions GmbH 2017/07/27 Java 9 General Availability http://openjdk.java.net/projects/jdk9/ Einleitung 5 Copyright © Accso – Accelerated Solutions GmbH JSR 277 (2005-2016) „Java Module System“ JSR 294 (2006-2016) „Improved Modularity Support” JSR 291 (2006-2007) „Dynamic Component Support“ JSR 376 (2014-2017) „Java Platform Module System“ Project Jigsaw für Java 9 geplant für Ende Juli 2017 6 Copyright © Accso – Accelerated Solutions GmbH Ziele von Modularisierung und Jigsaw Reliable Configuration Ablösung des Classpath (fehleranfällig, wenn Klassen mehrfach enthalten sind – Reihenfolge). Neu: explizite Definition von Abhängigkeiten. Strong Encapsulation Eine Komponente kann ihr öffentliches API definieren und verhindern, dass auf Implementierungsgeheimnisse zugegriffen wird. Scalable Java SE Platform Die Java-Plattform selber wird modularisiert. Damit kann man individuell angepasste und „schlanke“ Plattformen bauen. 7 Copyright © Accso – Accelerated Solutions GmbH Die wichtigsten Requirements aus der Spec-Dokumentation Modules mit Dependencies, Resolution, Encapsulation, Non-Interference: In allen Phasen (Compile, Laufzeit). Exports müssen von außen überschreibbar sein. Resource Encapsulation Services: Binding, Selective Binding Java Platform Modularization Interoperabilität mit anderen Modulsystemen (OSGi explizit genannt) Refactoring: Module aufspaltbar / zusammenlegbar, ohne Auswirkungen auf Clients Whitebox-Tests Schrittweise Migration, Weiterbenutzung von existierenden Tools wie Maven Linking („optimierte Plattform bauen“) Keine Verschlechterung der Performance Non-Requirements: Versionierung – nur als Versionsstring in einem Modul! 8 Copyright © Accso – Accelerated Solutions GmbH Grundlagen Module in Java 9 9 Copyright © Accso – Accelerated Solutions GmbH Ein Modul wird ein „First-Class-Citizen“ in Java Modul := Menge von Java-Packages & Resources. Wird in ein „Modular JAR“ kompiliert. Dieses liegt im neuen Module-Path. Modul-Namen müssen eindeutig sein (. und _ sind im Namen erlaubt, - nicht) • • 10 „read“-Abhängigkeitsbeziehungen zu einem oder mehreren anderen Modulen „exports“: Welche Packages des Moduls werden exportiert? (Default: nichts!) read modb pkgb inter nal moda pkg a pkg b exports Copyright © Accso – Accelerated Solutions GmbH Java 1.0 bis 8: Sichtbarkeitsmodifier von Klassen, Attributen, Methoden de.my.package public Foo Bar protected XYZ private ... <package> 11 Baz Copyright © Accso – Accelerated Solutions GmbH Java 1.0 bis 8: Sichtbarkeitsmodifier von Klassen, Attributen, Methoden 12 Copyright © Accso – Accelerated Solutions GmbH Java 9: Diese Sichtbarkeitsmodifier ändern sich nicht. 13 Copyright © Accso – Accelerated Solutions GmbH Neu in Java 9: Modul-Definition mit exportierten Packages modb 14 exports Copyright © Accso – Accelerated Solutions GmbH Neu in Java 9: Readability und Accessibility modb de.my. package. internal read pkg a de.my. package de.my. package. ximpl moda exports Check zu Compile-Zeit und zur Laufzeit von 1. neu: Readability „ich benötige dieses Module, will darauf zugreifen“ 2. neu: Accessibility „worauf dürfen andere zugreifen?“ (unabhg. von Classloadern!) 3. Check der „alten“ Sichtbarkeitsmodifier public,protected,<package>,private 15 Copyright © Accso – Accelerated Solutions GmbH Beispiel: Vier Module moda, modb, modc, modmain und ihr Sourcenbaum 16 moda/ module-info.java pkga1/ A1.java pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH Beispiel: Vier Module moda, modb, modc, modmain und ihr Sourcenbaum Modul-Definition eines Modules liegt in Datei module-info.java im obersten Module-Sourcenverzeichnis. Wird kompiliert zu .class-File! Wird mit in das JAR-File paketiert. 17 moda/ module-info.java pkga1/ A1.java pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH Übung Aufgabe 1a 18 Copyright © Accso – Accelerated Solutions GmbH modb/module-info.java module modb { // Export des Packages pkgb von modb exports pkgb; } 19 moda/ module-info.java pkga1/ A1.java pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH modmain/module-info.java modmain/pkgmain/Main.java module modmain { // Read-Abhängigkeit von modmain zu mod // (Compiler meckert fehlende Module an!) requires moda; } public class Main { public static void main(String[] args) throws Exception { // access to pkga1 pkga1.A1 mya1 = new pkga1.A1(); System.out.println("A1: " + mya1.doIt()); … 20 moda/ module-info.java pkga1/ A1.java pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH Aufgabe 1a: Erstellen des Moduldeskriptors für moda module moda { //TODO Read-Abhaengigkeiten zu den von moda benoetigten Modulen //TODO Exports von Packages von moda } 21 moda/ module-info.java pkga1/ A1.java pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH Zeit: bis …….. Uhr 22 Copyright © Accso – Accelerated Solutions GmbH Lösung Aufgabe 1a: Alle Abhängigkeiten der vier Module 23 moda/ module-info.java pkga1/ A1.java modmain pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH Lösung Aufgabe 1a: moda/module-info.java module moda { // Read-Abhängigkeiten von moda zu modb und modc // (Compiler meckert fehlende Module an!) requires modb; requires transitive modc; // Exports von Packages von moda // (Compiler meckert fehlende Packages an!) exports pkga1; exports pkga2 to modmain; // nur an modmain // (Compiler meckert zyklische Abhängigkeiten // an!) // requires modmain; } 24 moda/ module-info.java pkga1/ A1.java modmain pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH requires transitive für transitive Abhängigkeiten module moda { requires modb; requires transitive modc; ... 25 Copyright © Accso – Accelerated Solutions GmbH moda/pkga1.A1.java package pkga1; import pkgb.B; import pkgc.C; public class A1 { public String doIt() { return "from A1, " + new B().doIt(); } public C getMyC() { return new C(); } } 26 moda/ module-info.java pkga1/ A1.java modmain pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH modmain/pkgmain.Main.java public class Main { public static void main(String[] args) throws Exception { // access to pkga1 (exported from moda) pkga1.A1 mya1 = new pkga1.A1(); System.out.println("A1: " + mya1.doIt()); Object myc1 = mya1.getMyC(); System.out.println("from A1: getMyC()=" + myc1); pkgc.C myc2 = mya1.getMyC(); System.out.println("from A1: getMyC()=" + myc2); // access to pkga2 (exported from moda only to modmain) pkga2.A2 mya2 = new pkga2.A2(); System.out.println("A2: " + mya2.doIt()); ... 27 moda/ module-info.java pkga1/ A1.java modmain pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH modmain/pkgmain.Main.java public class Main { public static void main(String[] args) throws Exception { ... // access to pkga3 (opens from moda) // does not compile, pkga3 only via reflection // pkga3.A3 mya3 = new A3(); Class<?> myA3Class = Class.forName("pkga3.A3"); Constructor<?> con = myA3Class.getDeclaredConstructor(); con.setAccessible(true); // accessible because of opens Object myA3 = con.newInstance(); Method m = myA3.getClass().getMethod("doIt"); m.setAccessible(true); System.out.println("A3: " + m.invoke(myA3)); // does not compile, pkgainternal not exported // pkgainternal.InternalA myinternalA = // new pkgainternal.InternalA(); } 28 moda/ module-info.java pkga1/ A1.java modmain pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH Compile / Run-Skripte (Bash) Compile $JAVA_HOME/bin/javac -d mods --module-path mlib --module-source-path src $(find src -name "*.java") Run $JAVA_HOME/bin/java --module-path mlib -m modmain/pkgmain.Main 29 Copyright © Accso – Accelerated Solutions GmbH Interfaces und Implementierung mit Uses/Provides in der module-info Beispiel Schnittstelle java.sql.Driver in Module java.sql module java.sql { … // Definiert Schnittstelle uses java.sql.Driver; // ... und exportiert sie auch exports java.sql; } Implementierung in JDBC-Driver module com.mysql.jdbc { requires java.sql; … // Implementiert Schnittstelle provides java.sql.Driver with com.mysql.jdbc.Driver; } keine feste Bindung über Module-Namen wie bei Requires 30 Copyright © Accso – Accelerated Solutions GmbH Reflection, Split-Package 31 Copyright © Accso – Accelerated Solutions GmbH Was ist mit Reflection? … und mit Serialisierung, DependencyInjection, Bytecode-Enhancement, ...? Zur Erinnerung 1. Check: Readable, über requires? 2. Check: Accessible, über exports? 3. Check von public,protected,<package>,private Gilt alles auch bei Reflection! Convenience bei Reflection: read-Beziehung ist immer vorhanden. Aber Accessibility-Checks greifen auch „scharf“ bei Reflection: Klassen von nicht exportierten Packages sind nicht zugreifbar. • Gilt für newInstance, getField, getMethod • Gilt auch für setAccessible(true) 32 Copyright © Accso – Accelerated Solutions GmbH opens öffnet ein Package zur Laufzeit opens erlaubt Zugriff nur zur Laufzeit, nicht zur Compile-Zeit opens öffnet für „Deep Reflection“ mit setAccessible(true) Zugriff … exports opens exports und opens pkg pkg pkg Compile-Zeit Erlaubt Nicht Erlaubt Erlaubt Reflection (Shallow) Erlaubt Erlaubt Erlaubt Reflection (Deep) Nicht Erlaubt Erlaubt Erlaubt pkg Spezialfall „open module“: alle Packages des Moduls sind „open“ 33 Copyright © Accso – Accelerated Solutions GmbH Übung Aufgaben 1b & c 34 Copyright © Accso – Accelerated Solutions GmbH Aufgabe 1b: Reflection-Zugriffe modmain/pkgmain.Main.java public class Main { public static void main(String[] args) throws Exception { ... // Zugriff per Deep Reflection Class<?> myA3Class = Class.forName("pkga3.A3"); Constructor<?> con = myA3Class.getDeclaredConstructor(); con.setAccessible(true); Object myA3 = con.newInstance(); Method m = myA3.getClass().getDeclaredMethod("doIt"); m.setAccessible(true); System.out.println("A3: " + m.invoke(myA3)); // Zugriff per Shallow Reflection pkgc.C myc3 = mya1.getMyC(); System.out.println("From C (with shallow reflection): " + myc3.callA1WithShallowReflection()); } 35 moda/ module-info.java pkga1/ A1.java modmain pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH Zeit: bis …….. Uhr 36 Copyright © Accso – Accelerated Solutions GmbH Lösung Aufgabe 1b: moda/module-info.java module moda { // Read-Abhängigkeiten von moda zu modb und modc // (Compiler meckert fehlende Module an!) requires modb; requires transitive modc; // Exports von Packages von moda // (Compiler meckert fehlende Packages an!) exports pkga1; exports pkga2 to modmain; // nur an modmain // Nur zur Laufzeit, ermöglicht Deep Reflection opens pkga3; } 37 moda/ module-info.java pkga1/ A1.java modmain pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH Split Package: Modules müssen disjunkte Packages haben. Ausnahme: Gilt nicht für The Unnamed Module. Gilt nur für Module in einer gemeinsamen Configuration – nur auf Module-Path OK. Ein „Split“ von Packages auf mehrere Module ist nicht erlaubt! Gilt auch, wenn das Package nicht exportiert ist. Selbst dann, wenn es keine Klassen-Duplikate in den beiden Modules gibt. CompileFehler src\modmainfoo\module-info.java:1: error: module modmainfoo reads package pkgfoo from both modsplitfoo1 and modsplitfoo2 module modmainfoo { ^ 1 error LaufzeitFehler beim Start Error occurred during initialization of VM java.lang.reflect.LayerInstantiationException: Package pkgbar in both module modsplitbar1 and module modsplitbar2 at java.lang.reflect.Layer.fail(java.base@9-ea/Layer.java:449) at java.lang.reflect.Layer.checkBootModulesForDuplicatePkgs(java.base@9-ea/Layer.j at java.lang.reflect.Layer.defineModules(java.base@9-ea/Layer.java:357) at jdk.internal.module.ModuleBootstrap.boot(java.base@9-ea/ModuleBootstrap.java:29 at java.lang.System.initPhase2(java.base@9-ea/System.java:1925) 38 Copyright © Accso – Accelerated Solutions GmbH Ressourcen 39 Copyright © Accso – Accelerated Solutions GmbH Resource-Schutz und -Handling in Modules Zugriff auf Module-interne Resources möglich mit this.class.getModule().getResourceAsStream("myapp.properties") Funktioniert weiterhin: this.getClass().getResource ("myapp.properties") ClassLoader.getPlatformClassLoader().getResource("myapp.properties") Resource-Encapsulation wird durchgesetzt (funktionierte lange nicht). Ein Module sollte auf Resources eines anderen Modules nicht zugreifen dürfen, das funktioniert aber noch nicht wie erwartet … ?! that.class.getModule().getResourceAsStream("that.properties") 40 Copyright © Accso – Accelerated Solutions GmbH Wie kann man das statische Modell ändern/erweitern? 41 Copyright © Accso – Accelerated Solutions GmbH „Du kommst hier nicht rein!“ Doch! pkgainternal ist nicht exportiert, nicht zugreifbar (sog. „concealed package“)! Unschön JAR-File mit neuem module-info.class patchen ist i.d.R. keine Alternative (geht z.B. nicht bei Checksummen) Abhilfe Kommandozeilenoption --add-exports gibt Export zusätzlicher Packages an 42 moda/ module-info.java pkga1/ A1.java pkga2/ A2.java pkga3/ A3.java pkgainternal/ InternalA.java AHelperImpl.java modb/ module-info.java pkgb/ B.java modc/ module-info.java pkgc/ C.java modmain/ module-info.java pkgmain/ Main.java Copyright © Accso – Accelerated Solutions GmbH … wenn Exports und Reads der module-info nicht reichen weiteres Package exportieren Kommandozeile javac, java Reflection --add-exports (auch in Manifest.MF möglich) --add-reads java.lang.reflect. Module.addExports() java.lang.reflect. Module.addReads() weiteres (Root-)Module laden Kommandozeile javac, java 43 Neue Read-Beziehung von->nach --add-modules „Nimm-Alles“ ALL-MODULE-PATH Module mit Klassen patchen --patch-module Kein Patch von module-info ! Copyright © Accso – Accelerated Solutions GmbH Was ist (da)? Was wird (geladen)? 44 Copyright © Accso – Accelerated Solutions GmbH Observable Modules: „Was da ist“ Module-Path System-Module-Path modmain java. base Observable Modules Alle Module auf dem Module-Path, sowie die System-Module bilden das „Universum“ der Observable Modules. 45 Copyright © Accso – Accelerated Solutions GmbH Configuration: „Was wirklich geladen wird“ Module-Path System-Module-Path modmain java. base Observable Modules Die Configuration ist die transitive Hülle aller „reads“-Abhängigkeiten aller Root-Module der Observable Modules. Default-Root-Module hier: modmain java --module-path mlib 46 -m modmain/pkgmain.Main Copyright © Accso – Accelerated Solutions GmbH Configuration: „Was wirklich geladen wird“ plus „addMods“ Module-Path System-Module-Path modmain modx java. base Observable Modules Weitere Module kann man einer Configuration als Root-Module mit --add-modules java --module-path mlib --add-modules mlib/modx.jar hinzufügen: -m modmain/pkgmain.Main 47 Copyright © Accso – Accelerated Solutions GmbH Testen: Blackbox! Whitebox? 48 Copyright © Accso – Accelerated Solutions GmbH Blackbox-Test eines Modules modfib Separates Module modtest.blackbox testet äußere Schnittstelle von modfib. Braucht also keinen Zugriff auf interne Klassen. read pkgfib modfib pkgfib internal exports pkg black test modtest. blackbox java --module-path mlib\;amlib --add-modules hamcrest.core,modtest.blackbox -m junit/org.junit.runner.JUnitCore pkgblacktest.BlackBoxTest 49 Copyright © Accso – Accelerated Solutions GmbH Whitebox-Test eines Modules modfib : 4 Varianten Ein Whitebox-Test benötigt zum Test interne Klassen von modfib. Das Package pkgfib.internal ist aber nicht exportiert. pkgfib modfib pkgfib internal 50 exports Copyright © Accso – Accelerated Solutions GmbH Whitebox-Test eines Modules modfib : Varianten 1a, b 1. Separates Module modtest.whitebox Wie erhält es Zugriff auf die nicht-exportierten Klassen von modfib? a) Mit „exports to“ der zu testenden Packages an modtest.whitebox module modfib { exports pkgfib; exports pkgfibinternal } to modtest.whitebox; Statische Abhängigkeit zu Testcode b) Dynamischer Export der zu testenden Packages mit --add-exports javac --add-exports modfib/pkgfib.internal=modtest.whitebox java --add-exports modfib/pkgfib.internal=modtest.whitebox 51 Etwas besser. Aber: Pflege der Skripte?! Copyright © Accso – Accelerated Solutions GmbH Whitebox-Test eines Modules modfib : Varianten 2a, 2b 2. modfib enthält auch die Testklassen. Aber wo verwaltet man diese? a) Testklassen direkt bei modfib ablegen. Testklassen können so alle zu testenden Klassen aus modfib sehen. Testcode wird ebenfalls paketiert und deployed b) Testklassen getrennt ablegen. Zu Compile-Zeit und zur Test-Laufzeit dem Module modfib hinzufügen („Patchen“) 52 Copyright © Accso – Accelerated Solutions GmbH Whitebox-Test Variante 2b: modfib mit Testklassen patchen Testklassen erst beim Compile dem Module modfib hinzufügen pkgfib pkgfib …Test modfib pkgfib internal javac 53 -Xmodule:… --add-reads … -d patches/modfib ... src/modtest.whitebox/pkgfib/WhiteBoxTest.java Copyright © Accso – Accelerated Solutions GmbH Whitebox-Test Variante 2b: modfib mit Testklassen patchen Testklassen erst beim Test-Start dem Module modfib hinzufügen pkgfib pkgfib …Test modfib pkgfib internal java 54 --patch-module … --add-reads … ... -m junit/org.junit.runner.JUnitCore pkgfib.WhiteBoxTest Copyright © Accso – Accelerated Solutions GmbH Übung Aufgabe 2 55 Copyright © Accso – Accelerated Solutions GmbH Aufgabe 2: Erstellen von Blackbox- und Whiteboxtests Ziel der Übung ist das Verstehen der Mechanismen zur Strukturierung von Tests. Die Güte der Testfälle und Testabdeckung ist heute mal nebensächlich! a) Blackboxtests in einem eigenen Modul zum Test der öffentlichen Schnittstelle zu testenden Fibonacci-Modul modfib b) Whiteboxtests zum Test des Implementierungsgeheimnis der Fibonacci-Zahlen Die Whiteboxtests werden zur Compile- und Laufzeit in modfib hineingepatcht. 56 modfib/ modfib/ module-info.java pkfib/ … pkgfib.internal/ … modtest.blackbox/ module-info.java pkgblacktest/ BlackBoxTest.java modtest.whitebox/ pkgfib/ WhiteBoxTest.java Copyright © Accso – Accelerated Solutions GmbH Zeit: bis …….. Uhr 57 Copyright © Accso – Accelerated Solutions GmbH Lösung Aufgabe 2a: Blackbox-Tests Modul-info von modtest.blackbox module modtest.blackbox { requires modfib; requires junit; exports pkgblacktest; } Skript zum Ausführen der Blackboxtests java --module-path mlib\;amlib --add-modules hamcrest.core,modtest.blackbox -m junit/org.junit.runner.JUnitCore pkgblacktest.BlackBoxTest 58 Copyright © Accso – Accelerated Solutions GmbH Lösung Aufgabe 2b: Whitebox-Tests Skript zum Kompilieren der Whiteboxtests javac -d patches/modfib -Xmodule:modfib --add-reads modfib=junit --add-modules junit --module-path amlib\;mlib src/modtest.whitebox/pkgfib/WhiteBoxTest.java Skript zum Ausführen der Whiteboxtests java --patch-module modfib=patches/modfib --module-path mlib\;amlib --add-reads modfib=junit --add-modules ALL-MODULE-PATH -m junit/org.junit.runner.JUnitCore pkgfib.WhiteBoxTest 59 Copyright © Accso – Accelerated Solutions GmbH Lösung Aufgabe 2c: Optionen in @<file> auslagern Optionen in Datei auslagern (Beispiel: Skript zum Ausführen der Whiteboxtests) java @run-whiteboxtest-options Inhalt der Datei run-whiteboxtest-options --patch-module modfib=patches/modfib --module-path mlib\;amlib --add-reads modfib=junit --add-modules ALL-MODULE-PATH -m junit/org.junit.runner.JUnitCore pkgfib.WhiteBoxTest Optionen auf CLI und in Datei können gemischt werden (jedoch Reihenfolge beachten!) 60 Copyright © Accso – Accelerated Solutions GmbH TypenSichtbarkeit, Zugriffe 61 Copyright © Accso – Accelerated Solutions GmbH Letztlich geht‘s immer um Typen-Sichtbarkeit. Auch bei Ableitung. Funktioniert: • Oberklasse Data ist sichtbar nach außen, weil Package pkga exportiert. • Ihre Methoden sind von außerhalb aufrufbar. • Unterklasse InternalData ist nicht sichtbar nach außen. • Ihre Methoden sind von außerhalb nicht aufrufbar. 62 moda exports pkga Data pkga inter nal Inte rnal Data Copyright © Accso – Accelerated Solutions GmbH Letztlich geht‘s immer um Typen-Sichtbarkeit. Auch bei Ableitung. Funktioniert auch umgekehrt: • Oberklasse ist nicht sichtbar nach außen • Unterklasse ist sichtbar nach außen moda pkga Data pkga inter nal 63 Inte rnal Data exports Copyright © Accso – Accelerated Solutions GmbH Letztlich geht‘s immer um Typen-Sichtbarkeit. Auch bei Ableitung. public class Factory { public Data createData() { return new Data(); } public Data createInternalData1() { return new InternalData(); } moda Fact ory exports pkga Data … Funktioniert: Factory gibt Instanzen der Unterklasse InternalData zurück. Instanzen behalten natürlich ihren Typ. Es werden Methoden der Unterklasse aufgerufen, z.B. InternalData.toString() 64 pkga inter nal Inte rnal Data Copyright © Accso – Accelerated Solutions GmbH Letztlich geht‘s immer um Typen-Sichtbarkeit. Auch bei Ableitung. public class { Gilt auch beiFactory Ableitung public Data createData() { Wasreturn passiert, eine Methodensignatur new wenn Data(); } eine nicht exportierte Klasse zurückgibt public Data createInternalData1() { return new InternalData(); } // return type wird nicht exportiert! public InternalData createInternalData2() { return new InternalData(); } } 65 Factory kompiliert. Code in anderem Module kompiliert nicht bei Aufruf: Factory.createInternalData2() moda Fact ory exports pkga Data pkga inter nal Inte rnal Data Copyright © Accso – Accelerated Solutions GmbH Letztlich geht‘s immer um Typen-Sichtbarkeit. Auch bei Interfaces. public class FibonacciFactory { public Fibonacci createFibonacciCalculator() { return new FibonacciImpl(); } … Funktioniert: FibonacciFactory gibt Instanzen der Implementierung FibonacciImpl zurück. Instanzen behalten natürlich ihren Typ. 66 modfib Fib. Fact ory pkgfib exports Fibon acci pkgfib. Fibon inter acci nal Impl Copyright © Accso – Accelerated Solutions GmbH Letztlich geht‘s immer um Typen-Sichtbarkeit. Gilt auch bei Exception-Handling. Interne Exceptions (deren Package nicht exportiert ist) MyInternalException MyInternalRuntimeException können nach außerhalb des Modules geworfen werden. Typ bleibt auch hier erhalten. Alles funktioniert „ganz normal“, nur eben kein catch auf den internen Exception-Typ. catch auf Oberklassen wie Exception, RuntimeException problemlos möglich. 67 Copyright © Accso – Accelerated Solutions GmbH Letztlich geht‘s immer um Typen-Sichtbarkeit. Gilt auch bei Implementierung eines Interfaces. Eine Implementierung eines Interfaces muss nicht exportiert sein, um benutzt werden zu können. Beispiel Callback-Interface: read Call ee pkg sst Call back Impl ICall back pkg inter nal exports 68 Copyright © Accso – Accelerated Solutions GmbH ModuleKategorien und Migration 69 Copyright © Accso – Accelerated Solutions GmbH Ein „echtes“ Module: Explicit Module Module-Path modmain Explicit Module in einem JAR liegt auf dem Module-Path enthält module-info modb java. base 70 Open Module ist Spezialfall eines Explicit Modules Copyright © Accso – Accelerated Solutions GmbH Ein JAR in ein Module umwandeln: Automatic Module Module-Path modmain junit modb java. base Automatic Module JAR auf den Module-Path legen Automatisch: „reads“ auf alle Module, „exports“ aller Packages (incl. „opens“) Ein Explicit Module muss ein Automatic Module requiren. Automatischer Name: - . junit-4.12.jar junit Named Modules := Explicit Modules + Automatic Modules 71 Copyright © Accso – Accelerated Solutions GmbH Der alte Classpath: The Unnamed Module Module-Path The Unnamed Module b.jar modmain hibernate .jar junit modb The Unnamed Module java. base Alle JARs auf dem Classpath sind ein einziges Module „reads“ auf alle Modules Readable durch alle(!) Automatic Modules, aber nicht durch Explicit Modules Exports aller Packages 72 Copyright © Accso – Accelerated Solutions GmbH Wie Module-Path und The Unnamed Module interagieren 1 Module-Path b.jar modmain 2 The Unnamed Module pkgb. B hibernate .jar junit modb pkgb. B java. base Vorsicht bei gleichzeitiger Verwendung von Module-Path und The Unnamed Module! 73 Suchreihenfolge 1 Module-Path 2 The Unnamed Module Klasse pkgb.B wird in modb gefunden! Keine Fehlermeldung wie bei Split Package! Copyright © Accso – Accelerated Solutions GmbH Schritt für Schritt nach Jigsaw 74 Copyright © Accso – Accelerated Solutions GmbH Schritt 0: Anwendung unverändert mit Java 9 benutzen Module-Path The Unnamed Module main.jar b.jar c.jar java. sql java. base Die Java-Plattform-Module auf dem System-Module-Path hibernate.jar Die Anwendung liegt auf dem Classpath (im Unnamed Module). Keine Anpassungen notwendig, jedoch ohne Named Modules. ABER: Wenige inkompatible Änderungen in Java 9, z.B. kein Boot-Classpath 75 Copyright © Accso – Accelerated Solutions GmbH Schritt 1: „Unabhängiges“ JAR in Named Module migrieren Module-Path The Unnamed Module main.jar c b.jar c.jar java. sql java. base hibernate.jar c.jar hängt von nichts ab. c kann einfach in ein Named Module migriert werden. Compile- und Runtime-Option --add-modules notwendig! 76 Copyright © Accso – Accelerated Solutions GmbH Schritt 2: JAR in Automatic Module migrieren Module-Path The Unnamed Module main.jar b c b.jar java. sql java. base hibernate.jar b.jar hängt von hibernate.jar ab. Wird als Automatic Module migriert, damit hibernate.jar readable ist. Ein JAR kann nur (unverändert) migriert werden, wenn es keine PackageÜberschneidungen mit anderen Modulen gibt (sonst Split-Package)! 77 Copyright © Accso – Accelerated Solutions GmbH Schritt 3: Third-Party-Lib in Automatic Module migrieren Module-Path The Unnamed Module main.jar b c hiber nate java. sql java. base hibernate.jar hibernate wird in ein Automatic Module migriert. Um hibernate auch noch in ein Explicit Module zu migrieren, müsste eine module-info erstellt werden. Machbar, aber: Aufwändig, benötigt Sourcen & Build, erstellt Fork plus Abhängigkeiten 78 Copyright © Accso – Accelerated Solutions GmbH Schritt 4: Automatic Module in Explicit Module migrieren Module-Path The Unnamed Module main.jar b c hiber nate java. sql java. base b kann nun in ein Explicit Module migriert werden, weil hibernate nun ebenfalls im Module-Path liegt. 79 Copyright © Accso – Accelerated Solutions GmbH Schritt 5: Den Rest migrieren Module-Path main The Unnamed Module main b main.jar junitc b c hiber nate java. sql java. base 80 Copyright © Accso – Accelerated Solutions GmbH jdeps, jmod, API 81 Copyright © Accso – Accelerated Solutions GmbH Module-Informationen auslesen Auslesen der Module-Informationen aus JAR, aus module-info.class jar --file mlib/modmain.jar --print-module-descriptor Oder jdeps --module-path mlib mlib/modmain.jar Auslesen der Module-Informationen aus JMOD-Datei jmod describe java.base.jmod Auslesen der Module-Informationen einer module-info.class - Datei javap -verbose module-info.class 82 Copyright © Accso – Accelerated Solutions GmbH Module-Info aus einem „normalen JAR“ generieren z.B. für JAR-File junit-4.12.jar (und abhängiger JARs) jdeps --generate-module-info ./gensrc amlib/*.jar module junit { // Module-Name "junit" automatisch aus junit-4.12.jar requires transitive hamcrest.core; requires java.management; exports exports exports exports exports exports junit.extensions; junit.framework; junit.runner; junit.textui; org.junit; org.junit.experimental; // es werden *alle* Packages exportiert ... exports org.junit.runners.model; exports org.junit.runners.parameterized; exports org.junit.validator; } 83 Copyright © Accso – Accelerated Solutions GmbH Zugriff auf das Modulsystem über neue APIs java.lang.module.… java.lang.module ModuleFinder ModuleDescriptor ModuleDescriptor.Requires ModuleDescriptor.Exports ModuleReference Configuration Ein/alle Module finden („Observable Modules”) Modulbeschreibung mit Name, Version, … ... mit allen Requires ... mit allen Exports Laufzeit-Referenz auf ein Modul „Was geladen wird“ java.lang.reflect.… Module Layer 84 Reflection-Support Copyright © Accso – Accelerated Solutions GmbH Übung Aufgabe 3 85 Copyright © Accso – Accelerated Solutions GmbH Aufgabe 3: jmod, jdeps und neue API Ziel dieser Übung ist, den Umgang mit den neuen und erweiterten PlattformTools für die Arbeit mit Modulen zu erlernen, sowie die neue Modul-API kennenzulernen. a) Nutzung der Plattform-Tools jmod und jdeps b) Nutzung der API von java.lang.module zur Ausgabe von ModuleInformationen 86 Copyright © Accso – Accelerated Solutions GmbH Zeit: bis …….. Uhr 87 Copyright © Accso – Accelerated Solutions GmbH Liste der 31 Java-System-Module (mit Präfix „java.“) 88 java.activation@9-ea java.base@9-ea java.compact2@9-ea java.compiler@9-ea java.datatransfer@9-ea java.httpclient@9-ea java.jnlp@9-ea java.management@9-ea java.prefs@9-ea java.scripting@9-ea java.se.ee@9-ea java.security.sasl@9-ea java.sql@9-ea java.transaction@9-ea java.xml.bind@9-ea java.xml.ws@9-ea java.annotations.common@9-ea java.compact1@9-ea java.compact3@9-ea java.corba@9-ea java.desktop@9-ea java.instrument@9-ea java.logging@9-ea java.naming@9-ea java.rmi@9-ea java.se@9-ea java.security.jgss@9-ea java.smartcardio@9-ea java.sql.rowset@9-ea java.xml@9-ea $JAVA_HOME/jmod/java.* java.xml.crypto@9-ea im Build 9-ea+b148x64_20161213_build5846 Copyright © Accso – Accelerated Solutions GmbH Module java.desktop@9-ea requires java.base [MANDATED] requires java.datatransfer [TRANSITIVE] requires java.prefs requires java.xml [TRANSITIVE] exports exports exports exports exports exports exports exports exports exports exports exports exports exports exports exports exports exports 89 exports java.applet java.awt.... java.beans.... javax.accessibility javax.imageio.... javax.print.... javax.sound.... javax.swing.... java.desktop 4 requires 50 exports 12 exports-to an andere System-Module com.sun.awt to [jdk.desktop] com.sun.media.sound to [jdk.javaws, jdk.plugin] java.awt.dnd.peer to [javafx.swing] java.awt.peer to [jdk.plugin] sun.applet to [jdk.plugin] sun.applet.resources to [jdk.plugin] sun.awt to [javafx.swing, jdk.deploy, jdk.desktop, jdk.accessibility, jdk.plugin, jdk.javaws] sun.awt.dnd to [javafx.swing] sun.awt.image to [javafx.swing, jdk.plugin, jdk.javaws] sun.awt.windows to [jdk.plugin] sun.java2d to [javafx.swing] Copyright © Accso – Accelerated Solutions GmbH Module java.base@9-ea exports java.io exports java.lang.... exports java.math exports java.net.... exports java.nio.... exports java.security.... exports java.text.... exports java.time.... exports java.util.... exports javax.crypto.... exports javax.net.... exports javax.net.ssl exports javax.security.... java.base 0 requires 51 exports 65 exports-to an andere System-Module exports com.sun.net.ssl.internal.ssl to [jdk.deploy] exports com.sun.security.ntlm to [java.security.sasl] exports jdk.internal to [jdk.jfr] exports jdk.internal.jimage to [jdk.jlink] exports jdk.internal.jimage.decompressor to [jdk.jlink] exports jdk.internal.jmod to [jdk.jlink, jdk.compiler] exports jdk.internal.loader to [java.logging, java.instrument, jdk.jartool, jdk.jlink] exports jdk.internal.logger to [java.logging] exports jdk.internal.math to [java.desktop] exports jdk.internal.misc to [jdk.charsets, jdk.jshell, java.naming, jdk.unsupported, java.sql, java.rmi, jdk.jlink, jdk.plugin, jdk.deploy, javafx.graphics, jdk.compiler, java.xml, jdk.javaws, jdk.scripting.nashorn, jdk.jartool, java.logging, java.security.jgss, jdk.vm.ci, jdk.net, java.management, jdk.scripting.nashorn.shell, java.corba, java.desktop, jdk.jdeps, jdk.jfr] exports jdk.internal.module to [jdk.jlink, java.instrument, jdk.jartool, java.management, jdk.jfr] exports jdk.internal.org.objectweb.asm to [jdk.jfr, jdk.jartool, jdk.jlink, jdk.scripting.nashorn, jdk.vm.ci, java.instrument] exports jdk.internal.org.objectweb.asm.commons to [jdk.jfr, jdk.scripting.nashorn, java.instrument] ... exports sun.util.logging to [javafx.base, javafx.fxml, java.desktop, javafx.controls, java.logging, java.prefs, javafx.graphics, javafx.swing] Copyright © Accso – Accelerated Solutions GmbH 90 exports sun.util.resources to [jdk.localedata] Lösung Aufgabe 3b: API: Module finden // search all modules in module path ModuleFinder.of(Paths.get(System.getProperty("jdk.module.path"))) .findAll() .stream() .forEach(ref -> { System.out.println(ref.descriptor().name()); }); // search all system modules ModuleFinder.ofSystem() .findAll() .stream() .forEach(ref -> { System.out.println(ref.descriptor().name()); }); 91 Copyright © Accso – Accelerated Solutions GmbH Lösung Aufgabe 3b: API: Module finden, Infos ausgeben … .map(ref -> ref.descriptor()) .forEach(mod -> { // print the module name and version and is-automatic? System.out.println( "Module " + mod.toNameAndVersion() ); // print the module's requires mod.requires().stream().sorted() .forEach((Requires req) -> { System.out.println( " requires " + req.name()); }); // print the module's exports (and targets of exports-to) mod.exports().stream() .sorted(Comparator.comparing(Exports::source)) .forEach((Exports exp) -> { System.out.println( " exports " + exp.source() + " to " + exp.targets().toString()); }); 92 }); Copyright © Accso – Accelerated Solutions GmbH Module in Layern zur Laufzeit 93 Copyright © Accso – Accelerated Solutions GmbH Eine Jigsaw-Anwendung besteht zur Laufzeit aus Layern Modul-Gruppierung zur Laufzeit: Alle Module sind in einem Layer Layer • haben leider keinen Namen • haben jeweils eine eigene Configuration. • benötigen mindestens je einen Classloader (pro Layer / pro Module). Mindestens ein Layer zur Laufzeit Layer bilden eine Hierarchie (sind aber kein Baum – mehrere Parents möglich!) 94 Copyright © Accso – Accelerated Solutions GmbH Alle Module von Aufgabe 1 95 Copyright © Accso – Accelerated Solutions GmbH Alle Module von Aufgabe 1 – zur Laufzeit im Boot-Layer Boot Layer 96 Copyright © Accso – Accelerated Solutions GmbH Info zu „meinem Layer“ via java.lang.reflect.Layer import java.lang.reflect.Layer; Layer myLayer = this.getClass().getModule().getLayer(); System.out.println(myLayer.toString()); System.out.println(myLayer.equals(Layer.boot())); 97 List<Layer> parents = myLayer.parents(); if ( parents.isEmpty() || (parents.size()==1 && parents.contains(Layer.empty()))) { System.out.println("no parents, this is the boot layer"); } else { for (Layer parentLayer: parents) System.out.println(parentLayer.toString()); } Copyright © Accso – Accelerated Solutions GmbH Beispiel – Variante 1 – Alle Module im Boot-Layer Boot Layer 98 Copyright © Accso – Accelerated Solutions GmbH Layer erzeugen mit java.lang.reflect.Layer public Layer createLayer(Layer parent, String modulePath, List<String> modulesNames) { // get new Configuration from parent’s Configuration, // from ModuleFinder results and from the list of module names Configuration conf = parent.configuration() .resolveRequires(ModuleFinder.of(), ModuleFinder.of(Paths.get(modulePath)), modulesNames); // create and return new Layer, here with new Classloader for all // modules (which delegate to the System-Classloader) return parent.defineModulesWithOneLoader(conf, ClassLoader.getSystemClassLoader()); } 99 Copyright © Accso – Accelerated Solutions GmbH Beispiel – Variante 2 – Module aufgeteilt auf Layer-Hierarchie PseudoParent empty-Layer 100 Copyright © Accso – Accelerated Solutions GmbH Beispiel – Variante 2 – Module aufgeteilt auf Layer-Hierarchie PseudoParent empty-Layer Layerübergreifende Aufrufe von „oben nach unten“ und umgekehrt via Reflection 101 Split-Package mit mehreren (Geschwister-) Layern? Kein Problem, solange nur getrennte CLs verwendet werden Copyright © Accso – Accelerated Solutions GmbH Tools 102 Copyright © Accso – Accelerated Solutions GmbH „DepVis“: Tool zur Visualisierung eines Modul-Graphen DepVis kann visualisieren: … Module im Module-Path … Module im System … mit Black- & Whitelisting … Explicit Modules und Automatic Modules … requires, requires-transitive (1-transitiv), requires-mandated, exports-to https://github.com/accso/java9-jigsaw-depvis Basiert auf GraphViz http://www.graphviz.org/ mit Java-API https://github.com/kohsuke/graphviz-api 103 Ideen: req-transitive (n-transitiv), Filter auf einzelne Beziehungen, Uses/Provides, Packages, Hashes, Open, nur Module der Configuration, mehr Konfiguration mit Farben & Co … Copyright © Accso – Accelerated Solutions GmbH 104 Copyright © Accso – Accelerated Solutions GmbH Unsere Beispiele Auf Github: https://github.com/accso/java9-jigsaw-examples/ Java mit Jigsaw Build jdk1.9.0_ea-b156-x64_20170214_build6091 Eclipse 4.7 Oxygen (M5) plus Java9-Support (BETA) • • • • • Konvention: 1 Eclipse-Projekt == 1 Module Module-Namen: mod*, Package-Namen: pkg* (interne *internal) Module-Abhängigkeiten über Projekt-Abhängigkeiten in Eclipse nachmodelliert Launch-Files starten die JAR-Files im Module-Path Jedes Beispiel in einem eigenen Workspace *) Compile- und Run-Skripte für die Bash (auch für Windows, z.B. mit Babun) *) 105 Ein Workspace kann nicht 2 Projekte gleichen Namens enthalten. Copyright © Accso – Accelerated Solutions GmbH Wie steht‘s um die Standard-Tools? Eclipse 4.6 und 4.7M3,4,5 plus Java9-Plugin (BETA): • • • Eclipse startet mit Java 9 module-info: Das meiste wird erkannt, auch Sichtbarkeiten. Code-Completion für requires-Module, exports-Packages Es fehlt: Launch-Einstellungen für Module-Path, Automatic Modules, .... Maven, Gradle, Netbeans, … bieten Unterstützung für Java 9 Mühsame Pflege wird hoffentlich durch IDEs und Build-Tools erledigt: • • • 106 requires-Pflege Maven-POM Eclipse-.classpath exports -Pflege Package-Konventionen wie „…internal“ (?) Alle Kommandozeilenoptionen für javac und java Copyright © Accso – Accelerated Solutions GmbH Debugging Java-Launcher mit einigen nützlichen Optionen: java --list-modules ... java -Xdiag:resolver ... java -Xlog:modules=debug|trace ... Debugger kann Module-Informationen ausgeben, über Class.getModule() Stacktraces geben Module-Informationen aus: pkgb.MyException: MyException's message at pkgb.B.doItThrowException(modb/B.java:13) at pkgmain.Main.main(modmain/Main.java:18) 107 Copyright © Accso – Accelerated Solutions GmbH Tools mit Java 9: Quality Outreach Programm des OpenJDK https://wiki.openjdk.java.net/display/quality/Quality+Outreach 108 Copyright © Accso – Accelerated Solutions GmbH Ausblick, Literatur 109 Copyright © Accso – Accelerated Solutions GmbH … und viele weitere Themen in Java 9 (zu wenig Zeit ;-) Module und JavaDoc Module und Annotations Modifier von Requires , Exports ClassLoader -Xbootclasspath Upgradeable Modules Nutzung von jlink für JEP238 für Multi-Release-JAR-Files JMOD-Format und -Dateien Neuer Versionsstring in Java9 Instrumentierung 110 Mandated, Synthetic, Transitive, … hat sich im Grundprinzip nicht geändert fällt weg i.W. der Ersatz für Extension-Mechanismus Linking von optimierten Runtime-Images JAR-File mit Java-Release-spezifischen Versionen i.W. JARs mit Native-Code usw. u.a. fällt Präfix „1.“ endlich weg geht nicht mehr für sehr früh geladenen Code Copyright © Accso – Accelerated Solutions GmbH Zum Nachlesen Homepage Project Jigsaw Build Specification Diskussionsseite State of the Module System Quickstart Guide JSR376 JEPs http://openjdk.java.net/projects/jigsaw/ https://jdk9.java.net/jigsaw/ http://openjdk.java.net/projects/jigsaw/spec/reqs/ http://openjdk.java.net/projects/jigsaw/spec/issues/ http://openjdk.java.net/projects/jigsaw/spec/sotms/ http://openjdk.java.net/projects/jigsaw/quick-start https://www.jcp.org/en/jsr/detail?id=376 http://openjdk.java.net/jeps/<NR> 200 „The modular JDK“ 261 „Module System“ 220 „Modular Runtime Images“ 260 „Encapsulate Most Internal APIs“ 275 „Modular Java App. Packaging“ 282 „jlink: The Java Linker“ http://mail.openjdk.java.net/mailman/listinfo Mailinglisten jigsaw-dev, jdk9-dev, jpms-spec-comments, jpms-spec-experts, jpms-spec-observers 111 Copyright © Accso – Accelerated Solutions GmbH 160 to go! Roadmap bis Java 9 Roadmap für den JSR 376 (aus der Mailingliste) Early Draft Review Public Review Proposed Final Draft Final Release 112 9/2016 11/2016 1/2017 3/2017 Roadmap bis Java 9 http://openjdk.java.net/projects/jdk9/ 2016/05/26 2016/12/22 2017/01/05 2017/02/09 2017/02/16 2017/03/16 2017/07/06 2017/07/27 Feature Complete Feature Ext. Complete Rampdown Start All Tests Run Zero Bug Bounce Rampdown Phase 2 Final Release Candidate General Availability Copyright © Accso – Accelerated Solutions GmbH Laubsägenmassaker (Kritik und Lob) 113 Copyright © Accso – Accelerated Solutions GmbH Jigsaw ist noch nicht final, Diskussionen u.a. noch zu … Exporte nur zur Laufzeit, v.a. für Reflection (dynamic->Weak->Open)? Module-Abhängigkeiten nur zur Compile-Zeit („requires static“)? Laufzeit-Beziehungen lazy auflösen? Annotations für Module Deprecation für Module > 1 Module in 1 JAR (so wie Fat-JARs), dazu Multi-Release-JARs? Automatic Modules Teilweise sehr fundamentale Kritik auf den Mailinglisten: 114 Copyright © Accso – Accelerated Solutions GmbH Kritik … Drastische Semantikänderung: public != accessible Erster Accessibility-Level ist nun das „Package“. (Warum eigentlich?) Abhängigkeitsmodell ist sehr statisch über Namen. Kein Alias für ein Module möglich (außer --patch-module) Warum keine Scopes wie „Test“ und „Runtime“ (vgl. Maven)? Zugriffsschutz ist sehr restriktiv. Opt-in oder Opt-out? Leider keine Unterstützung von Exports-Package-Wildcards! Ein Module hat keine (echten) Versionen - nur informell module-info wird zu .class-File kompiliert. Ist aber doch gar keine Klasse. Warum nicht MANIFEST.MF? Oder wenigstens Human-Readable-Format? Modules sind nicht gruppierbar. Keine Hierarchie möglich (vgl. parent.pom) 115 Copyright © Accso – Accelerated Solutions GmbH … und Lob! Aggregator-Module über requires transitive Der richtige Schritt zur echter Komponentenorientierung! Jigsaw und Java 9 sind sehr stabil. Allerdings ändern sich immer noch Implementierungen (und auch Konzepte, gerade zu Reflection) Migration ist gut machbar, aber wird mühsam! • Module-Kategorien: „wo kommt was her?“ ist nicht trivial! • MP & CP: Bekommen wir das jemals richtig aussortiert? 116 Copyright © Accso – Accelerated Solutions GmbH 117 Copyright © Accso – Accelerated Solutions GmbH @accso @lemmi111171 accso MartinLehmann1971 Rgrammes kristines https://github.com/accso/ java9-jigsaw-examples/ de.slideshare.net/lemmi www.xing.com/profile/Martin_Lehmann3 www.xing.com/profile/Ruediger_Grammes www.xing.com/profile/Kristine_Schaal Accso – Accelerated Solutions GmbH www.accso.de twitter.com/accso 118 118 Berliner Allee 58 64295 Darmstadt Telefon: +49 (6151) 13029-0 Fax: +49 (6151) 13029-10 Moltkestraße 131 a 50674 Köln Telefon: +49 (221) 630691-0 Fax: +49 (221) 630691-10 Balanstraße 55 81541 München 118 Copyright © Accso Copyright © Accso – Accelerated Solutions GmbH GmbH SHARING YOUR CHALLENGE Accso – Accelerated Solutions GmbH www.accso.de twitter.com/accso 119 119 Berliner Allee 58 64295 Darmstadt Telefon: +49 (6151) 13029-0 Fax: +49 (6151) 13029-10 Moltkestraße 131 a 50674 Köln Telefon: +49 (221) 630691-0 Fax: +49 (221) 630691-10 Balanstraße 55 81541 München 119 Copyright © Accso Copyright © Accso – Accelerated Solutions GmbH GmbH