Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Java Module System

Java Module System

The presentation is about Java 9 module system that I presented at GDG Izmir DevFest'17 in December.

Avatar for Hakan Özler

Hakan Özler

December 03, 2017
Tweet

Other Decks in Programming

Transcript

  1. Java 8/home ├── bin │ ├── jar │ ├── java

    │ ├── javac │ ├── ... │ └── xjc ├── db ├── include ├── javafx-src.zip ├── jre │ ├── bin │ └── lib │ ├── jce.jar │ ├── ... │ └── rt.jar ├── lib ├── man └── release Java 9/home ├── README.html ├── bin │ ├── jar │ ├── java │ ├── jdeps │ ├── jlink │ ├── jmod │ └── jshell ├── conf ├── include ├── jmods │ ├── java.activation.jmod │ ├── java.base.jmod │ ├── ... │ └── java.compiler.jmod ├── legal ├── lib └── release
  2. Module Descriptor module-info.java import com.example.service.*; /** * we can give

    a comment to a module * * @since 1.1.1 */ @MyCustomAnnotation module com.example.module.name { // descriptor body }
  3. Module Name ❌ module com.example.module {} module com.1example.module {} module

    com-example-module {} module 123com.example.module {} module $mymodule {} module myModule {} module __ {} ❌ ❌ ❌ ✔ ✔ ✔
  4. New Keywords! (open)? module com.example.module.name { requires (transitive || static)

    <module-name>; exports <package-name>; exports <package-name> to <module-name>(,<module-name>)*; provides <qualified-service-name> with <qualified-service-impl>; uses <qualified-service-name>; opens <package-name>; opens <package-name> to <module-name>(,<module-name>)*; }
  5. requires & exports module_a package com.example.a.impl; import com.example.b.api; public class

    Machine { … public boolean doSomething() { GearService service = …; … } } requires module_b exports com.example.b.api; . └── com.example.b.api └── GearService.java
  6. requires transitive (aggregator) module_a package com.example.a.impl; import com.example.c.model; import com.example.b.api;

    public class Machine { … public boolean doSomething() { GearService service = …; Gear g = service.findOne(); } } requires module_b exports com.example.b.api; requires transitive module_c; . └── com.example.b.api └── GearService.java exports com.example.c.model . └── com.example.c.model └── Gear.java
  7. exports … to ... module_a package com.example.a.impl; import com.example.c.model; import

    com.example.b.api; public class Machine { … public boolean doSomething() { GearService service = …; Gear g = service.findOne(); } } requires module_b exports com.example.b.api; requires transitive module_c; . └── com.example.b.api └── GearService.java exports com.example.c.model to module_b . └── com.example.c.model └── Gear.java ❌
  8. provides ... with ... & uses module_a package com.example.a.impl; import

    com.example.b.api; public class Machine { public boolean doSomething() { GearService service = ServiceLoader .load(GearService.class) .findFirst() .get(); Gear g = service.findOne(); } } requires module_b; uses com.example.b.api.GearService; exports com.example.b.api; provides com.example.b.api.GearService with com.example.b.impl.GearServiceImpl; . └── com.example └── b ├── api │ └── GearService.java └── impl └── GearServiceImpl.java
  9. opens module_a package com.example.a.impl; import com.example.b.model.Gear; public class Machine {

    public boolean doSomething() { Field model = Gear.class.getField("model"); Gear newInstanceOfGear = Gear.class .getDeclaredConstructor() .newInstance(); model.set(newInstanceOfGear, "Machine 9876"); Field year = Class .forName("com.example.c.Joystick") .getDeclaredField("year"); Object newInstanceOfJoystick = Class .forName("com.example.c.Joystick") .getDeclaredConstructor() .newInstance(); year.trySetAccessible(); year.set(newInstanceOfJoystick, 2017); } } } requires module_b; requires module_c; exports com.example.b.api; module_b package com.example.b.model; public class Gear { public String model; public void shift() {...} } module_c package com.example.c.model; public class Joystick { private int year; private void moveUP() {} } exports com.example.b.model opens com.example.c.model
  10. The Unnamed Module • The classpath transforms into the unnamed

    module when working with the module path. • The unnamed module exports all classes and other resource files on the classpath • Application modules cannot read the unnamed module. • The unnamed module reads other modules. • Only automatic modules can use the unnamed module. The unnamed module An application module ✖cannot read
  11. Automatic modules • A nonmodular JAR file living on the

    module path is an automatic module. • A module descriptor is generated by the module system on the fly. • The module name of a JAR is ◦ derived from the name of the JAR ▪ mongo-java-driver-3.5.0.jar ➡ mongo.java.driver ◦ given in META-INF/MANIFEST.MF ▪ Automatic-Module-Name: mongodb.java.driver • Only automatic modules can access the unamed module (the classpath). • Automatic modules access the platform modules and application modules. • Automatic modules exports all their packages.
  12. WARNING: An illegal reflective access operation has occurred WARNING: Illegal

    reflective access by org.apache.poi.openxml4j.util.ZipSecureFile$1 (file:/home/travis/.m2/repository/org/apache/poi/poi-ooxml/3.17/poi-ooxml-3.17.jar) to field java.io.FilterInputStream.in WARNING: Please consider reporting this to the maintainers of org.apache.poi.openxml4j.util.ZipSecureFile$1 WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release
  13. The jdk.unsupported Module • jdk.unsupported ◦ com/sun/nio/file ▪ ExtendedCopyOption ▪

    ExtendedOpenOption ▪ ExtendedWatchEventModifier ▪ SensitivityWatchEventModifier ◦ sun/misc ▪ Signal ▪ SignalHandler ▪ Unsafe ◦ sun/reflect ▪ Reflection ▪ ReflectionFactory module jdk.unsupported { exports com.sun.nio.file; exports sun.misc; exports sun.reflect; opens sun.misc; opens sun.reflect; }