SlideShare a Scribd company logo
1 of 80
Download to read offline
Designing for Modularity
Paul Bakker
@pbakker
Sander Mak
@Sander_Mak
with Java 9
Today's journey
Module primer
Services & DI
Modular design
Layers & loading
Designing for Modularity with Java 9
What if we ...
... forget about the classpath
... embrace modules
... want to create truly modular software?
Designing for Modularity with Java 9
What if we ...
... forget about the classpath
... embrace modules
... want to create truly modular software?
Design Constraints Patterns
A Module Primer
module easytext.cli {
requires easytext.analysis;
}
module easytext.analysis {
exports analysis.api;
opens impl;
}
easytext.cli easytext.analysis
other
analysis.api
impl
reflection only!
A Module Primer
module easytext.cli {
requires easytext.analysis;
}
module easytext.analysis {
exports analysis.api;
opens impl;
}
Modules define dependencies
explicitly
easytext.cli easytext.analysis
other
analysis.api
impl
reflection only!
module easytext.cli {
requires easytext.analysis;
}
A Module Primer
module easytext.analysis {
exports analysis.api;
opens impl;
}
Packages are encapsulated by
default
easytext.cli easytext.analysis
other
analysis.api
impl
reflection only!
module easytext.cli {
requires easytext.analysis;
}
A Module Primer
module easytext.analysis {
exports analysis.api;
opens impl;
}
Packages can be “opened” for
deep reflection at run-time
easytext.cli easytext.analysis
other
analysis.api
impl
reflection only!
Services
EasyText example
easytext.gui
easytext.analysis.kincaid easytext.analysis.coleman
easytext.cli
analysis.api
EasyText example
easytext.gui
easytext.analysis.kincaid easytext.analysis.coleman
easytext.cli
analysis.api
Encapsulation vs. decoupling
Analyzer i = new KincaidAnalyzer();
‣ Even with interfaces, an instance has to be
created…
Encapsulation vs. decoupling
Analyzer i = new KincaidAnalyzer();
‣ Even with interfaces, an instance has to be
created…
‣ We need to export our implementation! :-(
module easytext.kincaid {
exports easytext.analysis.kincaid;
}
Reflection isn’t a workaround
Class myImpl = Class.forName(…);
MyInterface i = myImpl.newInstance();
‣ Package needs to be open
module easytext.kincaid {
opens easytext.analysis.kincaid;
}
Services to the rescue
easytext.gui
easytext.analysis.kincaid easytext.analysis.coleman
easytext.cli
Module System
uses uses
providesprovides
Providing a service
module easytext.analyzer.kincaid {
requires easytext.analysis.api;
provides javamodularity.easytext.analysis.api.Analyzer
with javamodularity.easytext.analysis.kincaid.KincaidAnalyzer;
}
Implementing a service
public class KincaidAnalyzer implements Analyzer {
public KincaidAnalyzer() { }
@Override
public double analyze(List<List<String>> sentences) {
…
}
}
‣ Just a plain Java class
‣ Not exported!
Consuming a service
module easytext.cli {
requires easytext.analysis.api;
uses javamodularity.easytext.analysis.api.Analyzer;
}
Consuming a service
Iterable<Analyzer> analyzers = ServiceLoader.load(Analyzer.class);
for (Analyzer analyzer: analyzers) {
System.out.println(
analyzer.getName() + ": " + analyzer.analyze(sentences));
}
module easytext.cli {
requires easytext.analysis.api;
uses javamodularity.easytext.analysis.api.Analyzer;
}
Finding the right service
ServiceLoader<Analyzer> analyzers =
ServiceLoader.load(Analyzer.class);
analyzers.stream()
.filter(provider -> …)
.map(ServiceLoader.Provider::get)
.forEach(analyzer -> System.out.println(analyzer.getName()));
‣ ServiceLoader supports streams
‣ Lazy instantiation of services
Add new
analyses by
adding provider
modules on the
module path
Dependency Injection
Providing a Guice service
public class ColemanModule extends AbstractModule {
@Override
protected void configure() {
Multibinder
.newSetBinder(binder(), Analyzer.class)
.addBinding().to(ColemanAnalyzer.class);
}
‣ Provider module should export a Guice Module
Providing a Guice service
‣ Consumers must be able to compile against the
Guice module
‣ Service impl package must be open
module easytext.algorithm.coleman {
requires easytext.algorithm.api;
requires guice;
requires guice.multibindings;
exports javamodularity.easytext.algorithm.coleman.guice;
opens javamodularity.easytext.algorithm.coleman;
}
javamodularity
│   └── easytext
│   └── algorithm
│   └── coleman
│   ├── ColemanAnalyzer.java
│   └── guice
│   └── ColemanModule.java
└── module-info.java
Consuming a Guice service
public class Main {
public static void main(String... args) {
Injector injector =
Guice.createInjector(
new ColemanModule(),
new KincaidModule());
CLI cli = injector.getInstance(CLI.class);
cli.analyze(args[0]);
}
}
Consuming a Guice service
‣ Require the implementation Guice modules
‣ Open package for Guice injection
module easytext.cli {
requires easytext.algorithm.api;
requires guice;
requires easytext.algorithm.coleman;
requires easytext.algorithm.kincaid;
opens javamodularity.easytext.cli;
}
Consuming a Guice service
‣ Now we can @Inject
public class CLI {
private final Set<Analyzer> analyzers;
@Inject
public CLI(Set<Analyzer> analyzers) {
this.analyzers = analyzers;
}
…
Injecting a service
algorithm.coleman
guice
Create binding
Injecting a service
cli
Requires Guice module
algorithm.coleman
guice
Create binding
Injecting a service
cli
Requires Guice module
algorithm.coleman
guice
Create binding
Create injector
Injecting a service
cli
Requires Guice module
algorithm.coleman
guice
Create binding Inject instance
Create injector
Services vs Guice
‣ @Inject vs using an API
‣ Developers might be more familiar the model
‣ Requires more coupling
‣ Adding an implementation requires code changes
Benefits of using Guice
Downsides of using Guice
Services *and* Guice
module easytext.algorithm.coleman {
requires easytext.algorithm.api;
requires guice;
requires guice.multibindings;
exports javamodularity.easytext.algorithm.coleman.guice;
opens javamodularity.easytext.algorithm.coleman;
}
Services *and* Guice
module easytext.algorithm.coleman {
requires easytext.algorithm.api;
requires guice;
requires guice.multibindings;
exports javamodularity.easytext.algorithm.coleman.guice;
opens javamodularity.easytext.algorithm.coleman;
}
provides com.google.inject.AbstractModule
with javamodularity.easytext.algorithm.coleman.guice.ColemanModule
Services *and* Guice
module easytext.cli {
requires easytext.algorithm.api;
requires guice;
requires easytext.algorithm.coleman;
requires easytext.algorithm.kincaid;
opens javamodularity.easytext.cli;
}
Services *and* Guice
module easytext.cli {
requires easytext.algorithm.api;
requires guice;
requires easytext.algorithm.coleman;
requires easytext.algorithm.kincaid;
opens javamodularity.easytext.cli;
}
uses com.google.inject.AbstractModule
Modular Design
Naming Modules
... is hard
Naming Modules
... is hard
Application modules
‣ Short & memorable
‣ <application>.<component>
‣ e.g. easytext.gui
Naming Modules
... is hard
Application modules
‣ Short & memorable
‣ <application>.<component>
‣ e.g. easytext.gui
vs. Library modules
‣ Uniqueness
‣ Reverse DNS
‣ com.mycompany.ourlib
‣ 'Root package'
API Modules
API Modules
‣ Module with exported API only
‣ When multiple implementations are expected
‣ Can also contain 'default' implementation
API Modules
‣ Module with exported API only
‣ When multiple implementations are expected
‣ Can also contain 'default' implementation
‣ API modules export:
‣ Interfaces
‣ (Abstract) classes
‣ Exceptions
‣ Etc.
Small Modules vs. All-in-one
Small Modules vs. All-in-one
‣ Composability
‣ Reusability
Small modules
Small Modules vs. All-in-one
‣ Composability
‣ Reusability
Small modules
‣ Ease-of-use
All-in-one modules ?
?
?
?
?
Small Modules vs. All-in-one
Why choose? Use aggregator modules
Small Modules vs. All-in-one
Why choose? Use aggregator modules
module mylib {
requires transitive mylib.one;
requires transitive mylib.two;
requires transitive mylib.three;
}

Module without code, using implied readability:
Small Modules vs. All-in-one
Why choose? Use aggregator modules
module mylib {
requires transitive mylib.one;
requires transitive mylib.two;
requires transitive mylib.three;
}

Module without code, using implied readability: mylib
mylib.one
mylib.two
mylib.three
Small Modules vs. All-in-one
Why choose? Use aggregator modules
mylib
mylib.one
mylib.two
mylib.three
application
Small Modules vs. All-in-one
Why choose? Use aggregator modules
mylib
mylib.one
mylib.two
mylib.three
application
Small Modules vs. All-in-one
Why choose? Use aggregator modules
mylib
mylib.one
mylib.two
mylib.three
application
Implied readability
Small Modules vs. All-in-one
mylib.extra
mylib.core
Small Modules vs. All-in-one
mylib.extra
mylib.core
application
Small Modules vs. All-in-one
mylib.extra
mylib.core
application
Small Modules vs. All-in-one
mylib.extra
mylib.core
application
Breaking cycles
‣ Non-modular JARs can have cyclic dependencies
‣ Modules can not
Breaking cycles
Breaking cycles
public class Author {
private String name;
private List<Book> books;
public Author(String name)
{
this.name = name;
}
// ..
}
Breaking cycles
public class Author {
private String name;
private List<Book> books;
public Author(String name)
{
this.name = name;
}
// ..
}
public class Book {
public Author author;
public String title;
public void printBook() {
System.out.printf(
"%s, by %snn%s",
title, author.getName(),
text);
}
Breaking cycles
public class Author {
private String name;
private List<Book> books;
public Author(String name)
{
this.name = name;
}
// ..
}
public class Book {
public Author author;
public String title;
public void printBook() {
System.out.printf(
"%s, by %snn%s",
title, author.getName(),
text);
}
Breaking cycles
public class Author {
private String name;
private List<Book> books;
public Author(String name)
{
this.name = name;
}
// ..
}
public class Book {
public Author author;
public String title;
public void printBook() {
System.out.printf(
"%s, by %snn%s",
title, author.getName(),
text);
}
Breaking cycles: abstraction
Breaking cycles: abstraction
public class Author
implements Named {
// ..
public String getName() {
return this.name;
}
}
Breaking cycles: abstraction
public class Author
implements Named {
// ..
public String getName() {
return this.name;
}
}
public interface Named {
String getName();
}
Optional dependencies
‣ Requires means compile-time and run-time dependency
‣ What if we want an optional dependency?
‣ Use it if available at run-time
‣ Otherwise, run without
Optional dependencies
‣ Requires means compile-time and run-time dependency
‣ What if we want an optional dependency?
‣ Use it if available at run-time
‣ Otherwise, run without
Compile-time only dependencies:
module framework {
requires static fastjsonlib;
}
Optional dependencies
‣ Requires means compile-time and run-time dependency
‣ What if we want an optional dependency?
‣ Use it if available at run-time
‣ Otherwise, run without
Compile-time only dependencies:
module framework {
requires static fastjsonlib;
}
Resolve fastjsonlib if available at run-time, ignore if not
Optional dependencies
Avoid run-time exceptions!
Optional dependencies
try {
Class<?> clazz =
Class.forName("javamodularity.fastjsonlib.FastJson");
FastJson instance =
(FastJson) clazz.getConstructor().newInstance();
System.out.println("Using FastJson");
} catch (ReflectiveOperationException e) {
System.out.println("Oops, we need a fallback!");
}
Avoid run-time exceptions!
Optional dependencies
Better yet: use services for optional dependencies
module framework {
requires json.api;
uses json.api.Json;
}
ServiceLoader.load(Json.class)
.stream()
.filter(this::isFast)
.findFirst();
Layers and
dynamic module
loading
ModuleLayer
mods
├── easytext.algorithm.api
├── easytext.algorithm.coleman
├── easytext.algorithm.kincaid
├── easytext.algorithm.naivesyllablecounter
├── easytext.algorithm.nextgensyllablecounter
├── easytext.cli
└── easytext.gui
Module path
ModuleLayer
mods
├── easytext.algorithm.api
├── easytext.algorithm.coleman
├── easytext.algorithm.kincaid
├── easytext.algorithm.naivesyllablecounter
├── easytext.algorithm.nextgensyllablecounter
├── easytext.cli
└── easytext.gui
Module path
boot layer
api coleman
kincaid gui
...
at run-time
ModuleLayer
Immutable boot layer
api coleman
kincaid gui
...
One version of a module
No dynamic loading?
App & platform modules
ModuleLayer
boot layer
api
gui
...
Create layers at run-time
Multiple versions in layers
Layers form hierarchy
ModuleLayer
boot layer
api
gui
...
layer 1
coleman
parent
Create layers at run-time
Multiple versions in layers
Layers form hierarchy
ModuleLayer
boot layer
api
gui
...
layer 1
coleman
parent
layer 2
kincaid
syllable.
counter
parent
Create layers at run-time
Multiple versions in layers
Layers form hierarchy
ModuleLayer Demo
Thank you.
https://javamodularity.com
Paul Bakker
@pbakker
Sander Mak
@Sander_Mak

More Related Content

What's hot

Modularity of the Java Platform (OSGi, Jigsaw and Penrose)
Modularity of the Java Platform (OSGi, Jigsaw and Penrose)Modularity of the Java Platform (OSGi, Jigsaw and Penrose)
Modularity of the Java Platform (OSGi, Jigsaw and Penrose)Martin Toshev
 
Java 9 Modularity and Project Jigsaw
Java 9 Modularity and Project JigsawJava 9 Modularity and Project Jigsaw
Java 9 Modularity and Project JigsawComsysto Reply GmbH
 
Java SE 9 modules (JPMS) - an introduction
Java SE 9 modules (JPMS) - an introductionJava SE 9 modules (JPMS) - an introduction
Java SE 9 modules (JPMS) - an introductionStephen Colebourne
 
Benefits of OSGi in Practise
Benefits of OSGi in PractiseBenefits of OSGi in Practise
Benefits of OSGi in PractiseDavid Bosschaert
 
Java 9 New Features
Java 9 New FeaturesJava 9 New Features
Java 9 New FeaturesAli BAKAN
 
Modular Java applications with OSGi on Apache Karaf
Modular Java applications with OSGi on Apache KarafModular Java applications with OSGi on Apache Karaf
Modular Java applications with OSGi on Apache KarafIoan Eugen Stan
 
Open Services Gateway Initiative (OSGI)
Open Services Gateway Initiative (OSGI)Open Services Gateway Initiative (OSGI)
Open Services Gateway Initiative (OSGI)Peter R. Egli
 
Modularization With Project Jigsaw in JDK 9
Modularization With Project Jigsaw in JDK 9Modularization With Project Jigsaw in JDK 9
Modularization With Project Jigsaw in JDK 9Simon Ritter
 
Migrating to java 9 modules
Migrating to java 9 modulesMigrating to java 9 modules
Migrating to java 9 modulesPaul Bakker
 
Polygot Java EE on the GraalVM
Polygot Java EE on the GraalVMPolygot Java EE on the GraalVM
Polygot Java EE on the GraalVMRyan Cuprak
 
Java Modularity with OSGi
Java Modularity with OSGiJava Modularity with OSGi
Java Modularity with OSGiIlya Rybak
 
Step by step guide to create theme for liferay dxp 7
Step by step guide to create theme for liferay dxp 7Step by step guide to create theme for liferay dxp 7
Step by step guide to create theme for liferay dxp 7Azilen Technologies Pvt. Ltd.
 
Java 10 New Features
Java 10 New FeaturesJava 10 New Features
Java 10 New FeaturesAli BAKAN
 

What's hot (20)

Modularity of the Java Platform (OSGi, Jigsaw and Penrose)
Modularity of the Java Platform (OSGi, Jigsaw and Penrose)Modularity of the Java Platform (OSGi, Jigsaw and Penrose)
Modularity of the Java Platform (OSGi, Jigsaw and Penrose)
 
Java 9 Modularity and Project Jigsaw
Java 9 Modularity and Project JigsawJava 9 Modularity and Project Jigsaw
Java 9 Modularity and Project Jigsaw
 
Java SE 9 modules (JPMS) - an introduction
Java SE 9 modules (JPMS) - an introductionJava SE 9 modules (JPMS) - an introduction
Java SE 9 modules (JPMS) - an introduction
 
Java 9 and Project Jigsaw
Java 9 and Project JigsawJava 9 and Project Jigsaw
Java 9 and Project Jigsaw
 
Java modularization
Java modularizationJava modularization
Java modularization
 
Java 9 preview
Java 9 previewJava 9 preview
Java 9 preview
 
JDK-9: Modules and Java Linker
JDK-9: Modules and Java LinkerJDK-9: Modules and Java Linker
JDK-9: Modules and Java Linker
 
Benefits of OSGi in Practise
Benefits of OSGi in PractiseBenefits of OSGi in Practise
Benefits of OSGi in Practise
 
Java 9 New Features
Java 9 New FeaturesJava 9 New Features
Java 9 New Features
 
Coding Your Way to Java 12
Coding Your Way to Java 12Coding Your Way to Java 12
Coding Your Way to Java 12
 
Modular Java applications with OSGi on Apache Karaf
Modular Java applications with OSGi on Apache KarafModular Java applications with OSGi on Apache Karaf
Modular Java applications with OSGi on Apache Karaf
 
Open Services Gateway Initiative (OSGI)
Open Services Gateway Initiative (OSGI)Open Services Gateway Initiative (OSGI)
Open Services Gateway Initiative (OSGI)
 
Modularization With Project Jigsaw in JDK 9
Modularization With Project Jigsaw in JDK 9Modularization With Project Jigsaw in JDK 9
Modularization With Project Jigsaw in JDK 9
 
Migrating to java 9 modules
Migrating to java 9 modulesMigrating to java 9 modules
Migrating to java 9 modules
 
Scala & Lift (JEEConf 2012)
Scala & Lift (JEEConf 2012)Scala & Lift (JEEConf 2012)
Scala & Lift (JEEConf 2012)
 
Polygot Java EE on the GraalVM
Polygot Java EE on the GraalVMPolygot Java EE on the GraalVM
Polygot Java EE on the GraalVM
 
Modularization in java 8
Modularization in java 8Modularization in java 8
Modularization in java 8
 
Java Modularity with OSGi
Java Modularity with OSGiJava Modularity with OSGi
Java Modularity with OSGi
 
Step by step guide to create theme for liferay dxp 7
Step by step guide to create theme for liferay dxp 7Step by step guide to create theme for liferay dxp 7
Step by step guide to create theme for liferay dxp 7
 
Java 10 New Features
Java 10 New FeaturesJava 10 New Features
Java 10 New Features
 

Similar to Desiging for Modularity with Java 9

Java modulesystem
Java modulesystemJava modulesystem
Java modulesystemMarc Kassis
 
Dependency injection in Java, from naive to functional
Dependency injection in Java, from naive to functionalDependency injection in Java, from naive to functional
Dependency injection in Java, from naive to functionalMarian Wamsiedel
 
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...Jitendra Bafna
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS MeetupLINAGORA
 
Modular JavaScript in an OSGi World - S Mak
Modular JavaScript in an OSGi World - S MakModular JavaScript in an OSGi World - S Mak
Modular JavaScript in an OSGi World - S Makmfrancis
 
Overview of the AngularJS framework
Overview of the AngularJS framework Overview of the AngularJS framework
Overview of the AngularJS framework Yakov Fain
 
Pitfalls of machine learning in production
Pitfalls of machine learning in productionPitfalls of machine learning in production
Pitfalls of machine learning in productionAntoine Sauray
 
26 top angular 8 interview questions to know in 2020 [www.full stack.cafe]
26 top angular 8 interview questions to know in 2020   [www.full stack.cafe]26 top angular 8 interview questions to know in 2020   [www.full stack.cafe]
26 top angular 8 interview questions to know in 2020 [www.full stack.cafe]Alex Ershov
 
Java programming concept
Java programming conceptJava programming concept
Java programming conceptSanjay Gunjal
 
Exploring Kotlin language basics for Android App development
Exploring Kotlin language basics for Android App developmentExploring Kotlin language basics for Android App development
Exploring Kotlin language basics for Android App developmentJayaprakash R
 
What's new in Gradle 4.0
What's new in Gradle 4.0What's new in Gradle 4.0
What's new in Gradle 4.0Eric Wendelin
 
OpenDaylight Developer Experience 2.0
 OpenDaylight Developer Experience 2.0 OpenDaylight Developer Experience 2.0
OpenDaylight Developer Experience 2.0Michael Vorburger
 
Java 9: Deep Dive into Modularity and Dealing with Migration Issues
Java 9: Deep Dive into Modularity and Dealing with Migration IssuesJava 9: Deep Dive into Modularity and Dealing with Migration Issues
Java 9: Deep Dive into Modularity and Dealing with Migration IssuesGlobalLogic Ukraine
 
Angular meetup 2 2019-08-29
Angular meetup 2   2019-08-29Angular meetup 2   2019-08-29
Angular meetup 2 2019-08-29Nitin Bhojwani
 
Creating and destroying objects
Creating and destroying objectsCreating and destroying objects
Creating and destroying objectsSandeep Chawla
 
Preparing for java 9 modules upload
Preparing for java 9 modules uploadPreparing for java 9 modules upload
Preparing for java 9 modules uploadRyan Cuprak
 
AngularJs Style Guide
AngularJs Style GuideAngularJs Style Guide
AngularJs Style GuideChiew Carol
 

Similar to Desiging for Modularity with Java 9 (20)

Java modulesystem
Java modulesystemJava modulesystem
Java modulesystem
 
Dependency injection in Java, from naive to functional
Dependency injection in Java, from naive to functionalDependency injection in Java, from naive to functional
Dependency injection in Java, from naive to functional
 
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...
MuleSoft Surat Virtual Meetup#6 - MuleSoft Project Template Using Maven Arche...
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS Meetup
 
Modular JavaScript in an OSGi World - S Mak
Modular JavaScript in an OSGi World - S MakModular JavaScript in an OSGi World - S Mak
Modular JavaScript in an OSGi World - S Mak
 
Designing Better API
Designing Better APIDesigning Better API
Designing Better API
 
Overview of the AngularJS framework
Overview of the AngularJS framework Overview of the AngularJS framework
Overview of the AngularJS framework
 
Pitfalls of machine learning in production
Pitfalls of machine learning in productionPitfalls of machine learning in production
Pitfalls of machine learning in production
 
26 top angular 8 interview questions to know in 2020 [www.full stack.cafe]
26 top angular 8 interview questions to know in 2020   [www.full stack.cafe]26 top angular 8 interview questions to know in 2020   [www.full stack.cafe]
26 top angular 8 interview questions to know in 2020 [www.full stack.cafe]
 
Java programming concept
Java programming conceptJava programming concept
Java programming concept
 
Exploring Kotlin language basics for Android App development
Exploring Kotlin language basics for Android App developmentExploring Kotlin language basics for Android App development
Exploring Kotlin language basics for Android App development
 
What's new in Gradle 4.0
What's new in Gradle 4.0What's new in Gradle 4.0
What's new in Gradle 4.0
 
OpenDaylight Developer Experience 2.0
 OpenDaylight Developer Experience 2.0 OpenDaylight Developer Experience 2.0
OpenDaylight Developer Experience 2.0
 
Java 9: Deep Dive into Modularity and Dealing with Migration Issues
Java 9: Deep Dive into Modularity and Dealing with Migration IssuesJava 9: Deep Dive into Modularity and Dealing with Migration Issues
Java 9: Deep Dive into Modularity and Dealing with Migration Issues
 
Angular meetup 2 2019-08-29
Angular meetup 2   2019-08-29Angular meetup 2   2019-08-29
Angular meetup 2 2019-08-29
 
Creating and destroying objects
Creating and destroying objectsCreating and destroying objects
Creating and destroying objects
 
java.pptx
java.pptxjava.pptx
java.pptx
 
JavaScript Module Loaders
JavaScript Module LoadersJavaScript Module Loaders
JavaScript Module Loaders
 
Preparing for java 9 modules upload
Preparing for java 9 modules uploadPreparing for java 9 modules upload
Preparing for java 9 modules upload
 
AngularJs Style Guide
AngularJs Style GuideAngularJs Style Guide
AngularJs Style Guide
 

More from Sander Mak (@Sander_Mak)

TypeScript: coding JavaScript without the pain
TypeScript: coding JavaScript without the painTypeScript: coding JavaScript without the pain
TypeScript: coding JavaScript without the painSander Mak (@Sander_Mak)
 
The Ultimate Dependency Manager Shootout (QCon NY 2014)
The Ultimate Dependency Manager Shootout (QCon NY 2014)The Ultimate Dependency Manager Shootout (QCon NY 2014)
The Ultimate Dependency Manager Shootout (QCon NY 2014)Sander Mak (@Sander_Mak)
 
Cross-Build Injection attacks: how safe is your Java build?
Cross-Build Injection attacks: how safe is your Java build?Cross-Build Injection attacks: how safe is your Java build?
Cross-Build Injection attacks: how safe is your Java build?Sander Mak (@Sander_Mak)
 
Hibernate Performance Tuning (JEEConf 2012)
Hibernate Performance Tuning (JEEConf 2012)Hibernate Performance Tuning (JEEConf 2012)
Hibernate Performance Tuning (JEEConf 2012)Sander Mak (@Sander_Mak)
 
Java 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the futureJava 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the futureSander Mak (@Sander_Mak)
 
JDK7: Improved support for dynamic languages
JDK7: Improved support for dynamic languagesJDK7: Improved support for dynamic languages
JDK7: Improved support for dynamic languagesSander Mak (@Sander_Mak)
 
Scala: functional programming for the imperative mind
Scala: functional programming for the imperative mindScala: functional programming for the imperative mind
Scala: functional programming for the imperative mindSander Mak (@Sander_Mak)
 

More from Sander Mak (@Sander_Mak) (20)

Scalable Application Development @ Picnic
Scalable Application Development @ PicnicScalable Application Development @ Picnic
Scalable Application Development @ Picnic
 
Coding Your Way to Java 13
Coding Your Way to Java 13Coding Your Way to Java 13
Coding Your Way to Java 13
 
Provisioning the IoT
Provisioning the IoTProvisioning the IoT
Provisioning the IoT
 
Event-sourced architectures with Akka
Event-sourced architectures with AkkaEvent-sourced architectures with Akka
Event-sourced architectures with Akka
 
TypeScript: coding JavaScript without the pain
TypeScript: coding JavaScript without the painTypeScript: coding JavaScript without the pain
TypeScript: coding JavaScript without the pain
 
The Ultimate Dependency Manager Shootout (QCon NY 2014)
The Ultimate Dependency Manager Shootout (QCon NY 2014)The Ultimate Dependency Manager Shootout (QCon NY 2014)
The Ultimate Dependency Manager Shootout (QCon NY 2014)
 
Modularity in the Cloud
Modularity in the CloudModularity in the Cloud
Modularity in the Cloud
 
Cross-Build Injection attacks: how safe is your Java build?
Cross-Build Injection attacks: how safe is your Java build?Cross-Build Injection attacks: how safe is your Java build?
Cross-Build Injection attacks: how safe is your Java build?
 
Hibernate Performance Tuning (JEEConf 2012)
Hibernate Performance Tuning (JEEConf 2012)Hibernate Performance Tuning (JEEConf 2012)
Hibernate Performance Tuning (JEEConf 2012)
 
Akka (BeJUG)
Akka (BeJUG)Akka (BeJUG)
Akka (BeJUG)
 
Fork Join (BeJUG 2012)
Fork Join (BeJUG 2012)Fork Join (BeJUG 2012)
Fork Join (BeJUG 2012)
 
Fork/Join for Fun and Profit!
Fork/Join for Fun and Profit!Fork/Join for Fun and Profit!
Fork/Join for Fun and Profit!
 
Kscope11 recap
Kscope11 recapKscope11 recap
Kscope11 recap
 
Java 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the futureJava 7: Fork/Join, Invokedynamic and the future
Java 7: Fork/Join, Invokedynamic and the future
 
Scala and Lift
Scala and LiftScala and Lift
Scala and Lift
 
Elevate your webapps with Scala and Lift
Elevate your webapps with Scala and LiftElevate your webapps with Scala and Lift
Elevate your webapps with Scala and Lift
 
Hibernate performance tuning
Hibernate performance tuningHibernate performance tuning
Hibernate performance tuning
 
JDK7: Improved support for dynamic languages
JDK7: Improved support for dynamic languagesJDK7: Improved support for dynamic languages
JDK7: Improved support for dynamic languages
 
Scala: functional programming for the imperative mind
Scala: functional programming for the imperative mindScala: functional programming for the imperative mind
Scala: functional programming for the imperative mind
 
Recursion Pattern Analysis and Feedback
Recursion Pattern Analysis and FeedbackRecursion Pattern Analysis and Feedback
Recursion Pattern Analysis and Feedback
 

Recently uploaded

Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 

Recently uploaded (20)

Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 

Desiging for Modularity with Java 9

  • 1. Designing for Modularity Paul Bakker @pbakker Sander Mak @Sander_Mak with Java 9
  • 2. Today's journey Module primer Services & DI Modular design Layers & loading
  • 3. Designing for Modularity with Java 9 What if we ... ... forget about the classpath ... embrace modules ... want to create truly modular software?
  • 4. Designing for Modularity with Java 9 What if we ... ... forget about the classpath ... embrace modules ... want to create truly modular software? Design Constraints Patterns
  • 5. A Module Primer module easytext.cli { requires easytext.analysis; } module easytext.analysis { exports analysis.api; opens impl; } easytext.cli easytext.analysis other analysis.api impl reflection only!
  • 6. A Module Primer module easytext.cli { requires easytext.analysis; } module easytext.analysis { exports analysis.api; opens impl; } Modules define dependencies explicitly easytext.cli easytext.analysis other analysis.api impl reflection only!
  • 7. module easytext.cli { requires easytext.analysis; } A Module Primer module easytext.analysis { exports analysis.api; opens impl; } Packages are encapsulated by default easytext.cli easytext.analysis other analysis.api impl reflection only!
  • 8. module easytext.cli { requires easytext.analysis; } A Module Primer module easytext.analysis { exports analysis.api; opens impl; } Packages can be “opened” for deep reflection at run-time easytext.cli easytext.analysis other analysis.api impl reflection only!
  • 12. Encapsulation vs. decoupling Analyzer i = new KincaidAnalyzer(); ‣ Even with interfaces, an instance has to be created…
  • 13. Encapsulation vs. decoupling Analyzer i = new KincaidAnalyzer(); ‣ Even with interfaces, an instance has to be created… ‣ We need to export our implementation! :-( module easytext.kincaid { exports easytext.analysis.kincaid; }
  • 14. Reflection isn’t a workaround Class myImpl = Class.forName(…); MyInterface i = myImpl.newInstance(); ‣ Package needs to be open module easytext.kincaid { opens easytext.analysis.kincaid; }
  • 15. Services to the rescue easytext.gui easytext.analysis.kincaid easytext.analysis.coleman easytext.cli Module System uses uses providesprovides
  • 16. Providing a service module easytext.analyzer.kincaid { requires easytext.analysis.api; provides javamodularity.easytext.analysis.api.Analyzer with javamodularity.easytext.analysis.kincaid.KincaidAnalyzer; }
  • 17. Implementing a service public class KincaidAnalyzer implements Analyzer { public KincaidAnalyzer() { } @Override public double analyze(List<List<String>> sentences) { … } } ‣ Just a plain Java class ‣ Not exported!
  • 18. Consuming a service module easytext.cli { requires easytext.analysis.api; uses javamodularity.easytext.analysis.api.Analyzer; }
  • 19. Consuming a service Iterable<Analyzer> analyzers = ServiceLoader.load(Analyzer.class); for (Analyzer analyzer: analyzers) { System.out.println( analyzer.getName() + ": " + analyzer.analyze(sentences)); } module easytext.cli { requires easytext.analysis.api; uses javamodularity.easytext.analysis.api.Analyzer; }
  • 20. Finding the right service ServiceLoader<Analyzer> analyzers = ServiceLoader.load(Analyzer.class); analyzers.stream() .filter(provider -> …) .map(ServiceLoader.Provider::get) .forEach(analyzer -> System.out.println(analyzer.getName())); ‣ ServiceLoader supports streams ‣ Lazy instantiation of services
  • 21. Add new analyses by adding provider modules on the module path
  • 23. Providing a Guice service public class ColemanModule extends AbstractModule { @Override protected void configure() { Multibinder .newSetBinder(binder(), Analyzer.class) .addBinding().to(ColemanAnalyzer.class); } ‣ Provider module should export a Guice Module
  • 24. Providing a Guice service ‣ Consumers must be able to compile against the Guice module ‣ Service impl package must be open module easytext.algorithm.coleman { requires easytext.algorithm.api; requires guice; requires guice.multibindings; exports javamodularity.easytext.algorithm.coleman.guice; opens javamodularity.easytext.algorithm.coleman; } javamodularity │   └── easytext │   └── algorithm │   └── coleman │   ├── ColemanAnalyzer.java │   └── guice │   └── ColemanModule.java └── module-info.java
  • 25. Consuming a Guice service public class Main { public static void main(String... args) { Injector injector = Guice.createInjector( new ColemanModule(), new KincaidModule()); CLI cli = injector.getInstance(CLI.class); cli.analyze(args[0]); } }
  • 26. Consuming a Guice service ‣ Require the implementation Guice modules ‣ Open package for Guice injection module easytext.cli { requires easytext.algorithm.api; requires guice; requires easytext.algorithm.coleman; requires easytext.algorithm.kincaid; opens javamodularity.easytext.cli; }
  • 27. Consuming a Guice service ‣ Now we can @Inject public class CLI { private final Set<Analyzer> analyzers; @Inject public CLI(Set<Analyzer> analyzers) { this.analyzers = analyzers; } …
  • 29. Injecting a service cli Requires Guice module algorithm.coleman guice Create binding
  • 30. Injecting a service cli Requires Guice module algorithm.coleman guice Create binding Create injector
  • 31. Injecting a service cli Requires Guice module algorithm.coleman guice Create binding Inject instance Create injector
  • 32. Services vs Guice ‣ @Inject vs using an API ‣ Developers might be more familiar the model ‣ Requires more coupling ‣ Adding an implementation requires code changes Benefits of using Guice Downsides of using Guice
  • 33. Services *and* Guice module easytext.algorithm.coleman { requires easytext.algorithm.api; requires guice; requires guice.multibindings; exports javamodularity.easytext.algorithm.coleman.guice; opens javamodularity.easytext.algorithm.coleman; }
  • 34. Services *and* Guice module easytext.algorithm.coleman { requires easytext.algorithm.api; requires guice; requires guice.multibindings; exports javamodularity.easytext.algorithm.coleman.guice; opens javamodularity.easytext.algorithm.coleman; } provides com.google.inject.AbstractModule with javamodularity.easytext.algorithm.coleman.guice.ColemanModule
  • 35. Services *and* Guice module easytext.cli { requires easytext.algorithm.api; requires guice; requires easytext.algorithm.coleman; requires easytext.algorithm.kincaid; opens javamodularity.easytext.cli; }
  • 36. Services *and* Guice module easytext.cli { requires easytext.algorithm.api; requires guice; requires easytext.algorithm.coleman; requires easytext.algorithm.kincaid; opens javamodularity.easytext.cli; } uses com.google.inject.AbstractModule
  • 39. Naming Modules ... is hard Application modules ‣ Short & memorable ‣ <application>.<component> ‣ e.g. easytext.gui
  • 40. Naming Modules ... is hard Application modules ‣ Short & memorable ‣ <application>.<component> ‣ e.g. easytext.gui vs. Library modules ‣ Uniqueness ‣ Reverse DNS ‣ com.mycompany.ourlib ‣ 'Root package'
  • 42. API Modules ‣ Module with exported API only ‣ When multiple implementations are expected ‣ Can also contain 'default' implementation
  • 43. API Modules ‣ Module with exported API only ‣ When multiple implementations are expected ‣ Can also contain 'default' implementation ‣ API modules export: ‣ Interfaces ‣ (Abstract) classes ‣ Exceptions ‣ Etc.
  • 44. Small Modules vs. All-in-one
  • 45. Small Modules vs. All-in-one ‣ Composability ‣ Reusability Small modules
  • 46. Small Modules vs. All-in-one ‣ Composability ‣ Reusability Small modules ‣ Ease-of-use All-in-one modules ? ? ? ? ?
  • 47. Small Modules vs. All-in-one Why choose? Use aggregator modules
  • 48. Small Modules vs. All-in-one Why choose? Use aggregator modules module mylib { requires transitive mylib.one; requires transitive mylib.two; requires transitive mylib.three; }
 Module without code, using implied readability:
  • 49. Small Modules vs. All-in-one Why choose? Use aggregator modules module mylib { requires transitive mylib.one; requires transitive mylib.two; requires transitive mylib.three; }
 Module without code, using implied readability: mylib mylib.one mylib.two mylib.three
  • 50. Small Modules vs. All-in-one Why choose? Use aggregator modules mylib mylib.one mylib.two mylib.three application
  • 51. Small Modules vs. All-in-one Why choose? Use aggregator modules mylib mylib.one mylib.two mylib.three application
  • 52. Small Modules vs. All-in-one Why choose? Use aggregator modules mylib mylib.one mylib.two mylib.three application Implied readability
  • 53. Small Modules vs. All-in-one mylib.extra mylib.core
  • 54. Small Modules vs. All-in-one mylib.extra mylib.core application
  • 55. Small Modules vs. All-in-one mylib.extra mylib.core application
  • 56. Small Modules vs. All-in-one mylib.extra mylib.core application
  • 57. Breaking cycles ‣ Non-modular JARs can have cyclic dependencies ‣ Modules can not
  • 59. Breaking cycles public class Author { private String name; private List<Book> books; public Author(String name) { this.name = name; } // .. }
  • 60. Breaking cycles public class Author { private String name; private List<Book> books; public Author(String name) { this.name = name; } // .. } public class Book { public Author author; public String title; public void printBook() { System.out.printf( "%s, by %snn%s", title, author.getName(), text); }
  • 61. Breaking cycles public class Author { private String name; private List<Book> books; public Author(String name) { this.name = name; } // .. } public class Book { public Author author; public String title; public void printBook() { System.out.printf( "%s, by %snn%s", title, author.getName(), text); }
  • 62. Breaking cycles public class Author { private String name; private List<Book> books; public Author(String name) { this.name = name; } // .. } public class Book { public Author author; public String title; public void printBook() { System.out.printf( "%s, by %snn%s", title, author.getName(), text); }
  • 64. Breaking cycles: abstraction public class Author implements Named { // .. public String getName() { return this.name; } }
  • 65. Breaking cycles: abstraction public class Author implements Named { // .. public String getName() { return this.name; } } public interface Named { String getName(); }
  • 66. Optional dependencies ‣ Requires means compile-time and run-time dependency ‣ What if we want an optional dependency? ‣ Use it if available at run-time ‣ Otherwise, run without
  • 67. Optional dependencies ‣ Requires means compile-time and run-time dependency ‣ What if we want an optional dependency? ‣ Use it if available at run-time ‣ Otherwise, run without Compile-time only dependencies: module framework { requires static fastjsonlib; }
  • 68. Optional dependencies ‣ Requires means compile-time and run-time dependency ‣ What if we want an optional dependency? ‣ Use it if available at run-time ‣ Otherwise, run without Compile-time only dependencies: module framework { requires static fastjsonlib; } Resolve fastjsonlib if available at run-time, ignore if not
  • 70. Optional dependencies try { Class<?> clazz = Class.forName("javamodularity.fastjsonlib.FastJson"); FastJson instance = (FastJson) clazz.getConstructor().newInstance(); System.out.println("Using FastJson"); } catch (ReflectiveOperationException e) { System.out.println("Oops, we need a fallback!"); } Avoid run-time exceptions!
  • 71. Optional dependencies Better yet: use services for optional dependencies module framework { requires json.api; uses json.api.Json; } ServiceLoader.load(Json.class) .stream() .filter(this::isFast) .findFirst();
  • 73. ModuleLayer mods ├── easytext.algorithm.api ├── easytext.algorithm.coleman ├── easytext.algorithm.kincaid ├── easytext.algorithm.naivesyllablecounter ├── easytext.algorithm.nextgensyllablecounter ├── easytext.cli └── easytext.gui Module path
  • 74. ModuleLayer mods ├── easytext.algorithm.api ├── easytext.algorithm.coleman ├── easytext.algorithm.kincaid ├── easytext.algorithm.naivesyllablecounter ├── easytext.algorithm.nextgensyllablecounter ├── easytext.cli └── easytext.gui Module path boot layer api coleman kincaid gui ... at run-time
  • 75. ModuleLayer Immutable boot layer api coleman kincaid gui ... One version of a module No dynamic loading? App & platform modules
  • 76. ModuleLayer boot layer api gui ... Create layers at run-time Multiple versions in layers Layers form hierarchy
  • 77. ModuleLayer boot layer api gui ... layer 1 coleman parent Create layers at run-time Multiple versions in layers Layers form hierarchy
  • 78. ModuleLayer boot layer api gui ... layer 1 coleman parent layer 2 kincaid syllable. counter parent Create layers at run-time Multiple versions in layers Layers form hierarchy