java

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