Skip to content

Latest commit

 

History

History

java-modules

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

java-modules

An example Gradle project that uses the Java Platform Module System (JPMS).

Overview

There are a few things to highlight about this project vs. a non-JPMS project:

  • The module-info.java files
  • Configuring the Gradle Application Plugin to work with modules with mainModule.set("dgroomes.runner")
  • When you build a distribution with ./gradlew install, the shell/start script that is generated (build/install/runner/bin/runner) by the Gradle Application Plugin defines a MODULE_PATH variable in addition to the CLASSPATH variable that normally exists.

Tip: disassemble a module-info.class file to view its content using javap. For example: javap --module-path . module-info.class. I've found this to be helpful while learning about JPMS.

Instructions

Follow these instructions to build and run the demo program:

  1. Pre-requisite: Java 21
  2. Build and run the program:
    • ./gradlew run
    • It should print something that looks like the following.
    • > Task :runner:run
      [main] INFO dgroomes.java_modules.runner.Main - You say: hello!
      [main] INFO dgroomes.java_modules.runner.Main - You heard: hello!, hello!, hello! ...
      [main] INFO dgroomes.java_modules.runner.Main - You say: { "message": "hello from JSON!" }
      [main] INFO dgroomes.java_modules.runner.Main - You heard: hello from JSON!, hello from JSON!, hello from JSON! ...
      

Wish List

General clean-ups, TODOs and things I wish to implement for this project:

  • DONE Incorporate Jackson as a dependency to this project because apparently Jackson has some integrations with JPMS. It would be useful to show how to incorporate a Gradle dependency that publishes module info. How does that work?
  • DONE (added slf4j 1.7.x. The 1.8.x and 2.x branches are modularized but are beta) Incorporate a non-modularized dependency to this project. This is an almost universal use-case because so many libraries are not modularized. This requires declaring an "automatic module".
  • OBSOLETE (slf4j 2.x is general availability for a while now and is modularized) Patch the slf4j dependency to be modular (will this let me jlink it without needing jdeps?). For reference about how to do this, see:
  • DONE Gradle's module support was promoted in Gradle 7.x. Read the release notes. In particular, the inferModulePath call is no longer required. Delete it.
  • DONE Showcase JPMS's strength when it comes to strongly encapsulating implementation details. For example, can I have classes that are used as implementation details in a package (or maybe sub-package?) and then export just a particular "ordained" package?

Reference