ein geduldsspiel! das 1000-module- puzzle fÜr … java 9 kommt das lange angekündigte modulsystem...

119
Copyright © Accso – Accelerated Solutions GmbH 1 DAS NEUE MODULSYSTEM JIGSAW IN JAVA 9 17. FEBRUAR 2017 | DR. RÜDIGER GRAMMES, MARTIN LEHMANN, DR. KRISTINE SCHAAL | FRANKFURTER ENTWICKLERTAG EIN GEDULDSSPIEL! DAS 1000-MODULE- PUZZLE FÜR ENTWICKLER.

Upload: others

Post on 22-May-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Copyright © Accso – Accelerated Solutions GmbH 1

DAS NEUE MODULSYSTEM JIGSAWIN JAVA 9

17. FEBRUAR 2017 | DR. RÜDIGER GRAMMES, MARTIN LEHMANN, DR. KRISTINE SCHAAL | FRANKFURTER ENTWICKLERTAG

EIN GEDULDSSPIEL! DAS 1000-MODULE-PUZZLE FÜR ENTWICKLER.

Copyright © Accso – Accelerated Solutions GmbH 2

Copyright © Accso – Accelerated Solutions GmbH 3

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?

Abstracthttps://entwicklertag.de/frankfurt/2017/ein-geduldsspiel-das-1000-module-puzzle-f%C3%BCr-entwickler-das-neue-modulsystem-jigsaw-java-9

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 Folienund 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.

2017/07/27 Java 9 General Availabilityhttp://openjdk.java.net/projects/jdk9/

Copyright © Accso – Accelerated Solutions GmbH 5

Einleitung

Copyright © Accso – Accelerated Solutions GmbH 6

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

Copyright © Accso – Accelerated Solutions GmbH 7

Ziele von Modularisierung und Jigsaw

Reliable ConfigurationAblösung des Classpath (fehleranfällig, wenn Klassen mehrfach enthalten sind – Reihenfolge). Neu: explizite Definition von Abhängigkeiten.

Strong EncapsulationEine Komponente kann ihr öffentliches API definieren und verhindern, dass auf Implementierungsgeheimnisse zugegriffen wird.

Scalable Java SE PlatformDie Java-Plattform selber wird modularisiert. Damit kann man individuell angepasste und „schlanke“ Plattformen bauen.

Copyright © Accso – Accelerated Solutions GmbH 8

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!

Die wichtigsten Requirements aus der Spec-Dokumentation

Copyright © Accso – Accelerated Solutions GmbH 9

GrundlagenModule in Java 9

Copyright © Accso – Accelerated Solutions GmbH 10

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)

• „read“-Abhängigkeitsbeziehungen zu einem oder mehrerenanderen Modulen

• „exports“: Welche Packages des Moduls werden exportiert?(Default: nichts!)

moda

Ein Modul wird ein „First-Class-Citizen“ in Java

modb

read

exports

pkga

pkgb

pkgbinternal

Copyright © Accso – Accelerated Solutions GmbH 11

de.my.package

...

Foo Bar

XYZBaz

protected

private<package>

public

Java 1.0 bis 8: Sichtbarkeitsmodifier von Klassen, Attributen, Methoden

Copyright © Accso – Accelerated Solutions GmbH 12

Java 1.0 bis 8: Sichtbarkeitsmodifier von Klassen, Attributen, Methoden

Copyright © Accso – Accelerated Solutions GmbH 13

Java 9: Diese Sichtbarkeitsmodifier ändern sich nicht.

Copyright © Accso – Accelerated Solutions GmbH 14

modb

Neu in Java 9: Modul-Definition mit exportierten Packages

exports

Copyright © Accso – Accelerated Solutions GmbH 15

Neu in Java 9: Readability und Accessibility

read moda

pkga

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

de.my.package.ximpl

de.my.package.internal

de.my.package

exports

modb

Copyright © Accso – Accelerated Solutions GmbH 16

Beispiel: Vier Module moda, modb,modc, modmain und ihr Sourcenbaum

moda/module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

Copyright © Accso – Accelerated Solutions GmbH 17

moda/module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

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.

Beispiel: Vier Module moda, modb,modc, modmain und ihr Sourcenbaum

module-info.java

Copyright © Accso – Accelerated Solutions GmbH 18

ÜbungAufgabe 1a

Copyright © Accso – Accelerated Solutions GmbH 19

moda/module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

modb/module-info.java

module-info.java

module modb{// Export des Packages pkgb von modb

exports pkgb;}

Copyright © Accso – Accelerated Solutions GmbH 20

moda/module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

modmain/module-info.javamodmain/pkgmain/Main.java

module-info.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 pkga1pkga1.A1 mya1 = new pkga1.A1();System.out.println("A1: " + mya1.doIt());

Main.java

Copyright © Accso – Accelerated Solutions GmbH 21

moda/module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

Aufgabe 1a: Erstellen des Moduldeskriptors für moda

module-info.java

module moda{//TODO Read-Abhaengigkeiten zu

den von moda benoetigten Modulen

//TODO Exports von Packages von moda}

Copyright © Accso – Accelerated Solutions GmbH 22

Zeit:bis …….. Uhr

Copyright © Accso – Accelerated Solutions GmbH 23

Lösung Aufgabe 1a: Alle Abhängigkeiten der vier Module

moda/module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

module-info.java

modmain

Copyright © Accso – Accelerated Solutions GmbH 24

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;}

moda/module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

module-info.java

modmain

Lösung Aufgabe 1a:moda/module-info.java

Copyright © Accso – Accelerated Solutions GmbH 25

requires transitive für transitive Abhängigkeiten

module moda {requires modb;requires transitive modc;

...

Copyright © Accso – Accelerated Solutions GmbH 26

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();

}}

moda/pkga1.A1.javamoda/

module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

A1.javamodmain

Copyright © Accso – Accelerated Solutions GmbH 27

modmain/pkgmain.Main.javamoda/

module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.javaMain.java

modmainpublic 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());

...

Copyright © Accso – Accelerated Solutions GmbH 28

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 opensObject 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();}

modmain/pkgmain.Main.javamoda/

module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

modmain

Main.java

Copyright © Accso – Accelerated Solutions GmbH 29

Compile

Run

Compile / Run-Skripte (Bash)

$JAVA_HOME/bin/java --module-path mlib -m modmain/pkgmain.Main

$JAVA_HOME/bin/javac -d mods --module-path mlib--module-source-path src $(find src -name "*.java")

Copyright © Accso – Accelerated Solutions GmbH 30

Beispiel

Schnittstelle java.sql.Driver Implementierungin Module java.sql in JDBC-Driver

keine feste Bindung über Module-Namen wie bei Requires

Interfaces und Implementierung mit Uses/Provides in der module-info

module java.sql {…

// Definiert Schnittstelle uses java.sql.Driver;

// ... und exportiert sie auchexports java.sql;

}

module com.mysql.jdbc {requires java.sql;

…// Implementiert Schnittstelle

provides java.sql.Driverwith com.mysql.jdbc.Driver;

}

Copyright © Accso – Accelerated Solutions GmbH 31

Reflection,Split-Package

Copyright © Accso – Accelerated Solutions GmbH 32

Was ist mit Reflection? … und mit Serialisierung, Dependency-Injection, 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)

Copyright © Accso – Accelerated Solutions GmbH 33

opens erlaubt Zugriff nur zur Laufzeit, nicht zur Compile-Zeit

opens öffnet für „Deep Reflection“ mit setAccessible(true)

Spezialfall „open module“: alle Packages des Moduls sind „open“

opens öffnet ein Package zur Laufzeit

Zugriff … Compile-Zeit Reflection(Shallow)

Reflection(Deep)

exports pkg Erlaubt Erlaubt Nicht Erlaubt

opens pkg Nicht Erlaubt Erlaubt Erlaubt

exports pkg undopens pkg

Erlaubt Erlaubt Erlaubt

Copyright © Accso – Accelerated Solutions GmbH 34

ÜbungAufgaben 1b & c

Copyright © Accso – Accelerated Solutions GmbH 35

public class Main {public static void main(String[] args) throws Exception {...

// Zugriff per Deep ReflectionClass<?> 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 Reflectionpkgc.C myc3 = mya1.getMyC();System.out.println("From C (with shallow reflection): "

+ myc3.callA1WithShallowReflection()); }

Aufgabe 1b: Reflection-Zugriffemodmain/pkgmain.Main.java

moda/module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

modmain

Main.java

Copyright © Accso – Accelerated Solutions GmbH 36

Zeit:bis …….. Uhr

Copyright © Accso – Accelerated Solutions GmbH 37

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 Reflectionopens pkga3;

}

moda/module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

module-info.java

modmain

Lösung Aufgabe 1b:moda/module-info.java

Copyright © Accso – Accelerated Solutions GmbH 38

Compile-Fehler

Laufzeit-Fehlerbeim Start

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.

Split Package: Modules müssen disjunkte Packages haben.Ausnahme: Gilt nicht für The Unnamed Module.

src\modmainfoo\module-info.java:1: error: module modmainfoo reads package pkgfoo from both modsplitfoo1 and modsplitfoo2module modmainfoo {^1 error

Error occurred during initialization of VMjava.lang.reflect.LayerInstantiationException: Package pkgbar in both module modsplitbar1 and module modsplitbar2at java.lang.reflect.Layer.fail(java.base@9-ea/Layer.java:449)at java.lang.reflect.Layer.checkBootModulesForDuplicatePkgs(java.base@9-ea/Layer.java:407)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:298)at java.lang.System.initPhase2(java.base@9-ea/System.java:1925)

Gilt nur für Module in einer gemeinsamen Configuration – nur auf Module-Path OK.

Copyright © Accso – Accelerated Solutions GmbH 39

Ressourcen

Copyright © Accso – Accelerated Solutions GmbH 40

Zugriff auf Module-interne Resources möglich mit

Funktioniert weiterhin:

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 … ?!

Resource-Schutz und -Handling in Modules

this.class.getModule().getResourceAsStream("myapp.properties")

this.getClass().getResource ("myapp.properties")

ClassLoader.getPlatformClassLoader().getResource("myapp.properties")

that.class.getModule().getResourceAsStream("that.properties")

Copyright © Accso – Accelerated Solutions GmbH 41

Wie kann man dasstatische Modell

ändern/erweitern?

Copyright © Accso – Accelerated Solutions GmbH 42

„Du kommst hier nicht rein!“

ist nicht exportiert, nicht zugreifbar (sog. „concealed package“)!

moda/module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

AHelperImpl.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

moda/module-info.javapkga1/

A1.javapkga2/

A2.javapkga3/

A3.javapkgainternal/

InternalA.javamodb/

module-info.javapkgb/

B.javamodc/

module-info.javapkgc/

C.javamodmain/

module-info.javapkgmain/

Main.java

pkgainternal/InternalA.java

pkgainternal

Doch!

Unschön

JAR-File mit neuem module-info.classpatchen ist i.d.R. keine Alternative(geht z.B. nicht bei Checksummen)

Abhilfe

Kommandozeilenoption --add-exportsgibt Export zusätzlicher Packages an

Copyright © Accso – Accelerated Solutions GmbH 43

… wenn Exports und Reads der module-info nicht reichen

weiteres Package exportieren

Neue Read-Beziehung von->nach

Kommandozeile javac, java

weiteres (Root-)Module laden

Module mit Klassen patchen

Reflection

--add-exports

(auch in Manifest.MF möglich)

java.lang.reflect.Module.addExports()

--add-reads

java.lang.reflect.Module.addReads()

--add-modules

„Nimm-Alles“ ALL-MODULE-PATH

--patch-module

Kein Patch von module-info !

Kommandozeile javac, java

Copyright © Accso – Accelerated Solutions GmbH 44

Was ist (da)?Was wird (geladen)?

Copyright © Accso – Accelerated Solutions GmbH 45

Observable Modules

System-Module-Path

Observable Modules: „Was da ist“

java.base

Module-Path

modmain

Alle Module auf dem Module-Path, sowie die System-Module bilden das „Universum“ der Observable Modules.

Copyright © Accso – Accelerated Solutions GmbH 46

Die Configuration ist die transitive Hülle aller „reads“-Abhängigkeiten aller Root-Module der Observable Modules.

Default-Root-Module hier: modmain

Observable Modules

System-Module-Path

Configuration: „Was wirklich geladen wird“

Module-Path

modmain

java.base

java --module-path mlib -m modmain/pkgmain.Main

modmain

java.base

Copyright © Accso – Accelerated Solutions GmbH 47

Weitere Module kann man einer Configuration als Root-Module mit --add-moduleshinzufügen:

Observable Modules

System-Module-Path

Configuration: „Was wirklich geladen wird“ plus „addMods“

Module-Path

modmain

java.base

modmain

java.base

java --module-path mlib --add-modules mlib/modx.jar -m modmain/pkgmain.Main

modxmodx

Copyright © Accso – Accelerated Solutions GmbH 48

Testen:Blackbox! Whitebox?

Copyright © Accso – Accelerated Solutions GmbH 49

Separates Module modtest.blackbox testet äußere Schnittstelle von modfib. Braucht also keinen Zugriff auf interne Klassen.

Blackbox-Test eines Modules modfib

modfibmodtest.blackbox

read

exports

pkg blacktest

pkgfibinternal

pkgfib

java --module-path mlib\;amlib --add-modules hamcrest.core,modtest.blackbox-m junit/org.junit.runner.JUnitCore pkgblacktest.BlackBoxTest

Copyright © Accso – Accelerated Solutions GmbH 50

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.

modfibexports

pkgfibinternal

pkgfib

Copyright © Accso – Accelerated Solutions GmbH 51

1. Separates Module modtest.whiteboxWie erhält es Zugriff auf die nicht-exportierten Klassen von modfib?

Whitebox-Test eines Modules modfib : Varianten 1a, b

Statische Abhängigkeit zu Testcode

Etwas besser. Aber: Pflege der Skripte?!

module modfib {exports pkgfib; exports pkgfibinternal to modtest.whitebox;

}

a) Mit „exports to“ der zu testenden Packages an modtest.whitebox

javac --add-exports modfib/pkgfib.internal=modtest.whitebox

java --add-exports modfib/pkgfib.internal=modtest.whitebox

b) Dynamischer Export der zu testenden Packages mit --add-exports

Copyright © Accso – Accelerated Solutions GmbH 52

2. modfib enthält auch die Testklassen.Aber wo verwaltet man diese?

Whitebox-Test eines Modules modfib : Varianten 2a, 2b

Testcode wird ebenfalls paketiert und deployed

a) Testklassen direkt bei modfib ablegen.Testklassen können so alle zu testenden Klassen aus modfib sehen.

b) Testklassen getrennt ablegen.Zu Compile-Zeit und zur Test-Laufzeit dem Module modfib hinzufügen („Patchen“)

Copyright © Accso – Accelerated Solutions GmbH 53

Whitebox-Test Variante 2b: modfib mit Testklassen patchen

Testklassen erst beim Compile dem Module modfib hinzufügen

modfib

pkgfibinternal

pkgfib pkgfib

…Test

javac -Xmodule:… --add-reads …-d patches/modfib ... src/modtest.whitebox/pkgfib/WhiteBoxTest.java

Copyright © Accso – Accelerated Solutions GmbH 54

modfib

pkgfibinternal

pkgfib pkgfib

…Test

Testklassen erst beim Test-Start dem Module modfib hinzufügen

Whitebox-Test Variante 2b: modfib mit Testklassen patchen

java --patch-module …--add-reads …...-m junit/org.junit.runner.JUnitCore pkgfib.WhiteBoxTest

Copyright © Accso – Accelerated Solutions GmbH 55

ÜbungAufgabe 2

Copyright © Accso – Accelerated Solutions GmbH 56

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 Implementierungs-geheimnis der Fibonacci-Zahlen

Die Whiteboxtests werden zur Compile- und Laufzeit in modfib hineingepatcht.

Aufgabe 2: Erstellen von Blackbox- und Whiteboxtests

modfib/module-info.javapkfib/

…pkgfib.internal/

modtest.blackbox/module-info.javapkgblacktest/

BlackBoxTest.java

modtest.whitebox/pkgfib/

WhiteBoxTest.java

modfib/

Copyright © Accso – Accelerated Solutions GmbH 57

Zeit:bis …….. Uhr

Copyright © Accso – Accelerated Solutions GmbH 58

Lösung Aufgabe 2a: Blackbox-Tests

module modtest.blackbox {

requires modfib;requires junit;

exports pkgblacktest;}

java --module-path mlib\;amlib --add-modules hamcrest.core,modtest.blackbox-m junit/org.junit.runner.JUnitCore pkgblacktest.BlackBoxTest

Modul-info von modtest.blackbox

Skript zum Ausführen der Blackboxtests

Copyright © Accso – Accelerated Solutions GmbH 59

Lösung Aufgabe 2b: Whitebox-Tests

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

Skript zum Ausführen 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 Kompilieren der Whiteboxtests

Copyright © Accso – Accelerated Solutions GmbH 60

Lösung Aufgabe 2c: Optionen in @<file> auslagern

--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

Inhalt der Datei run-whiteboxtest-options

java @run-whiteboxtest-options

Optionen in Datei auslagern (Beispiel: Skript zum Ausführen der Whiteboxtests)

Optionen auf CLI und in Datei können gemischt werden (jedoch Reihen-folge beachten!)

Copyright © Accso – Accelerated Solutions GmbH 61

Typen-Sichtbarkeit,

Zugriffe

Copyright © Accso – Accelerated Solutions GmbH 62

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.

exports

pkgainternal

pkgaData

moda

Internal

Data

Copyright © Accso – Accelerated Solutions GmbH 63

Funktioniert auch umgekehrt:

• Oberklasse ist nicht sichtbar nach außen

• Unterklasse ist sichtbar nach außen

pkgaData

moda

exports

pkgainternal

Internal

Data

Letztlich geht‘s immer um Typen-Sichtbarkeit. Auch bei Ableitung.

Copyright © Accso – Accelerated Solutions GmbH 64

pkgainternal

pkga

moda

Fact

ory

Internal

Data

Data

exports

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()

public class Factory {public Data createData() {

return new Data(); }

public Data createInternalData1() {return new InternalData();

}…

Letztlich geht‘s immer um Typen-Sichtbarkeit. Auch bei Ableitung.

Copyright © Accso – Accelerated Solutions GmbH 65

Gilt auch bei Ableitung

Was passiert, wenn eine Methodensignatur eine nicht exportierte Klasse zurückgibt

pkgainternal

pkga

moda

Fact

ory

public class Factory {public Data createData() {

return new Data(); }

public Data createInternalData1() {return new InternalData();

}

// return type wird nicht exportiert!public InternalData createInternalData2() {

return new InternalData();}

}

Factory kompiliert.

Code in anderem Module kompiliert nicht bei Aufruf:

Internal

Data

Data

exports

Factory.createInternalData2()

Letztlich geht‘s immer um Typen-Sichtbarkeit. Auch bei Ableitung.

Copyright © Accso – Accelerated Solutions GmbH 66

Letztlich geht‘s immer um Typen-Sichtbarkeit. Auch bei Interfaces.

exports

pkgfib.internal

pkgfibFibon

acci

modfib

Fibonacci

Impl

Funktioniert: FibonacciFactory gibt Instanzen der Implementierung FibonacciImpl zurück.

Instanzen behalten natürlich ihren Typ.

public class FibonacciFactory {public Fibonacci createFibonacciCalculator() {

return new FibonacciImpl();}…

Fib.Fact

ory

Copyright © Accso – Accelerated Solutions GmbH 67

Interne Exceptions (deren Package nicht exportiert ist)MyInternalExceptionMyInternalRuntimeException

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, RuntimeExceptionproblemlos möglich.

Letztlich geht‘s immer um Typen-Sichtbarkeit.Gilt auch bei Exception-Handling.

Copyright © Accso – Accelerated Solutions GmbH 68

Eine Implementierung eines Interfaces muss nicht exportiert sein, um benutzt werden zu können.

Beispiel Callback-Interface:

exports

pkgsst

ICall

back

Call

eepkg

internalCall

back

Impl

read

Letztlich geht‘s immer um Typen-Sichtbarkeit.Gilt auch bei Implementierung eines Interfaces.

Copyright © Accso – Accelerated Solutions GmbH 69

Module-Kategorien

und Migration

Copyright © Accso – Accelerated Solutions GmbH 70

Module-Path

Ein „echtes“ Module: Explicit Module

Explicit Module

in einem JAR

liegt auf dem Module-Path

enthält module-info

Open Module ist Spezialfall eines Explicit Modules

modb

java.base

modmain

Copyright © Accso – Accelerated Solutions GmbH 71

Ein JAR in ein Module umwandeln: Automatic Module

Module-Path

modb

java.base

Automatic Module

JAR auf den Module-Path legenmodmain

junit

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

Copyright © Accso – Accelerated Solutions GmbH 72

Der alte Classpath: The Unnamed Module

The Unnamed Module

Alle JARs auf dem Classpathsind ein einziges Module

Module-Path

modmain

modb

The Unnamed Module

java.base

Exports aller Packages

Readable durch alle(!) Automatic Modules, aber nicht durch Explicit Modules

„reads“ auf alle Modules

junit

b.jar

hibernate.jar

Copyright © Accso – Accelerated Solutions GmbH 73

Wie Module-Path und The Unnamed Module interagieren

Module-Path

modb

modmain

java.base

junit

1 The Unnamed Module

b.jar

Suchreihenfolge

Module-Path

The Unnamed Module

Vorsicht bei gleichzeitiger Verwendung von Module-Path und The Unnamed Module!

2

hibernate.jar

1

2

pkgb.B

pkgb.B

Klasse pkgb.B wird in modbgefunden! Keine Fehler-meldung wie bei Split Package!

Copyright © Accso – Accelerated Solutions GmbH 74

Schritt für Schritt nach Jigsaw

Copyright © Accso – Accelerated Solutions GmbH 75

Schritt 0: Anwendung unverändert mit Java 9 benutzen

Die Java-Plattform-Module auf dem System-Module-Path

Module-Path The Unnamed Module

java.base

java.sql

main.jar

b.jar c.jar

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

Copyright © Accso – Accelerated Solutions GmbH 76

Schritt 1: „Unabhängiges“ JAR in Named Module migrieren

c.jar hängt von nichts ab.

c kann einfach in ein Named Module migriert werden.

Compile- und Runtime-Option --add-modules notwendig!

The Unnamed Module

main.jar

b.jar

hibernate.jar

Module-Path

java.base

java.sql

c.jar

c

Copyright © Accso – Accelerated Solutions GmbH 77

Schritt 2: JAR in Automatic Module migrieren

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)!

Module-Path

java.base

java.sql

b c

The Unnamed Module

main.jar

hibernate.jar

b.jar

Copyright © Accso – Accelerated Solutions GmbH 78

Schritt 3: Third-Party-Lib in Automatic Module migrieren

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

Module-Path

java.base

java.sql

cb

hibernate

The Unnamed Module

main.jar

hibernate.jar

Copyright © Accso – Accelerated Solutions GmbH 79

Schritt 4: Automatic Module in Explicit Module migrieren

b kann nun in ein Explicit Module migriert werden, weil hibernate nun ebenfalls im Module-Path liegt.

Module-Path

java.base

java.sql

cb

hibernate

b

The Unnamed Module

main.jar

Copyright © Accso – Accelerated Solutions GmbH 80

Schritt 5: Den Rest migrieren

Module-Path

java.base

java.sql

c

junit

bmain

Module-Path

java.base

java.sql

c

hibernate

b

mainmain

The Unnamed Module

main.jar

Copyright © Accso – Accelerated Solutions GmbH 81

jdeps, jmod, API

Copyright © Accso – Accelerated Solutions GmbH 82

Auslesen der Module-Informationen aus JAR, aus module-info.class

Oder

Auslesen der Module-Informationen aus JMOD-Datei

Auslesen der Module-Informationen einer module-info.class - Datei

Module-Informationen auslesen

jar --file mlib/modmain.jar --print-module-descriptor

jdeps --module-path mlib mlib/modmain.jar

jmod describe java.base.jmod

javap -verbose module-info.class

Copyright © Accso – Accelerated Solutions GmbH 83

Module-Info aus einem „normalen JAR“ generierenz.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.jarrequires transitive hamcrest.core;requires java.management;

exports junit.extensions; // es werden *alle* Packages exportiertexports junit.framework;exports junit.runner;exports junit.textui;exports org.junit;exports org.junit.experimental;

... exports org.junit.runners.model;exports org.junit.runners.parameterized;exports org.junit.validator;

}

Copyright © Accso – Accelerated Solutions GmbH 84

java.lang.module

ModuleFinder

ModuleDescriptor

ModuleDescriptor.Requires

ModuleDescriptor.Exports

ModuleReference

Configuration

ModuleLayer

Zugriff auf das Modulsystem über neue APIs

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.module.…

java.lang.reflect.…

Reflection-Support

Copyright © Accso – Accelerated Solutions GmbH 85

ÜbungAufgabe 3

Copyright © Accso – Accelerated Solutions GmbH 86

Ziel dieser Übung ist, den Umgang mit den neuen und erweiterten Plattform-Tools 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 Module-Informationen

Aufgabe 3: jmod, jdeps und neue API

Copyright © Accso – Accelerated Solutions GmbH 87

Zeit:bis …….. Uhr

Copyright © Accso – Accelerated Solutions GmbH 88

java.activation@9-ea java.annotations.common@9-ea java.base@9-ea java.compact1@9-ea java.compact2@9-ea java.compact3@9-ea java.compiler@9-ea java.corba@9-ea java.datatransfer@9-ea java.desktop@9-ea java.httpclient@9-ea java.instrument@9-ea java.jnlp@9-ea java.logging@9-ea java.management@9-ea java.naming@9-ea java.prefs@9-ea java.rmi@9-ea java.scripting@9-ea java.se@9-ea java.se.ee@9-ea java.security.jgss@9-ea java.security.sasl@9-ea java.smartcardio@9-ea java.sql@9-ea java.sql.rowset@9-ea java.transaction@9-ea java.xml@9-ea java.xml.bind@9-ea java.xml.crypto@9-ea java.xml.ws@9-ea

Liste der 31 Java-System-Module (mit Präfix „java.“)

$JAVA_HOME/jmod/java.*

im Build 9-ea+b148-x64_20161213_build5846

Copyright © Accso – Accelerated Solutions GmbH 89

Module java.desktop@9-earequires java.base [MANDATED]requires java.datatransfer [TRANSITIVE]requires java.prefsrequires java.xml [TRANSITIVE]

exports java.appletexports java.awt....exports java.beans....exports javax.accessibilityexports javax.imageio....exports javax.print....exports javax.sound....exports javax.swing....

exports com.sun.awt to [jdk.desktop]exports com.sun.media.sound to [jdk.javaws, jdk.plugin]exports java.awt.dnd.peer to [javafx.swing]exports java.awt.peer to [jdk.plugin]exports sun.applet to [jdk.plugin]exports sun.applet.resources to [jdk.plugin]exports sun.awt to [javafx.swing, jdk.deploy, jdk.desktop, jdk.accessibility, jdk.plugin, jdk.javaws]exports sun.awt.dnd to [javafx.swing]exports sun.awt.image to [javafx.swing, jdk.plugin, jdk.javaws]exports sun.awt.windows to [jdk.plugin]exports sun.java2d to [javafx.swing]exports sun.swing to [javafx.swing, jdk.plugin]

java.desktop

4 requires

50 exports

12 exports-to an andere System-Module

Copyright © Accso – Accelerated Solutions GmbH 90

Module java.base@9-eaexports java.ioexports java.lang....exports java.mathexports 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.sslexports javax.security....

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]exports sun.util.resources to [jdk.localedata]

java.base

0 requires

51 exports

65 exports-to an andere System-Module

Copyright © Accso – Accelerated Solutions GmbH 91

Lösung Aufgabe 3b: API: Module finden

// search all modules in module pathModuleFinder.of(Paths.get(System.getProperty("jdk.module.path")))

.findAll()

.stream()

.forEach(ref -> { System.out.println(ref.descriptor().name());

});

// search all system modulesModuleFinder.ofSystem()

.findAll()

.stream()

.forEach(ref -> { System.out.println(ref.descriptor().name());

});

Copyright © Accso – Accelerated Solutions GmbH 92

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 requiresmod.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()); });});

Copyright © Accso – Accelerated Solutions GmbH 93

Module in Layernzur Laufzeit

Copyright © Accso – Accelerated Solutions GmbH 94

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!)

Eine Jigsaw-Anwendung besteht zur Laufzeit aus Layern

Copyright © Accso – Accelerated Solutions GmbH 95

Alle Module von Aufgabe 1

Copyright © Accso – Accelerated Solutions GmbH 96

Alle Module von Aufgabe 1 – zur Laufzeit im Boot-Layer

BootLayer

Copyright © Accso – Accelerated Solutions GmbH 97

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()));

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 98

Beispiel – Variante 1 – Alle Module im Boot-Layer

BootLayer

Copyright © Accso – Accelerated Solutions GmbH 99

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());

}

Copyright © Accso – Accelerated Solutions GmbH 100

Beispiel – Variante 2 – Module aufgeteilt auf Layer-HierarchiePseudo-Parentempty-Layer

Copyright © Accso – Accelerated Solutions GmbH 101

Beispiel – Variante 2 – Module aufgeteilt auf Layer-HierarchiePseudo-Parentempty-Layer

Layerübergreifende Aufrufe von „oben nach unten“ und umgekehrt

via Reflection

Split-Package mit mehreren (Geschwister-)

Layern?Kein Problem, solange

nur getrennte CLs verwendet werden

Copyright © Accso – Accelerated Solutions GmbH 102

Tools

Copyright © Accso – Accelerated Solutions GmbH 103

„DepVis“: Tool zur Visualisierung eines Modul-Graphen

Ideen: req-transitive (n-transitiv), Filter auf einzelne Beziehungen,

Uses/Provides, Packages, Hashes, Open, nur Module der Configuration,

mehr Konfiguration mit Farben & Co …

https://github.com/accso/java9-jigsaw-depvis

Basiert auf GraphViz http://www.graphviz.org/mit Java-API https://github.com/kohsuke/graphviz-api

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

Copyright © Accso – Accelerated Solutions GmbH 104

Copyright © Accso – Accelerated Solutions GmbH 105

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)

Unsere Beispiele

*) Ein Workspace kann nicht 2 Projekte gleichen Namens enthalten.

Copyright © Accso – Accelerated Solutions GmbH 106

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:

• requires-Pflege Maven-POM Eclipse-.classpath

• exports -Pflege Package-Konventionen wie „…internal“ (?)

• Alle Kommandozeilenoptionen für javac und java

Wie steht‘s um die Standard-Tools?

Copyright © Accso – Accelerated Solutions GmbH 107

Java-Launcher mit einigen nützlichen Optionen:

Debugger kann Module-Informationen ausgeben, über Class.getModule()

Stacktraces geben Module-Informationen aus:

Debugging

pkgb.MyException: MyException's messageat pkgb.B.doItThrowException(modb/B.java:13)at pkgmain.Main.main(modmain/Main.java:18)

java --list-modules ...

java -Xdiag:resolver ...

java -Xlog:modules=debug|trace ...

Copyright © Accso – Accelerated Solutions GmbH 108

Tools mit Java 9: Quality Outreach Programm des OpenJDKhttps://wiki.openjdk.java.net/display/quality/Quality+Outreach

Copyright © Accso – Accelerated Solutions GmbH 109

Ausblick,Literatur

Copyright © Accso – Accelerated Solutions GmbH 110

… und viele weitere Themen in Java 9 (zu wenig Zeit ;-)

Module und JavaDoc

Module und Annotations

Modifier von Requires , Exports Mandated, Synthetic, Transitive, …

ClassLoader hat sich im Grundprinzip nicht geändert

-Xbootclasspath fällt weg

Upgradeable Modules i.W. der Ersatz für Extension-Mechanismus

Nutzung von jlink für Linking von optimierten Runtime-Images

JEP238 für Multi-Release-JAR-Files JAR-File mit Java-Release-spezifischen Versionen

JMOD-Format und -Dateien i.W. JARs mit Native-Code usw.

Neuer Versionsstring in Java9 u.a. fällt Präfix „1.“ endlich weg

Instrumentierung geht nicht mehr für sehr früh geladenen Code

Copyright © Accso – Accelerated Solutions GmbH 111

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>

Zum NachlesenHomepage Project Jigsaw

Build

Specification

Diskussionsseite

State of the Module System

Quickstart Guide

JSR376

JEPs

200 „The modular JDK“

220 „Modular Runtime Images“

260 „Encapsulate Most Internal APIs“

Mailinglisten

jigsaw-dev, jdk9-dev, jpms-spec-comments, jpms-spec-experts, jpms-spec-observers

261 „Module System“

275 „Modular Java App. Packaging“

282 „jlink: The Java Linker“

http://mail.openjdk.java.net/mailman/listinfo

Copyright © Accso – Accelerated Solutions GmbH 112

160 to go! Roadmap bis Java 9

Early Draft Review 9/2016

Public Review 11/2016

Proposed Final Draft 1/2017

Final Release 3/2017

Roadmap bis Java 9http://openjdk.java.net/projects/jdk9/

2016/05/26 Feature Complete

2016/12/22 Feature Ext. Complete

2017/01/05 Rampdown Start

2017/02/09 All Tests Run

2017/02/16 Zero Bug Bounce

2017/03/16 Rampdown Phase 2

2017/07/06 Final Release Candidate

2017/07/27 General Availability

Roadmap für den JSR 376 (aus der Mailingliste)

Copyright © Accso – Accelerated Solutions GmbH 113

Laubsägenmassaker(Kritik und Lob)

Copyright © Accso – Accelerated Solutions GmbH 114

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:

Copyright © Accso – Accelerated Solutions GmbH 115

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)

Kritik …

Copyright © Accso – Accelerated Solutions GmbH 116

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?

… und Lob!

Copyright © Accso – Accelerated Solutions GmbH 117

Copyright © Accso – Accelerated Solutions GmbH 118118 Copyright © Accso GmbH

Accso – Accelerated Solutions GmbHwww.accso.detwitter.com/accso

Berliner Allee 5864295 DarmstadtTelefon: +49 (6151) 13029-0Fax: +49 (6151) 13029-10

Moltkestraße 131 a50674 KölnTelefon: +49 (221) 630691-0Fax: +49 (221) 630691-10

Balanstraße 5581541 München

118

@lemmi111171

de.slideshare.net/lemmi

www.xing.com/profile/Martin_Lehmann3www.xing.com/profile/Ruediger_Grammes

MartinLehmann1971accso

https://github.com/accso/java9-jigsaw-examples/ Rgrammes

kristines

@accso

www.xing.com/profile/Kristine_Schaal

Copyright © Accso – Accelerated Solutions GmbH 119

SHARING YOURCHALLENGE

119 Copyright © Accso GmbH

Accso – Accelerated Solutions GmbHwww.accso.detwitter.com/accso

Berliner Allee 5864295 DarmstadtTelefon: +49 (6151) 13029-0Fax: +49 (6151) 13029-10

Moltkestraße 131 a50674 KölnTelefon: +49 (221) 630691-0Fax: +49 (221) 630691-10

Balanstraße 5581541 München

119