0%

Book Description

The Java Module System is your in-depth guide to creating and using Java modules. With detailed examples and easy-to-understand diagrams, you’ll learn the anatomy of a modular Java application. Along the way, you’ll master best practices for designing with modules, debugging your modular app, and deploying to production.

Table of Contents

  1. Titlepage
  2. Copyright
  3. brief contents
  4. contents
  5. Dedication
  6. foreword
  7. preface
  8. acknowledgments
  9. about this book
    1. Who should read this book
    2. How this book is organized: a roadmap
      1. Parts and chapters
      2. Pick your own path
      3. Watch out for these
    3. About the code
      1. About the Java version
      2. Code formatting conventions
      3. Module name conventions
      4. Placeholders in code snippets
      5. Commands and their output
    4. liveBook discussion forum
  10. about the author
  11. about the cover illustration
  12. Part 1: Hello, modules
    1. Chapter 1: First piece of the puzzle
      1. 1.1 What is modularity all about?
        1. 1.1.1 Visualizing software as graphs
        2. 1.1.2 The impact of design principles
        3. 1.1.3 What modularity is all about
      2. 1.2 Module erasure before Java 9
      3. 1.3 Complications before Java 9
        1. 1.3.1 Unexpressed dependencies between JARs
        2. 1.3.2 Shadowing classes with the same name
        3. 1.3.3 Conflicts between different versions of the same project
        4. 1.3.4 Complex class loading
        5. 1.3.5 Weak encapsulation across JARs
        6. 1.3.6 Security checks have to be handcrafted
        7. 1.3.7 Poor startup performance
        8. 1.3.8 Rigid Java runtime
      4. 1.4 Bird’s-eye view of the module system
        1. 1.4.1 Everything is a module
        2. 1.4.2 Your first module
        3. 1.4.3 The module system in action
        4. 1.4.4 Your non-modular project will be fine—mostly
      5. 1.5 Goals of the module system
        1. 1.5.1 Reliable configuration: Leaving no JAR behind
        2. 1.5.2 Strong encapsulation: Making module-internal code inaccessible
        3. 1.5.3 Automated security and improved maintainability
        4. 1.5.4 Improved startup performance
        5. 1.5.5 Scalable Java platform
        6. 1.5.6 Non-goals
      6. 1.6 Skills, old and new
        1. 1.6.1 What you’ll learn
        2. 1.6.2 What you should know
      7. Summary
    2. Chapter 2: Anatomy of a modular application
      1. 2.1 Introducing ServiceMonitor
      2. 2.2 Modularizing ServiceMonitor
      3. 2.3 Cutting ServiceMonitor into modules
      4. 2.4 Laying out files in a directory structure
      5. 2.5 Declaring and describing modules
        1. 2.5.1 Declaring dependencies on other modules
        2. 2.5.2 Defining a module’s public API
        3. 2.5.3 Visualizing ServiceMonitor with the module graph
      6. 2.6 Compiling and packaging modules
      7. 2.7 Running ServiceMonitor
      8. 2.8 Extending a modular code base
      9. 2.9 Post mortem: Effects of the module system
        1. 2.9.1 What the module system does for you
        2. 2.9.2 What else the module system can do for you
        3. 2.9.3 Allowing optional dependencies
      10. Summary
    3. Chapter 3: Defining modules and their properties
      1. 3.1 Modules: The building blocks of modular applications
        1. 3.1.1 Java modules (JMODs), shipped with the JDK
        2. 3.1.2 Modular JARs: Home-grown modules
        3. 3.1.3 Module declarations: Defining a module’s properties
        4. 3.1.4 The many types of modules
      2. 3.2 Readability: Connecting the pieces
        1. 3.2.1 Achieving reliable configuration
        2. 3.2.2 Experimenting with unreliable configurations
      3. 3.3 Accessibility: Defining public APIs
        1. 3.3.1 Achieving strong encapsulation
        2. 3.3.2 Encapsulating transitive dependencies
        3. 3.3.3 Encapsulation skirmishes
      4. 3.4 The module path: Letting Java know about modules
        1. 3.4.1 Module resolution: Analyzing and verifying an application’s structure
        2. 3.4.2 Module graph: Representation of an application’s structure
        3. 3.4.3 Adding modules to the graph
        4. 3.4.4 Adding edges to the graph
        5. 3.4.5 Accessibility is an ongoing effort
      5. Summary
    4. Chapter 4: Building modules from source to JAR
      1. 4.1 Organizing your project in a directory structure
        1. 4.1.1 New proposal—new convention?
        2. 4.1.2 Established directory structure
        3. 4.1.3 The place for module declarations
      2. 4.2 Compiling a single module
        1. 4.2.1 Compiling modular code
        2. 4.2.2 Modular or non-modular?
      3. 4.3 Compiling multiple modules
        1. 4.3.1 The naive approach
        2. 4.3.2 The module source path: Informing the compiler about the project structure
        3. 4.3.3 The asterisk as a token for the module name
        4. 4.3.4 Multiple module source path entries
        5. 4.3.5 Setting the initial module
        6. 4.3.6 Is it worth it?
      4. 4.4 Compiler options
      5. 4.5 Packaging a modular JAR
        1. 4.5.1 Quick recap of jar
        2. 4.5.2 Analyzing a JAR
        3. 4.5.3 Defining an entry point
        4. 4.5.4 Archiver options
      6. Summary
    5. Chapter 5: Running and debugging modular applications
      1. 5.1 Launching the JVM with modules
        1. 5.1.1 Specifying the main class
        2. 5.1.2 If the initial module and main module aren’t the same
        3. 5.1.3 Passing parameters to the application
      2. 5.2 Loading resources from modules
        1. 5.2.1 Resource loading before Java 9
        2. 5.2.2 Resource loading on Java 9 and later
        3. 5.2.3 Loading package resources across module boundaries
      3. 5.3 Debugging modules and modular applications
        1. 5.3.1 Analyzing individual modules
        2. 5.3.2 Validating sets of modules
        3. 5.3.3 Validating a module graph
        4. 5.3.4 Listing observable modules and dependencies
        5. 5.3.5 Excluding modules during resolution
        6. 5.3.6 Observing the module system with log messages
      4. 5.4 Java Virtual Machine options
      5. Summary
  13. Part 2: Adapting real-world projects
    1. Chapter 6: Compatibility challenges when moving to Java 9 or later
      1. 6.1 Working with JEE modules
        1. 6.1.1 Why are the JEE modules special?
        2. 6.1.2 Manually resolving JEE modules
        3. 6.1.3 Dropping in third-party implementations of JEE modules
      2. 6.2 Casting to URLClassLoader
        1. 6.2.1 Application class loaders, then and now
        2. 6.2.2 Getting by without URLClassLoader
        3. 6.2.3 Finding troublesome casts
      3. 6.3 Updated run-time image directory layout
      4. 6.4 Selecting, replacing, and extending the platform
        1. 6.4.1 No more compact profiles
        2. 6.4.2 Extension mechanism removed
        3. 6.4.3 Endorsed standards override mechanism removed
        4. 6.4.4 Some boot class path options removed
        5. 6.4.5 No compilation for Java 5
        6. 6.4.6 JRE version selection removed
      5. 6.5 Little things that make big things fail
        1. 6.5.1 New version strings
        2. 6.5.2 Tool exodus
        3. 6.5.3 The littlest things
        4. 6.5.4 New deprecations in Java 9, 10, and 11
      6. Summary
    2. Chapter 7: Recurring challenges when running on Java 9 or later
      1. 7.1 Encapsulation of internal APIs
        1. 7.1.1 Internal APIs under the microscope
        2. 7.1.2 Analyzing dependencies with JDeps
        3. 7.1.3 Compiling against internal APIs
        4. 7.1.4 Executing against internal APIs
        5. 7.1.5 Compiler and JVM options for accessing internal APIs
      2. 7.2 Mending split packages
        1. 7.2.1 What’s the problem with split packages?
        2. 7.2.2 The effects of split packages
        3. 7.2.3 Many ways to handle split packages
        4. 7.2.4 Patching modules: Last resort for handling split packages
        5. 7.2.5 Finding split packages with JDeps
        6. 7.2.6 A note on dependency version conflicts
      3. Summary
    3. Chapter 8: Incremental modularization of existing projects
      1. 8.1 Why incremental modularization is an option
        1. 8.1.1 If every JAR had to be modular …
        2. 8.1.2 Mixing and matching plain JARs with modules
        3. 8.1.3 Technical underpinnings of incremental modularization
      2. 8.2 The unnamed module, aka the class path
        1. 8.2.1 The chaos of the class path, captured by the unnamed module
        2. 8.2.2 Module resolution for the unnamed module
        3. 8.2.3 Depending on the unnamed module
      3. 8.3 Automatic modules: Plain JARs on the module path
        1. 8.3.1 Automatic module names: Small detail, big impact
        2. 8.3.2 Module resolution for automatic modules
        3. 8.3.3 All in on automatic modules?
        4. 8.3.4 Depending on automatic modules
      4. Summary
    4. Chapter 9: Migration and modularization strategies
      1. 9.1 Migration strategies
        1. 9.1.1 Preparatory updates
        2. 9.1.2 Estimating the effort
        3. 9.1.3 Continuously build on Java 9+
        4. 9.1.4 Thoughts on command-line options
      2. 9.2 Modularization strategies
        1. 9.2.1 Bottom-up modularization: If all project dependencies are modular
        2. 9.2.2 Top-down modularization: If an application can’t wait for its dependencies
        3. 9.2.3 Inside-out modularization: If a project is in the middle of the stack
        4. 9.2.4 Applying these strategies within a project
      3. 9.3 Making JARs modular
        1. 9.3.1 Open modules as an intermediate step
        2. 9.3.2 Generating module declarations with JDeps
        3. 9.3.3 Hacking third-party JARs
        4. 9.3.4 Publishing modular JARs for Java 8 and older
      4. Summary
  14. Part 3: Advanced module system features
    1. Chapter 10: Using services to decouple modules
      1. 10.1 Exploring the need for services
      2. 10.2 Services in the Java Platform Module System
        1. 10.2.1 Using, providing, and consuming services
        2. 10.2.2 Module resolution for services
      3. 10.3 Designing services well
        1. 10.3.1 Types that can be services
        2. 10.3.2 Using factories as services
        3. 10.3.3 Isolating consumers from global state
        4. 10.3.4 Organizing services, consumers, and providers into modules
        5. 10.3.5 Using services to break cyclic dependencies
        6. 10.3.6 Declaring services across different Java versions
      4. 10.4 Accessing services with the ServiceLoader API
        1. 10.4.1 Loading and accessing services
        2. 10.4.2 Idiosyncrasies of loading services
      5. Summary
    2. Chapter 11: Refining dependencies and APIs
      1. 11.1 Implied readability: Passing on dependencies
        1. 11.1.1 Exposing a module’s dependencies
        2. 11.1.2 The transitive modifier: Implying readability on a dependency
        3. 11.1.3 When to use implied readability
        4. 11.1.4 When to rely on implied readability
        5. 11.1.5 Refactoring modules with implied readability
        6. 11.1.6 Refactoring modules by merging them
      2. 11.2 Optional dependencies
        1. 11.2.1 The conundrum of reliable configuration
        2. 11.2.2 The static modifier: Marking dependencies as optional
        3. 11.2.3 Module resolution of optional dependencies
        4. 11.2.4 Coding against optional dependencies
      3. 11.3 Qualified exports: Limiting accessibility to specific modules
        1. 11.3.1 Exposing internal APIs
        2. 11.3.2 Exporting packages to modules
        3. 11.3.3 When to use qualified exports
        4. 11.3.4 Exporting packages on the command line
      4. Summary
    3. Chapter 12: Reflection in a modular world
      1. 12.1 Why exports directives aren’t a good fit for reflection
        1. 12.1.1 Breaking into non-modular code
        2. 12.1.2 Forcing the publication of internal types
        3. 12.1.3 Qualified exports create coupling to specific modules
        4. 12.1.4 No support for deep reflection
      2. 12.2 Open packages and modules: Designed for the reflection use case
        1. 12.2.1 Opening packages to run-time access
        2. 12.2.2 Opening packages for specific modules
        3. 12.2.3 Exporting vs. opening packages
        4. 12.2.4 Opening modules: Reflection closeout
      3. 12.3 Reflecting over modules
        1. 12.3.1 Updating reflecting code for modules (or not)
        2. 12.3.2 Using variable handles instead of reflection
        3. 12.3.3 Analyzing module properties with reflection
        4. 12.3.4 Modifying module properties with reflection
        5. 12.3.5 Forwarding open packages
      4. 12.4 Dynamically creating module graphs with layers
        1. 12.4.1 What are layers?
        2. 12.4.2 Analyzing layers
        3. 12.4.3 Creating module layers
      5. Summary
    4. Chapter 13: Module versions: What’s possible and what’s not
      1. 13.1 The lack of version support in the JPMS
        1. 13.1.1 No support for multiple versions
        2. 13.1.2 No support for version selection
        3. 13.1.3 What the future may bring
      2. 13.2 Recording version information
        1. 13.2.1 Recording versions while building modules
        2. 13.2.2 Accessing module versions
      3. 13.3 Running multiple versions of a module in separate layers
        1. 13.3.1 Why you need a starter to spin up additional layers
        2. 13.3.2 Spinning up layers for your application, Apache Twill, and Cassandra Java Driver
      4. Summary
    5. Chapter 14: Customizing runtime images with jlink
      1. 14.1 Creating custom runtime images
        1. 14.1.1 Getting started with jlink
        2. 14.1.2 Image content and structure
        3. 14.1.3 Including services in runtime images
        4. 14.1.4 Right-sizing images with jlink and jdeps
      2. 14.2 Creating self-contained application images
        1. 14.2.1 Including application modules in images
        2. 14.2.2 Generating a native launcher for your application
        3. 14.2.3 Security, performance, and stability
      3. 14.3 Generating images across operating systems
      4. 14.4 Using jlink plugins to optimize images
        1. 14.4.1 Plugins for jlink
        2. 14.4.2 Reducing image size
        3. 14.4.3 Improving run-time performance
      5. 14.5 Options for jlink
      6. Summary
    6. Chapter 15: Putting the pieces together
      1. 15.1 Adding bells and whistles to ServiceMonitor
        1. 15.1.1 Diversified dependencies
        2. 15.1.2 Reduced visibility
        3. 15.1.3 Decoupled with services
        4. 15.1.4 Loads code at run time with layers
        5. 15.1.5 Handles dependencies on plain JARs
      2. 15.2 Tips for a modular application
        1. 15.2.1 Modular or not?
        2. 15.2.2 The ideal module
        3. 15.2.3 Take care of your module declarations
        4. 15.2.4 Breaking code by editing module declarations
      3. 15.3 The technology landscape
        1. 15.3.1 Maven, Gradle, and other build tools
        2. 15.3.2 OSGi
        3. 15.3.3 Microservices
      4. 15.4 Thoughts on a modular ecosystem
      5. Summary
  15. appendix A: Class-path recap
    1. Using the class path to load application JARs
    2. The class path since Java 9
  16. appendix B: High-level introduction to the reflection API
    1. Fundamental types and methods
    2. Breaking into APIs with setAccessible
    3. Annotations mark code for reflection
  17. appendix C: Observing the JVM with unified logging
    1. What is unified logging?
    2. Defining which messages should be shown
    3. Defining where messages should go
    4. Defining what messages should say
    5. Configuring the entire logging pipeline
  18. appendix D: Analyzing a project’s dependencies with JDeps
    1. Getting to know JDeps
    2. Including dependencies in the analysis
    3. Configuring JDeps’ output
    4. Drilling deeper into your project’s dependencies
    5. JDeps understands modules
  19. appendix E: Targeting multiple Java versions with multi-release JARs
    1. Creating a multi-release JAR
    2. Internal workings of MR-JARs
    3. Usage recommendations
      1. Organizing the source code
      2. Organizing the bytecode
      3. When to use MR-JARs
  20. Index
  21. List of Figures
  22. List of Tables
  23. List of Listings
3.139.239.41