jigsaw modularity

27

Upload: srinivasan-raghavan

Post on 11-Apr-2017

43 views

Category:

Software


0 download

TRANSCRIPT

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

Copyright © 2016, Oracle and/or its affiliates. All rights reserved. |

Question and Answers

27