The Java Module System
Nicolai Parlog
  • MEAP began March 2017
  • Publication in February 2018 (estimated)
  • ISBN 9781617294280
  • 275 pages (estimated)
  • printed in black & white

Java's much-awaited "Project Jigsaw" is finally here! Java 9 will include a built-in modularity framework, and The Java Module System is your guide to discovering it. In this new book, you'll learn how the module system improves reliability and maintainability and can be used to reduce tight coupling of system components. You'll then discover how to build, compile, and run your own fully modular applications with best practices and expert techniques. Along the way, you'll also explore Java 9's compatibility challenges and how to migrate your application to the module system.

"The best book about the Java Module System."

~ Ivan Milosavljevic, Senior Software Developer, Novomatic Lottery Solutions

"Really clean, clear code. If only everybody would write like that..."

~ Mark Dechamps, Java/Spring/JPA developer, Agfa HealthCare

"A very pragmatic book that doesn't waste time in useless information"

~ Guido Pio Mariotti, Research Engineer, Linkoping University

"Gripping and interesting"

~ Maria Gemini, Student

Table of Contents detailed table of contents

Part 1: Hello, Modules

1. First piece of the puzzle

1.1. What is modularity all about?

1.1.1. Visualizing software as graphs

1.1.2. The impact of design principles

1.1.3. What modularity is all about

1.2. Module erasure before Java 9

1.3. Complications before Java 9

1.3.1. Unexpressed dependencies

1.3.2. Shadowing

1.3.3. Version conflicts

1.3.4. Complex class loading

1.3.5. Weak encapsulation

1.3.6. Manual Security

1.3.7. Startup Performance

1.3.8. Rigid Java Runtime

1.4. Bird’s-eye view on the module system

1.4.1. Everything is a module

1.4.2. Your non-modular project will be fine—​mostly

1.4.3. The module system in action

1.5. Goals of the module system

1.5.1. Reliable configuration

1.5.2. Strong encapsulation

1.5.3. Improved security and maintainability

1.5.4. Improved performance

1.5.5. Scalable platform

1.5.6. Non-Goals

1.6. Skills, old and new

1.6.1. What you will learn

1.6.2. What you should know

1.7. Technology landscape

1.7.1. Java 9 beyond the module system

1.7.2. Maven, Gradle, and other build tools

1.7.3. OSGi

1.7.4. Microservices

1.8. Summary

2. Anatomy of a modular application

2.1. The application—​monitoring services

2.2. Modularizing the application

2.2.1. Cutting the application into modules

2.2.2. Laying files out in a directory structure

2.2.3. Module declarations (and descriptors)

2.2.4. Writing code is much like before

2.2.5. Compiling and packaging modules

2.2.6. Running the application

2.3. Post mortem—​effects of the module system

2.3.1. What the module system does for us

2.3.2. What else the module system can do for us

2.4. Summary

3. Defining modules and their properties

3.1. Modules—​the building blocks of modular applications

3.1.1. Java modules (JMODs)--shipped with the JDK

3.1.2. Modular JARs—​home-grown modules

3.1.3. Module declarations—​defining a module’s properties

3.1.4. Types of modules

3.2. Readability—​connecting the pieces

3.2.1. Achieving reliable configuration

3.2.2. Unreliable configurations

3.3. Accessibility—​defining public APIs

3.3.1. Achieving strong encapsulation

3.3.2. Encapsulating transitive dependencies

3.3.3. Encapsulation skirmishes

3.4. The module path—​letting Java know about modules

3.4.1. Module resolution

3.4.2. Module graph

3.4.3. Adding modules to the graph

3.4.4. Adding edges to the graph

3.4.5. Accessibility

3.5. Summary

4. Building modules from source to JAR

4.1. Organizing the project in a directory structure

4.1.1. New convention?

4.1.2. Established default

4.1.3. The place for module declarations

4.2. Compiling a single module

4.2.1. Compiling modular code

4.2.2. Modular or non-modular?

4.3. Compiling multiple modules

4.3.1. The naive approach

4.3.2. The module source path

4.3.3. The asterisk as a token for the module name

4.3.4. Multiple module source path entries

4.3.5. Setting the initial module

4.3.6. Is it worth it?

4.4. Compiler options

4.5. Packaging a modular JAR

4.5.1. Quick recap of jar

4.5.2. Analyzing a JAR

4.5.3. Defining an entry point

4.5.4. Archiver options

4.6. Summary

5. Running modular applications

5.1. Launching the JVM with modules

5.1.1. Specifying the main class

5.1.2. Passing parameters

5.2. Accessing resources

5.3. Debugging modular applications

5.3.1. Analyzing individual modules

5.3.2. Validating sets of modules

5.3.3. Validating a module graph

5.3.4. Listing observable modules and dependencies

5.3.5. Excluding modules during resolution

5.3.6. Logging

5.4. Java Virtual Machine options

5.5. Summary

Part 2: Adapting Real World Applications

6. Compatibility challenges when moving to Java 9

6.1. Working with Java EE modules

6.1.1. Why are the Java EE modules special?

6.1.2. Resolving Java EE modules

6.1.3. Upgrading Java EE modules

6.2. Casting to URLClassLoader

6.2.1. Application class loaders, then and now

6.2.2. Getting by without URLClassLoader

6.2.3. Finding troublesome casts

6.3. Runtime image directory layout

6.4. Selecting, replacing, and extending the platform

6.4.1. Compact profiles

6.4.2. Extension mechanism

6.4.3. Endorsed standards override mechanism

6.4.4. Boot class path

6.4.5. Compiling for Java 5

6.4.6. JRE version selection

6.5. The little things that make big things fail

6.5.1. New Version Strings

6.5.2. Tool exodus

6.5.3. The littlest things

6.6. Summary

7. Recurring challenges when running on Java 9

7.1. Encapsulation of internal APIs

7.1.1. Internal APIs under the microscope

7.1.2. Analyzing dependencies with JDeps

7.1.3. Compiling against internal APIs

7.1.4. Executing against internal APIs

7.1.5. Compiler and JVM options for accessing internal APIs

7.2. Mending split packages

7.2.1. What is the problem with split packages?

7.2.2. The effects of split packages

7.2.3. Many ways to handle split packages

7.2.4. Patching modules

7.2.5. Finding split packages with JDeps

7.2.6. A note on dependency version conflicts

7.3. Summary

8. Incremental modularization of existing projects

8.1. Why incremental modularization is even an option

8.1.1. If every JAR needed to be modular…​

8.1.2. Mixing and matching plain JARs with modules

8.1.3. Technical underpinnings of incremental modularization

8.2. The unnamed module—​a.k.a the class path

8.2.1. The chaos of the class path—​captured by the unnamed module

8.2.2. Module resolution for the unnamed module

8.2.3. Depending on the unnamed module

8.3. Automatic modules—​plain JARs on the module path

8.3.1. Automatic module names

8.3.2. Module resolution for automatic modules

8.3.3. All-in on automatic modules?

8.3.4. Depending on automatic modules

8.4. Summary

9. Migration and modularization strategies

9.1. Migration strategies

9.1.1. Preparatory updates

9.1.2. Estimating the effort

9.1.3. Continuously build on Java 9

9.1.4. Thoughts on command line options

9.2. Modularization Strategies

9.2.1. Bottom-up modularization

9.2.2. Top-down modularization

9.2.3. Inside-out modularization

9.2.4. Applying these strategies inside your project

9.3. Making JARs modular

9.3.1. Open modules as an intermediate step

9.3.2. Generating module declarations with JDeps

9.3.3. Hacking third-party JARs

9.3.4. Publishing modular JARs for Java 8 and older

9.4. Summary

Part 3: Advanced Module System Features

10. Decoupling modules with services

10.1. Services in the Java Platform Module System

10.1.1. Using, providing, and consuming services

10.1.2. Service resolution

10.2. Designing services well

10.2.1. Types of services

10.2.2. Factories as services

10.2.3. Isolating consumers from global state

10.2.4. Organizing services, consumers, and providers into modules

10.2.5. Services in Java 6, Java 9, and beyond

10.3. The ServiceLoader API

10.3.1. Loading and accessing services

10.3.2. Idiosyncrasies of the service loader

10.4. Summary

11. Refining dependencies and APIs

11.1. Implied readability

11.1.1. Exposing dependencies

11.1.2. The transitive modifier

11.1.3. When to use implied readability

11.1.4. When to rely on implied readability

11.1.5. Refactoring modules with implied readability

11.2. Optional dependencies

11.2.1. The conundrum of unrequired dependencies

11.2.2. The static modifier

11.2.3. How module resolution handles optional dependencies

11.2.4. Coding against optional dependencies

11.3. Qualified Exports

11.3.1. Exposing internal APIs

11.3.2. Exporting packages to modules

11.3.3. When to use qualified exports

11.3.4. Exporting packages on the command line

11.4. Summary

12. Reflection in a modular world

13. Runtime images with jLinq

14. Troubleshooting


Appendix A: Class Path Recap

Appendix B: High-level introduction to the reflection API

B.1. Fundamental types and methods

B.2. Breaking into APIs with setAccessible

B.3. Summary

Appendix C: Observing the JVM with unified logging

C.1. What is unified logging?

C.2. Defining which messages should be shown

C.3. Defining where messages should go

C.4. Defining what messages should say

C.5. Putting the pieces together

C.6. Summary

Appendix D: Analyzing a project’s dependencies with JDeps

D.1. Getting to know JDeps

D.2. Including dependencies

D.3. Configuring output

D.4. Drilling deeper

D.5. JDeps and modules

D.6. Summary

About the Technology

Experienced developers understand the benefits of strong encapsulation; when two components can interact only through the interfaces you define, you reduce the chance that you'll introduce hidden dependencies and unwanted tight coupling into your code. The Java Module System, aka "Project Jigsaw", gives Java developers the ability to define and enforce modularity without an outside framework. A modular application allows a team to more-safely approach large projects and produce cleaner code with superior run-time stability. The benefits don't just stop there however, the shift to modules also promises reliable configuration - allowing individual modules to declare their dependencies on other modules, along with allowing both the developers and JVM the same vision of the running application; changing how you develop with Java for the better!

What's inside

  • The anatomy of a modular Java app
  • Building modules from source to JAR
  • Compiling both single and multiple modules
  • Debugging your finished applications

About the reader

If you are a developer who has experience working with Java, then this book is perfect for you.

About the author

Nicolai Parlog is a thirty year old boy, as the narrator would put it, who has found his passion in software development. He constantly reads, thinks, and writes about it, and codes for a living as well as for fun. He is the editor of SitePoint's Java channel, blogs about software development on, and is a long-tail contributor to several open source projects. The best way to get in touch is via Twitter.

Manning Early Access Program (MEAP) Read chapters as they are written, get the finished eBook as soon as it’s ready, and receive the pBook long before it's in bookstores.
MEAP combo $44.99 pBook + eBook + liveBook
MEAP eBook $35.99 pdf + ePub + kindle + liveBook

FREE domestic shipping on three or more pBooks