Home Page Icon
Home Page
Table of Contents for
Titlepage
Close
Titlepage
by Nicolai Parlog
The Java Module System
Titlepage
Copyright
brief contents
contents
Dedication
foreword
preface
acknowledgments
about this book
Who should read this book
How this book is organized: a roadmap
Parts and chapters
Pick your own path
Watch out for these
About the code
About the Java version
Code formatting conventions
Module name conventions
Placeholders in code snippets
Commands and their output
liveBook discussion forum
about the author
about the cover illustration
Part 1: Hello, modules
Chapter 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 between JARs
1.3.2 Shadowing classes with the same name
1.3.3 Conflicts between different versions of the same project
1.3.4 Complex class loading
1.3.5 Weak encapsulation across JARs
1.3.6 Security checks have to be handcrafted
1.3.7 Poor startup performance
1.3.8 Rigid Java runtime
1.4 Bird’s-eye view of the module system
1.4.1 Everything is a module
1.4.2 Your first module
1.4.3 The module system in action
1.4.4 Your non-modular project will be fine—mostly
1.5 Goals of the module system
1.5.1 Reliable configuration: Leaving no JAR behind
1.5.2 Strong encapsulation: Making module-internal code inaccessible
1.5.3 Automated security and improved maintainability
1.5.4 Improved startup performance
1.5.5 Scalable Java platform
1.5.6 Non-goals
1.6 Skills, old and new
1.6.1 What you’ll learn
1.6.2 What you should know
Summary
Chapter 2: Anatomy of a modular application
2.1 Introducing ServiceMonitor
2.2 Modularizing ServiceMonitor
2.3 Cutting ServiceMonitor into modules
2.4 Laying out files in a directory structure
2.5 Declaring and describing modules
2.5.1 Declaring dependencies on other modules
2.5.2 Defining a module’s public API
2.5.3 Visualizing ServiceMonitor with the module graph
2.6 Compiling and packaging modules
2.7 Running ServiceMonitor
2.8 Extending a modular code base
2.9 Post mortem: Effects of the module system
2.9.1 What the module system does for you
2.9.2 What else the module system can do for you
2.9.3 Allowing optional dependencies
Summary
Chapter 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 The many types of modules
3.2 Readability: Connecting the pieces
3.2.1 Achieving reliable configuration
3.2.2 Experimenting with 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: Analyzing and verifying an application’s structure
3.4.2 Module graph: Representation of an application’s structure
3.4.3 Adding modules to the graph
3.4.4 Adding edges to the graph
3.4.5 Accessibility is an ongoing effort
Summary
Chapter 4: Building modules from source to JAR
4.1 Organizing your project in a directory structure
4.1.1 New proposal—new convention?
4.1.2 Established directory structure
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: Informing the compiler about the project structure
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
Summary
Chapter 5: Running and debugging modular applications
5.1 Launching the JVM with modules
5.1.1 Specifying the main class
5.1.2 If the initial module and main module aren’t the same
5.1.3 Passing parameters to the application
5.2 Loading resources from modules
5.2.1 Resource loading before Java 9
5.2.2 Resource loading on Java 9 and later
5.2.3 Loading package resources across module boundaries
5.3 Debugging modules and 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 Observing the module system with log messages
5.4 Java Virtual Machine options
Summary
Part 2: Adapting real-world projects
Chapter 6: Compatibility challenges when moving to Java 9 or later
6.1 Working with JEE modules
6.1.1 Why are the JEE modules special?
6.1.2 Manually resolving JEE modules
6.1.3 Dropping in third-party implementations of JEE 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 Updated run-time image directory layout
6.4 Selecting, replacing, and extending the platform
6.4.1 No more compact profiles
6.4.2 Extension mechanism removed
6.4.3 Endorsed standards override mechanism removed
6.4.4 Some boot class path options removed
6.4.5 No compilation for Java 5
6.4.6 JRE version selection removed
6.5 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.5.4 New deprecations in Java 9, 10, and 11
Summary
Chapter 7: Recurring challenges when running on Java 9 or later
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’s 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: Last resort for handling split packages
7.2.5 Finding split packages with JDeps
7.2.6 A note on dependency version conflicts
Summary
Chapter 8: Incremental modularization of existing projects
8.1 Why incremental modularization is an option
8.1.1 If every JAR had 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, aka 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: Small detail, big impact
8.3.2 Module resolution for automatic modules
8.3.3 All in on automatic modules?
8.3.4 Depending on automatic modules
Summary
Chapter 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: If all project dependencies are modular
9.2.2 Top-down modularization: If an application can’t wait for its dependencies
9.2.3 Inside-out modularization: If a project is in the middle of the stack
9.2.4 Applying these strategies within a 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
Summary
Part 3: Advanced module system features
Chapter 10: Using services to decouple modules
10.1 Exploring the need for services
10.2 Services in the Java Platform Module System
10.2.1 Using, providing, and consuming services
10.2.2 Module resolution for services
10.3 Designing services well
10.3.1 Types that can be services
10.3.2 Using factories as services
10.3.3 Isolating consumers from global state
10.3.4 Organizing services, consumers, and providers into modules
10.3.5 Using services to break cyclic dependencies
10.3.6 Declaring services across different Java versions
10.4 Accessing services with the ServiceLoader API
10.4.1 Loading and accessing services
10.4.2 Idiosyncrasies of loading services
Summary
Chapter 11: Refining dependencies and APIs
11.1 Implied readability: Passing on dependencies
11.1.1 Exposing a module’s dependencies
11.1.2 The transitive modifier: Implying readability on a dependency
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.1.6 Refactoring modules by merging them
11.2 Optional dependencies
11.2.1 The conundrum of reliable configuration
11.2.2 The static modifier: Marking dependencies as optional
11.2.3 Module resolution of optional dependencies
11.2.4 Coding against optional dependencies
11.3 Qualified exports: Limiting accessibility to specific modules
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
Summary
Chapter 12: Reflection in a modular world
12.1 Why exports directives aren’t a good fit for reflection
12.1.1 Breaking into non-modular code
12.1.2 Forcing the publication of internal types
12.1.3 Qualified exports create coupling to specific modules
12.1.4 No support for deep reflection
12.2 Open packages and modules: Designed for the reflection use case
12.2.1 Opening packages to run-time access
12.2.2 Opening packages for specific modules
12.2.3 Exporting vs. opening packages
12.2.4 Opening modules: Reflection closeout
12.3 Reflecting over modules
12.3.1 Updating reflecting code for modules (or not)
12.3.2 Using variable handles instead of reflection
12.3.3 Analyzing module properties with reflection
12.3.4 Modifying module properties with reflection
12.3.5 Forwarding open packages
12.4 Dynamically creating module graphs with layers
12.4.1 What are layers?
12.4.2 Analyzing layers
12.4.3 Creating module layers
Summary
Chapter 13: Module versions: What’s possible and what’s not
13.1 The lack of version support in the JPMS
13.1.1 No support for multiple versions
13.1.2 No support for version selection
13.1.3 What the future may bring
13.2 Recording version information
13.2.1 Recording versions while building modules
13.2.2 Accessing module versions
13.3 Running multiple versions of a module in separate layers
13.3.1 Why you need a starter to spin up additional layers
13.3.2 Spinning up layers for your application, Apache Twill, and Cassandra Java Driver
Summary
Chapter 14: Customizing runtime images with jlink
14.1 Creating custom runtime images
14.1.1 Getting started with jlink
14.1.2 Image content and structure
14.1.3 Including services in runtime images
14.1.4 Right-sizing images with jlink and jdeps
14.2 Creating self-contained application images
14.2.1 Including application modules in images
14.2.2 Generating a native launcher for your application
14.2.3 Security, performance, and stability
14.3 Generating images across operating systems
14.4 Using jlink plugins to optimize images
14.4.1 Plugins for jlink
14.4.2 Reducing image size
14.4.3 Improving run-time performance
14.5 Options for jlink
Summary
Chapter 15: Putting the pieces together
15.1 Adding bells and whistles to ServiceMonitor
15.1.1 Diversified dependencies
15.1.2 Reduced visibility
15.1.3 Decoupled with services
15.1.4 Loads code at run time with layers
15.1.5 Handles dependencies on plain JARs
15.2 Tips for a modular application
15.2.1 Modular or not?
15.2.2 The ideal module
15.2.3 Take care of your module declarations
15.2.4 Breaking code by editing module declarations
15.3 The technology landscape
15.3.1 Maven, Gradle, and other build tools
15.3.2 OSGi
15.3.3 Microservices
15.4 Thoughts on a modular ecosystem
Summary
appendix A: Class-path recap
Using the class path to load application JARs
The class path since Java 9
appendix B: High-level introduction to the reflection API
Fundamental types and methods
Breaking into APIs with setAccessible
Annotations mark code for reflection
appendix C: Observing the JVM with unified logging
What is unified logging?
Defining which messages should be shown
Defining where messages should go
Defining what messages should say
Configuring the entire logging pipeline
appendix D: Analyzing a project’s dependencies with JDeps
Getting to know JDeps
Including dependencies in the analysis
Configuring JDeps’ output
Drilling deeper into your project’s dependencies
JDeps understands modules
appendix E: Targeting multiple Java versions with multi-release JARs
Creating a multi-release JAR
Internal workings of MR-JARs
Usage recommendations
Organizing the source code
Organizing the bytecode
When to use MR-JARs
Index
List of Figures
List of Tables
List of Listings
Search in book...
Toggle Font Controls
Playlists
Add To
Create new playlist
Name your new playlist
Playlist description (optional)
Cancel
Create playlist
Sign In
Email address
Password
Forgot Password?
Create account
Login
or
Continue with Facebook
Continue with Google
Sign Up
Full Name
Email address
Confirm Email Address
Password
Login
Create account
or
Continue with Facebook
Continue with Google
Prev
Previous Chapter
Cover
Next
Next Chapter
Copyright
The Java Module System
Nicolai Parlog
Foreword by Kevlin Henney
Manning
Shelter Island
Add Highlight
No Comment
..................Content has been hidden....................
You can't read the all page of ebook, please click
here
login for view all page.
Day Mode
Cloud Mode
Night Mode
Reset