Upload
srinivasan-raghavan
View
43
Download
0
Embed Size (px)
Citation preview
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Jigsaw ModularityThe current state of the Module System
Srinivasan Raghavan Senior Member of Technical Staff Java Platform Group [email protected] Sep 24, 2016
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Safe Harbor Statement
The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.
3
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
Project Jigsaw Introduction
Reliable configuration and Strong encapsulation
Module Types
Modules and Services
Q and A
1
2
3
4
5
4
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Project Jigsaw
5
• JEP 200: The Modular JDK • JEP 201: Modular Source Code • JEP 220: Modular Run-Time Images • JEP 260: Encapsulate Most Internal APIs • JEP 261: Module System • JEP 282: jlink: The Java Linker • JSR 376: Java Platform Module System
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
• 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
• javafx.base@9-ea
• javafx.controls@9-ea
• javafx.deploy@9-ea
• javafx.fxml@9-ea
• javafx.graphics@9-ea
• javafx.media@9-ea
• javafx.swing@9-ea
• javafx.web@9-ea
• jdk.accessibility@9-ea
• jdk.attach@9-ea
• jdk.charsets@9-ea
• jdk.compiler@9-ea
• jdk.crypto.ec@9-ea
• jdk.crypto.pkcs11@9-ea
• jdk.deploy@9-ea
• jdk.deploy.controlpanel@9-ea
• jdk.deploy.controlpanel.fx@9-ea
• jdk.dynalink@9-ea
• jdk.hotspot.agent@9-ea
• jdk.httpserver@9-ea
• jdk.internal.le@9-ea
• jdk.internal.opt@9-ea
• jdk.jartool@9-ea
• jdk.javadoc@9-ea
• jdk.javaws@9-ea
• jdk.jcmd@9-ea
• jdk.jconsole@9-ea
• jdk.jdeps@9-ea
• jdk.jdi@9-ea
• jdk.jdwp.agent@9-ea
• jdk.jfr@9-ea
• jdk.jlink@9-ea
• jdk.jshell@9-ea
• jdk.jsobject@9-ea
• jdk.jstatd@9-ea
• jdk.jvmstat@9-ea
• jdk.localedata@9-ea
• jdk.management@9-ea
• jdk.management.cmm@9-ea
• jdk.management.jfr@9-ea
• jdk.management.resource@9-ea
• jdk.naming.dns@9-ea
• jdk.naming.rmi@9-ea
• jdk.net@9-ea
• jdk.pack200@9-ea
• jdk.packager@9-ea
• jdk.packager.services@9-ea
• jdk.plugin@9-ea
• jdk.plugin.dom@9-ea
• jdk.plugin.server@9-ea
• jdk.policytool@9-ea
• jdk.rmic@9-ea
• jdk.scripting.nashorn@9-ea
• jdk.scripting.nashorn.shell@9-ea
• jdk.sctp@9-ea
• jdk.security.auth@9-ea
• jdk.security.jgss@9-ea
• jdk.snmp@9-ea
• jdk.unsupported@9-ea
• jdk.vm.cds@9-ea
• jdk.vm.ci@9-ea
• jdk.xml.bind@9-ea
• jdk.xml.dom@9-ea
• jdk.xml.ws@9-ea
• jdk.zipfs@9-ea
6
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 7
Let’s take a configuration
java.base
m1 m2
App
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 8
package com.m1.p1;
public class Type1 {
public String whoAmI() { return " I am " + Type1.class.getSimpleName() +" from the module " + Type1.class.getModule().getName() + " from package " + Type1.class.getPackageName() + " Loaded by " + Type1.class.getModule().getClassLoader().toString(); }}
package com.m1.p2;public class Type2 { public String whoAmI() { return " I am " + Type2.class.getSimpleName() +" from the module " + Type2.class.getModule().getName() + " from package " + Type2.class.getPackageName() + " Loaded by " + Type2.class.getModule().getClassLoader().toString(); }}
The module m1 code
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 9
package com.m2.p3;import com.m1.p1.Type1;import com.m1.p2.Type2;
public class Type3 { private final Type1 type1 = new Type1(); private final Type2 type2 = new Type2(); public Type1 getMeType1() { return type1; } public String whoAmI() { return " I am " + Type3.class.getSimpleName() +" from the module " + Type3.class.getModule().getName() + " from package " + Type3.class.getPackageName() + " Loaded by " + Type3.class.getModule().getClassLoader().toString(); } public String whoisType2() { return type2.whoAmI(); }}
The module m2 code
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 10
module m1 { exports com.m1.p1; exports com.m1.p2 to m2;}
module m2 { requires transitive m1; exports com.m2.p3;}
The module m1 and m2 module-info.java
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 11
package com.app.p1;import com.m1.p1.Type1;import com.m2.p3.Type3;class App1 { static final Type3 type3 = new Type3(); public static void main(String[] args) { System.out.println(type3.whoAmI()); System.out.println(type3.whoisType2()); System.out.println(type3.getMeType1().whoAmI()); }}
module app{requires m2;exports com.app.p1;}
The app module code
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 12
$find src -name “*.java"
src//app/com/app/p1/App1.java src//app/module-info.java src//m1/com/m1/p1/Type1.java src//m1/com/m1/p2/Type2.java src//m1/module-info.java src//m2/com/m2/p3/Type3.java src//m2/module-info.java
How its structured
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 13
$javac -d mods --module-source-path src/ $(find src -name "*.java")
$java -p mods -m app/com.app.p1.App1
I am Type3 from the module m2 from package com.m2.p3 Loaded by jdk.internal.loader.ClassLoaders$AppClassLoader@5ae9a829 I am Type2 from the module m1 from package com.m1.p2 Loaded by jdk.internal.loader.ClassLoaders$AppClassLoader@5ae9a829 I am Type1 from the module m1 from package com.m1.p1 Loaded by jdk.internal.loader.ClassLoaders$AppClassLoader@5ae9a829
Build and run
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 14
$jlink --module-path $JDKMODS:mods --add-modules app --compress=2 --strip-debug --output myappimage
$myappimage/bin/java --list-modulesappjava.base@9-eam1m2
$ myappimage/bin/java -m app/com.app.p1.App1 I am Type3 from the module m2 from package com.m2.p3 Loaded by jdk.internal.loader.ClassLoaders$AppClassLoader@5ae9a829 I am Type2 from the module m1 from package com.m1.p2 Loaded by jdk.internal.loader.ClassLoaders$AppClassLoader@5ae9a829 I am Type1 from the module m1 from package com.m1.p1 Loaded by jdk.internal.loader.ClassLoaders$AppClassLoader@5ae9a829
Create your own JDK
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
What we can infer
15
• As we can see from the code and module-info Type2 is exported only to m2 which means app module cannot directly access it • Type1 is return value of a method in Type3 so Type1 is transitively
exported to app module • If the app says Type2 type = new Type2() would fail to compile • Type2 class code can be only accessible to Type3 which in m2 • This ensures a reliable configuration. It also ensures the Type2 is
encapsulated and its used only where it is meant to.
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 16
$javac -d mods --module-source-path src/ $(find src -name “*.java")
src/app/com/app/p1/App2.java:8: error: Type2 is not visible because package com.m1.p2 is not visible import com.m1.p2.Type2; ^ src/app/com/app/p1/App2.java:18: error: cannot find symbol Type2 type = new Type2(); ^ symbol: class Type2 location: class App2 src/app/com/app/p1/App2.java:18: error: cannot find symbol Type2 type = new Type2(); ^ symbol: class Type2 location: class App2 3 errors
Type2 accessed by the App module
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 17
public Unsafe getUnsafe() throws Exception {
Unsafe unsafe =Unsafe.getUnsafe(); }
public Unsafe someHowGetUnsafe() throws Exception {
Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); Unsafe unsafe = (Unsafe) field.get(null); return unsafe; }
Problems with un encapsulated code
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Problems with un encapsulated code
18
• com.sun.misc.Unsafe is important code widely used inside JDK but not not meant for out use • In Java8 getUnsafe() would fail with java.lang.SecurityException:
Unsafe . There would be clever check in code to see whether only Jdk classes call unsafe • But with some clever reflection hacks someHowGetUnsafe() would
pass • In Java 9 both would fail with
java.lang.IllegalAccessError:jdk.internal.misc.Unsafe (in module java.base) because module java.base does not export jdk.internal.misc to unnamed module
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Modules Types
19
• Name Module - A module With module-info.java with both exports and requires specified • Automatic Module - Any Jar in ModulePath. The module info is auto-
generated which exports all package and requires all other mods • Unnamed Module- All the jars which reside in the class-path
togethers is Unnamed Module • Weak module - A module which has a module-info.java which
defines what is requires but exports all the package
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Modules Types
20
• Name Module - A module With module-info.java with both exports and requires specified • Automatic Module - Any Jar in ModulePath. The module info is auto-
generated which exports all package and requires all other mods • Unnamed Module- All the jars which reside in the class-path
togethers is Unnamed Module • Weak module - A module which has a module-info.java which
defines what is requires but exports all the package
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Modules And Services
21
• Services are first class citizens in the Module System • The provide the basic loose-coupling between the Service Types and
the their Implementation • Any Interface or abstract class be a Service Type • Service Types and the their Implementation can be in any module and
they follow the following semantics • when a module use a Service the module-info carries a “use” Service • when a module provide an Implementation for the Service the
module-info carries “provides” service “with” Impl
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 22
Modules And Servicesmodule m1 { exports com.m1.p1; exports com.m1.p2 to m2; }
module m2{ requires public m1; exports com.m2.p3; provides com.m1.p1.Service1 with com.m2.p3.Impl1; provides com.m1.p1.Service1 with com.m2.p3.Impl2; }
module app{ requires m2; exports com.app.p1; uses com.m1.p1.Service1; }
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 23
Modules And Services public static void main(String[] args) { getImpl("com.m2.p3.Imp1"); }
public static Service getImpl(String impl) { Service service = null; Optional<Provider<Service>> oprovider = ServiceLoader.load(Service.class) .stream() .fiter(p -> p.type().getName().equals(impl) .map(Provider::get) .findFirst(); if (oprovider.isPresent()) { Provider<Service> provider = oprovider.get(); service = provider.get(); } return service; }
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
Some of Design issues and solution
24
• ReflectiveAccessToNonExportedTypes. • Some libraries require reflective access to members of the non-
exported types of other modules • Examples include dependency injection (Guice) • Solution proposed is a weak module • Weak Module provides Reilable Configuration but skips the
encapsulation part so that DI frameworks can reflect upon
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. | 25
Weak modules
weak module app{ requires m2; }
Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |
References
26
• http://openjdk.java.net/projects/jigsaw/spec/issues/#ReflectiveAccessToNonExportedTypes • http://openjdk.java.net/projects/jigsaw/spec/reqs/ • http://hg.openjdk.java.net/jigsaw/jake • http://download.java.net/java/jigsaw/docs/api/index.html • http://openjdk.java.net/projects/jigsaw/talks/ • https://www.youtube.com/channel/UCdDhYMT2USoLdh4SZIsu_1g/
videos