Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Modules in Java? Finally!
Jigsaw
What is this talk all about? (Agenda)
• This talk is for a very important new feature in Java SE 9
• Code named Jigsaw, th...
Who am I? @mihailstoynov
• By day: sty.bz
• Java
• Security audits, web pen testing, sec tools
• Training, travelling ->
•...
Problems with a monolithic Java
Why do we need jigsaw? 1
• "Small" devices can run Java,
but JRE size is a problem
• Clouds don't like wasting resources
l...
Why do we need jigsaw? 2
• JDK is messy
Why do we need jigsaw? 3
• Classpath is messy
Why do we need jigsaw? 4
• People use sun.misc.* or *.internal.* APIs, which was not intended
• Securing the platform is d...
Problem: source code is monolithic 201
• JRE source code itself is monolithic – it has no modules
• Solution (JEP 201)
• R...
Problem: JRE code is not modular 200
• JRE itself is not using modules
• Solution (JEP 200)
• Create modules for code gove...
Offtopic: jmods are not for you
• .jmod format was created for the platform
• can have native code
• Overall very cool
• $...
Problem: JRE code is not modular 200
Check out the java.compact{1..3}
Problem: Internal APIs 260
• Many are using internal APIs (example: sun.misc.Unsafe)
• Solution (JEP 260)
• Provide safe a...
Problem: JRE is too big 282
• The JRE is too big
• Some distributions are over 100MB
• In mobile devices: CPU is strong en...
Problem: Put it all together 261 (376)
• JSR 376 (Java Platform Module System) proposes changes and
extensions to
• the Ja...
More problems
• The base classes had a lot of cyclic dependencies
• They had to be unwounded
• It took several years to sp...
Jigsaw in examples
Modules
JDK9 Early Access with Jigsaw
• jdk9.java.net/jigsaw
pre-Java9 class visibility
• Until Java 9 a class had the following visibility "levels":
• public
• friendly, package priv...
post-Java9 class visibility
• In Java 9 new levels of "public" are provided:
• public
• To all
• To some modules (we speci...
Creating a simple module bz.sty.logger
• Important note: just like packages, module names are dir names
• module-info.java...
Referencing the log module bz.sty.main
• module-info.java:
module bz.sty.main {
requires bz.sty.logger; //implicit
//expor...
Compile multiple modules at once
$ javac 
-d mods/ 
-modulesourcepath Logger/:Main/ 
$(find Logger/ Main/ -name *.java)
• ...
Running a multi module app
$ java 
-modulepath mods/ 
-m bz.sty.main/bz.sty.main.Program
Logger: Hello, World!
Support for Jigsaw
• Maven, Gradle
• None
• IntelliJ IDEA, Eclipse
• None
• I use IDEA modules and duplicate the dependenc...
Packaging
$ mkdir mlib
$ jar --create 
--file=mlib/bz.sty.logger@2.0.jar 
--module-version=199.0 
-C mods/bz.sty.logger .
...
What's in the jar?
$ jar --print-module-descriptor 
--file=mlib/bz.sty.main.jar
bz.sty.main
requires bz.sty.logger
require...
Transitivity ("requires public")
• We create a new module, called prettylogger
• public class PrettyLogger extends Logger
...
Quering the JDK module system
• $ java –listmods
• List all modules in the JDK
• Shows the version
• $ jmod describe $JAVA...
Jigsaw in examples
Services
Services
• Services allow for loose coupling between service
consumers modules and service providers modules
• Since Java ...
The module and the provider
module bz.sty.pluggablelogger {
exports bz.sty.pluggablelogger;
exports bz.sty.pluggablelogger...
PluggableLogger
public abstract class PluggableLogger {
public static PluggableLogger get() {
ServiceLoader<PluggableLogge...
SuperLogger (implementing module)
module bz.sty.superlogger {
requires bz.sty.pluggablelogger;
exports bz.sty.superlogger;...
Running it all together
$ javac -d mods –modulesourcepath 
PluggableLogger:PluggableLoggerImpl:PluggableLoggerMain
$(find ...
Jigsaw in examples
Custom JREs
(Jlink)
Create a custom JRE
• And now a drum roll for the coolest feature
• We hinted that it's now possible to create custom JREs...
jlink in action (example)
$ jlink --modulepath $JAVA_HOME/jmods:mlib 
--addmods bz.sty.pluggablelogger,
bz.sty.superlogger...
Stuff we didn't discuss, but it's important
• Jdeps
• A tool to check if you use internal APIs
• Unnamed modules
• All old...
Jigsaw in examples
Q&A
Upcoming SlideShare
Loading in …5
×

Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)

7,751 views

Published on

This talk is for a very important new feature in Java SE 9. Code named Jigsaw, this feature modularizes the Java SE platform.
The coolest thing we do here is to create a custom JRE

Code: https://bitbucket.org/stybz/jigsaw.sty/
PPT: https://www.slideshare.net/mihailstoynov/modules-in-java-finally-openjdk-jigsaw
Video: https://www.youtube.com/watch?v=W5LeNPtPrqw

Published in: Engineering
  • Be the first to comment

Modules in Java? Finally! (OpenJDK 9 Jigsaw, JSR376)

  1. 1. Modules in Java? Finally! Jigsaw
  2. 2. What is this talk all about? (Agenda) • This talk is for a very important new feature in Java SE 9 • Code named Jigsaw, this feature modularizes the Java SE platform • Agenda • Who am I? • Problems with monolithic java • Solutions in Java SE 9 • Jigsaw in examples • JDK9 Early Access with Jigsaw • A modular example, transitivity • Services and Custom JREs
  3. 3. Who am I? @mihailstoynov • By day: sty.bz • Java • Security audits, web pen testing, sec tools • Training, travelling -> • By night: jug.bg • Java evangelism • Submitting Java patches, writing manuals, early adoption • jprime.io – organize big java conf in Sofia • Co-authoring books, university courses • Weekends • Bikes
  4. 4. Problems with a monolithic Java
  5. 5. Why do we need jigsaw? 1 • "Small" devices can run Java, but JRE size is a problem • Clouds don't like wasting resources loading a large JRE full of unnecessary classes
  6. 6. Why do we need jigsaw? 2 • JDK is messy
  7. 7. Why do we need jigsaw? 3 • Classpath is messy
  8. 8. Why do we need jigsaw? 4 • People use sun.misc.* or *.internal.* APIs, which was not intended • Securing the platform is difficult if everyone can read anything
  9. 9. Problem: source code is monolithic 201 • JRE source code itself is monolithic – it has no modules • Solution (JEP 201) • Reorganize mercurial repo • src/share/classes/java/lang/Object.java src/share/native/java/lang/Object.c -> src/java.base/share/classes/java/lang/Object.java src/java.base/share/native/java/lang/Object.c • Rename solaris to unix • Compile repo -> compile modules • Enforce module boundaries at build time
  10. 10. Problem: JRE code is not modular 200 • JRE itself is not using modules • Solution (JEP 200) • Create modules for code governed by JCP (module java.base) • Modules for other code in the JDK (module jdk.javadoc ) • Define requires public • All reside in $JAVA_HOME/jmods
  11. 11. Offtopic: jmods are not for you • .jmod format was created for the platform • can have native code • Overall very cool • $ jmod list $JAVA_HOME/jmods/java.base.jmod --list of classes—- --native code too (so, dylib)-- • $ jmod describe $JAVA_HOME/jmods/java.base.jmod • Describes what it exports, what it conceals, who it exports it too and stuff
  12. 12. Problem: JRE code is not modular 200 Check out the java.compact{1..3}
  13. 13. Problem: Internal APIs 260 • Many are using internal APIs (example: sun.misc.Unsafe) • Solution (JEP 260) • Provide safe alternative (other JEPs) • Non critical (Base64Decoder) are encapsulated or deprecated • Critical APIs (Unsafe) are rewritten and encapsulated (JEP 259)
  14. 14. Problem: JRE is too big 282 • The JRE is too big • Some distributions are over 100MB • In mobile devices: CPU is strong enough for java, but little space • Solution (JEP 282) • In Java 9 we can create a "custom runtime image" • A tool that can do that is called jlink • The same tool can also add our application modules • Only the ones we need
  15. 15. Problem: Put it all together 261 (376) • JSR 376 (Java Platform Module System) proposes changes and extensions to • the Java programming language • the Java virtual machine • the standard Java APIs • JSR 376 Will be implemented in JEP 261 • JCP = Java Community Process (IBM, SAP, RedHat "participate") • JSR = Java Specification Request (specifies new standards, JCP) • JEP = Java Enhancement Process (implementations, non JCP)
  16. 16. More problems • The base classes had a lot of cyclic dependencies • They had to be unwounded • It took several years to specify the module format • Several abandoned formats so far • It took several years to specify the scope of Jigsaw • For example no dynamic loading/unloading • No luck for OSGi • Mark Reinhold said that this will not be implemented soon
  17. 17. Jigsaw in examples Modules
  18. 18. JDK9 Early Access with Jigsaw • jdk9.java.net/jigsaw
  19. 19. pre-Java9 class visibility • Until Java 9 a class had the following visibility "levels": • public • friendly, package private (includes protected) • protected • private
  20. 20. post-Java9 class visibility • In Java 9 new levels of "public" are provided: • public • To all • To some modules (we specify them) • Only to our module • friendly, package private (includes protected) • protected • private
  21. 21. Creating a simple module bz.sty.logger • Important note: just like packages, module names are dir names • module-info.java module bz.sty.logger { requires java.base; //implicit exports bz.sty.logger; } • Logger.java package bz.sty.logger; public class Logger { public void log(String message) { System.out.println("Logger: "+message); } } • Compilation $ javac -d mods/ Logger/bz.sty.logger/bz/sty/logger/Logger.java Logger/bz.sty.logger/module-info.java
  22. 22. Referencing the log module bz.sty.main • module-info.java: module bz.sty.main { requires bz.sty.logger; //implicit //exports bz.sty.logger; } • Program.java public class Program { public void main(String... args) { new Logger.log("Hello, World!"); } } • Compilation $ javac -d mods -modulepath mods/ Main/bz.sty.main/bz/sty/main/Program.java Main/bz.sty.main/module-info.java
  23. 23. Compile multiple modules at once $ javac -d mods/ -modulesourcepath Logger/:Main/ $(find Logger/ Main/ -name *.java) • What did we do here? • All source paths are in modulesourcepath • We use a bit of bash magic to add all java files • All should be deployed
  24. 24. Running a multi module app $ java -modulepath mods/ -m bz.sty.main/bz.sty.main.Program Logger: Hello, World!
  25. 25. Support for Jigsaw • Maven, Gradle • None • IntelliJ IDEA, Eclipse • None • I use IDEA modules and duplicate the dependencies • NetBeans • http://wiki.netbeans.org/JDK9Support • But I don't like it, so we won't use it • When will it be released • With Java SE 9 • Used to be mid'2016, jigsaw delayed it to Q1'2017 • http://www.java9countdown.xyz/ • Nobody believes it will be on time
  26. 26. Packaging $ mkdir mlib $ jar --create --file=mlib/bz.sty.logger@2.0.jar --module-version=199.0 -C mods/bz.sty.logger . $ jar --create --file=mlib/bz.sty.main.jar --main-class=bz.sty.main.Program -C mods/bz.sty.main . $ java -mp mlib -m bz.sty.main Logger: Hello, World!
  27. 27. What's in the jar? $ jar --print-module-descriptor --file=mlib/bz.sty.main.jar bz.sty.main requires bz.sty.logger requires mandated java.base conceals bz.sty.main main-class bz.sty.main.Program $ jar --print-module-descriptor --file=mlib/bz.sty.logger@2.0.jar bz.sty.logger@199.0 requires java.base exports bz.sty.logger
  28. 28. Transitivity ("requires public") • We create a new module, called prettylogger • public class PrettyLogger extends Logger • We change dependencies so that main  prettylogger  logger • The new main: public class Program { public static void main(String... args) { Logger logger = new PrettyLogger(); logger.log("Hello, World!"); } } • module-info.java module bz.sty.prettylogger { requires public bz.sty.logger; exports bz.sty.prettylogger; }
  29. 29. Quering the JDK module system • $ java –listmods • List all modules in the JDK • Shows the version • $ jmod describe $JAVA_HOME/jmods/java.base.jmod • Shows a very detailed description • $ jmod list $JAVA_HOME/jmods/java.base.jmod • A list of all classes in the jmod
  30. 30. Jigsaw in examples Services
  31. 31. Services • Services allow for loose coupling between service consumers modules and service providers modules • Since Java SE 6, ServiceLoader API allows extending applications • SL detects implementations of an interface and loads them • This solution still works nicely with Java modules • It is now sufficient the modules to be present on module-path • Basically we define an interface/abstract class and we state that we depend on their implementations • we cant run without an implementation • Other modules implement that interface/abstract class • All is defined in the module-info
  32. 32. The module and the provider module bz.sty.pluggablelogger { exports bz.sty.pluggablelogger; exports bz.sty.pluggablelogger.spi; uses bz.sty.pluggablelogger.spi.PluggableLoggerProvider; } public abstract class PluggableLoggerProvider { protected PluggableLoggerProvider() { } public abstract PluggableLogger getPluggableLogger(); }
  33. 33. PluggableLogger public abstract class PluggableLogger { public static PluggableLogger get() { ServiceLoader<PluggableLoggerProvider> sl = ServiceLoader.load(PluggableLoggerProvider.class); Iterator<PluggableLoggerProvider> iter = sl.iterator(); if (!iter.hasNext()) throw new RuntimeException("No service providers found!"); PluggableLoggerProvider provider = iter.next(); return provider.getPluggableLogger(); } protected PluggableLogger() { } public abstract void log(String message); }
  34. 34. SuperLogger (implementing module) module bz.sty.superlogger { requires bz.sty.pluggablelogger; exports bz.sty.superlogger; provides bz.sty.pluggablelogger.spi.PluggableLoggerProvider with bz.sty.superlogger.SuperLoggerProvider; } public class SuperLoggerProvider extends PluggableLoggerProvider { public PluggableLogger getPluggableLogger() { return new SuperLogger(); } } public class SuperLogger extends PluggableLogger { public void log(String message) { System.out.println("SuperLogger: " + message); } }
  35. 35. Running it all together $ javac -d mods –modulesourcepath PluggableLogger:PluggableLoggerImpl:PluggableLoggerMain $(find Pluggable* -name *.java) $ jar --create --file=X.jar –C mods/mdl . $ java -mp mlib/ -m bz.sty.pluggableloggerexample SuperLogger: Hello, World! $ java -Xdiag:resolver
  36. 36. Jigsaw in examples Custom JREs (Jlink)
  37. 37. Create a custom JRE • And now a drum roll for the coolest feature • We hinted that it's now possible to create custom JREs • The tool is called JLINK • jlink takes the smallest set of needed jars and jmods and creates a new JRE in a dir. Very WOW
  38. 38. jlink in action (example) $ jlink --modulepath $JAVA_HOME/jmods:mlib --addmods bz.sty.pluggablelogger, bz.sty.superlogger, bz.sty.pluggableloggerexample --output CustomVM $ CustomVM/bin/java -listmods $ CustomVM/bin/java -m bz.sty.pluggableloggerexample SuperLogger: Hello, World! $ du –sh CustomVM/ 30M $ du -sh $JAVA_HOME 408M
  39. 39. Stuff we didn't discuss, but it's important • Jdeps • A tool to check if you use internal APIs • Unnamed modules • All old jars • Automatic modules • Making old jars to modules • Migrating an application gradually • Not difficult at all, but only after IntelliJ/Eclipse and maven support • The console is difficult • Mixing --classpath and --modulepath • It takes some getting used to
  40. 40. Jigsaw in examples Q&A

×