Home » Core Java » Java 9 Jigsaw Project Tutorial

About JJ

Jean-Jay Vester graduated from the Cape Peninsula University of Technology, Cape Town, in 2001 and has spent most of his career, since 2004, developing Java backend based systems for small to large sized companies both sides of the equator. He has an abundance of experience and knowledge in many varied Java frameworks and has also acquired some systems knowledge along the way. Recently he has started developing his JavaScript skill set specifically targeting Angularjs and also bridged that skill to the backend with Nodejs.

Java 9 Jigsaw Project Tutorial

In this tutorial we will get a brief introduction to the Java 9 Jigsaw feature by a way of a simple project. This project will demonstrate some of the features of the new module system (Jigsaw) being introduced in Java 9 and how to go about structuring projects in a way that will leverage the features and adhere to the requirements of Jigsaw.

We will cover the mechanics of how the module system will work for new projects and how existing projects and libraries can be retro-fitted (if needed) to leverage the new module system.

We will also demonstrate structuring, building and packaging our simple project both from command line and via the popular build and dependency management tool, Maven in order to leverage the new module system, Jigsaw.

1. Introduction

Project Jigsaw is a modularization of the JDK and introduction of a module system for Java bringing about stronger encapsulation, smaller package footprint and reliable configuration to Java applications.

2. Technologies used

The example code in this article was built and run using:

  • Java 9
  • Maven 3.3.9
  • Eclipse Oxygen (4.7.0)
  • Ubuntu 16.04 (Windows, Mac or Linux will do fine)

3. Setup

To follow along in this tutorial we only need Java 9 and maven 3.3.9 installed with both bin folders available on the path. Also your JAVA_HOME variable needs to be set to the Java 9 install. To verify:

  • JAVA_HOME: issue echo $JAVA_HOME and you should see the path to your Java 9 install shown on screen
  • jdeps: issue jdeps --version
  • jlink: issue jlink --version
  • jar: issue jar --version
  • javac: issue javac --version
  • java: issue java --version
  • mvn: issue mvn --version

Issuing these commands should give output very similar to below:

Output from Setup commands

export JAVA_HOME=/home/jean-jay/runtimes/jdk-9
echo $JAVA_HOME
/home/jean-jay/runtimes/jdk-9
jdeps --version
9
jlink --version
9
jar --version
jar 9
javac --version
javac 9
java --version
java 9
Java(TM) SE Runtime Environment (build 9+180)
Java HotSpot(TM) 64-Bit Server VM (build 9+180, mixed mode)
mvn --version
Apache Maven 3.3.9
Maven home: /usr/share/maven
Java version: 9, vendor: Oracle Corporation
Java home: /home/jean-jay/runtimes/jdk-9
Default locale: en_ZA, platform encoding: UTF-8
OS name: "linux", version: "4.10.0-33-generic", arch: "amd64", family: "unix"

Add a toolchains.xml file in your .m2 folder for maven. (replace the jdkHome locations with your local path to Java 9 install)

ToolChains configuration for Maven

<toolchains>
  <toolchain>
    <type>jdk</type>
    <provides>
      <version>1.9</version>
      <vendor>oracle</vendor>
    </provides>
    <configuration>
      <jdkHome>/home/jean-jay/runtimes/jdk-9</jdkHome>
    </configuration>
  </toolchain>
  <toolchain>
    <type>jdk</type>
    <provides>
      <version>1.8</version>
      <vendor>oracle</vendor>
    </provides>
    <configuration>
      <jdkHome>/home/jean-jay/runtimes/jdk1.8.0_101</jdkHome>
    </configuration>
  </toolchain>
</toolchains>

4. Goals of Jigsaw

The goals of Jigsaw are:

  • Provide stronger encapsulation of components that extend beyond what the JDK currently provides.
  • Reliable configuration of modules in an application.
  • Reduce the footprint of the run-time image for an application to what is only needed.

4.1 Stronger Encapsulation

As a recap the JDK provides access modifiers that help us promote encapsulation and information / behavior hiding between classes and members of classes on the class-path. These are (in order of most visible to least visible):

  • public
  • protected
  • package private
  • private

Now this is quite ample from a jar file’s perspective (ie within a jar) but the moment we go beyond the jar (i.e. collaboration between jars on the class-path) we encounter a limitation. What was once public to the jar is now actually public to the entire class-path and this might not be what we want. Conveniently classes that are public within a jar (domain) but were not intended for use outside that jar (domain) are now free to be used / misused by consumers of said jar.

4.2 Reliable Configuration

What was previously not possible is now possible via Jigsaw. Our Java applications will be able to verify dependencies at run-time and enforce the integrity of it.

Although versioning ambiguity remains an open issue (two identical jars with different versions), Jigsaw goes a long way in enforcing dependency integrity by guaranteeing a dependency is available and that their exists no cyclic dependencies between jars / modules.

4.3 Reduction of Package Footprint

By shrink wrapping the JDK and the application code base (including dependencies) into a collection of what is only needed, we can ship much smaller packages when deploying our applications. This is particularly useful when it comes to devices / platforms with resource constraints.

5. Modules

A module is a jar file which declares it’s dependencies and “public” API via a module descriptor file named module-info.java. The module-info.java file specifies the following:

  • The name of the module.
  • The packages it exports.
  • Other modules it depends on.

Modules can be 1 of 4 types:

5.1 Automatic Modules

Backward compatibility has never been an afterthought when it comes to Java and with Jigsaw that is no different. As we stated earlier, a module is a jar file with a module descriptor in it specifying it’s public contract, however most, if not all 3rd party libraries in use today, do not have a module descriptor and thus are not modules.

A method to allow us to use 3rd party libraries in modularized applications is via the “automatic module system”. What this means is that any jar file that has not explicitly bought into the module system (no module-info.java), which happens to be on the “module path” will become an “automatic module” where it’s entire contents will be made public to all other modules and subsequently also has access to all other modules including the “unnamed module”.

The JDK will publish the name of the jar (excluding version and extension with period spaces between words) as the module name. This way we can reference it as a dependency in our own custom module descriptors.

5.2 Application Modules

These are the orthodox module jar files which contain a module descriptor and publish their public contract (dependencies and API).

5.3 Platform Modules

These modules are “native” to the JDK and basically form the nett effect of modularizing the JDK. eg: java.base (implicity dependended on by any module) or java.xml.

5.4 Unnamed Module

A module that represents the consolidation of all jar files (modules and non modules) on the class-path and carries no module name, hence “unnamed”. It cannot be referenced by other modules but can access all other modules.

6. Module Descriptor

The module descriptor is the module-info.java file. It specifies the public API of the module. (ie: what it requires and what it depends on)

Required modules are not transitively available to transitive consumers, (ie: A requires B requires C means A does not see C automatically) unless requires transitive is specified. Modules are required and packages are exported.

The following example module descriptors include commons-lang3 (generated with the help of jdeps and patched into the binary commons-lang3 jar file) and jigsaw.date.service which specifies a dependency on commons.lang3.

Commons-lang3 Automatic Module

module commons.lang3 {
    exports org.apache.commons.lang3;
    exports org.apache.commons.lang3.builder;
    exports org.apache.commons.lang3.concurrent;
    exports org.apache.commons.lang3.event;
    exports org.apache.commons.lang3.exception;
    exports org.apache.commons.lang3.math;
    exports org.apache.commons.lang3.mutable;
    exports org.apache.commons.lang3.reflect;
    exports org.apache.commons.lang3.text;
    exports org.apache.commons.lang3.text.translate;
    exports org.apache.commons.lang3.time;
    exports org.apache.commons.lang3.tuple;
}

 
Jigsaw Date Service Application Module

module jigsaw.date.service {
	requires commons.lang3;
	exports com.javacodegeeks.jigsaw.date.service;
}

7. Tools

A brief primer on some tools available in the JDK which will help us build, package and run our application using Jigsaw features.

7.1 JDeps

A Java command line driven static dependency management tool for jar files. Results can be filtered and packaged at package level or jar file level.

It can be found in the bin folder of your JDK and has been around since Java 8. Confirming the version of jdeps is as easy as running jdeps --version. For help with jdeps simply run jdeps --help. Running jdeps commons-lang3-3.4.jar will reveal all the dependencies of commons-lang3 aggregated by package.

Jdeps output on Commons-Lang3

   org.apache.commons.lang3.mutable                   -> java.io                                            java.base
   org.apache.commons.lang3.mutable                   -> java.lang                                          java.base
   org.apache.commons.lang3.mutable                   -> org.apache.commons.lang3                           commons-lang3-3.4.jar
   org.apache.commons.lang3.mutable                   -> org.apache.commons.lang3.math                      commons-lang3-3.4.jar
   org.apache.commons.lang3.reflect                   -> java.lang                                          java.base
   org.apache.commons.lang3.reflect                   -> java.lang.annotation                               java.base
   org.apache.commons.lang3.reflect                   -> java.lang.reflect                                  java.base
   org.apache.commons.lang3.reflect                   -> java.util                                          java.base
   org.apache.commons.lang3.reflect                   -> org.apache.commons.lang3                           commons-lang3-3.4.jar
   org.apache.commons.lang3.reflect                   -> org.apache.commons.lang3.builder                   commons-lang3-3.4.jar
   org.apache.commons.lang3.text                      -> java.io                                            java.base
   org.apache.commons.lang3.text                      -> java.lang                                          java.base
   org.apache.commons.lang3.text                      -> java.nio                                           java.base
   org.apache.commons.lang3.text                      -> java.text                                          java.base
   org.apache.commons.lang3.text                      -> java.util                                          java.base
   org.apache.commons.lang3.text                      -> org.apache.commons.lang3                           commons-lang3-3.4.jar
   org.apache.commons.lang3.text                      -> org.apache.commons.lang3.builder                   commons-lang3-3.4.jar
   org.apache.commons.lang3.text.translate            -> java.io                                            java.base
   org.apache.commons.lang3.text.translate            -> java.lang                                          java.base
   org.apache.commons.lang3.text.translate            -> java.util                                          java.base
   org.apache.commons.lang3.text.translate            -> org.apache.commons.lang3                           commons-lang3-3.4.jar
   org.apache.commons.lang3.time                      -> java.io                                            java.base

In the snippet above we can see from left to right:

  • left: packages of commons-lang3
  • middle: packages it depends on
  • right: modules where the packages (middle) can be found

7.2 JLink

A Java command line driven tool which links / brings together all required modules for an application into a run time image.

This image is usually drastically smaller in size, thus helping reduce the footprint of the application as the entire JRE is not normally needed. jlink will also resolve static dependencies between modules thus guaranteeing the integrity of each module at run time. jlink requires that all artifacts are modules with well defined public contracts (exports, requires etc), thus “Automatic” modules will not suffice.

Running jlink --version reveals the version and running jlink --help brings up the help menu.

8. Building the Sample Application

In this section we will demonstrate how to build a very simple multi module date service application. The application very conveniently gives us the system date in a nice format using FastDateFormatter found in commons-lang3. The application has 2 main modules namely:

  • jigsaw.date.cli contains the main-class entry point of the application and depends on jigsaw.date.service.
  • jigsaw.date.service  which depends on commons-lang3. This module defines an interface (DateUtil), an implementation (SystemDate) (package private) and a factory (DateUtilFactory) which constructs the implementation for us. Being Jigsaw we export the package containing the interface and the factory for consumers to require and use. Although the implementation SystemDate is in the same package it is package-private and thus not visible from outside the package.

When you download the sample code and extract it to your file system you will notice 2 main folders, namely maven-build and manual-build. We will start with the manual-build.

8.1. Manual Build

The manual-build project directory has 2 folders in it, namely before and after. after represents everything completed right up until the creation of a run-time image and thus can be used for reference purposes and is also in fact used in parts of the maven build section. Our focus will be in the before folder where we will execute a series of instructions to build, package and run our sample application.

Navigating into the before folder you will see the following structure:

Manual directory Structure (before folder)

 
The 2 folders contained within:

  • automatic-modules: contains the commons-lang3-3.4.jar
  • src: contains the source code for our project jigsaw.date.cli and jigsaw.date.service and the source code for commons-lang3-3.4.jar

The next steps will be to compile and build our project manually.

Instructions for building and packaging the project manually

$ javac --module-path automatic-modules -d modules/jigsaw.date.service/ src/jigsaw.date.service/module-info.java src/jigsaw.date.service/com/javacodegeeks/jigsaw/date/service/*.java
$ javac --module-path automatic-modules:modules -d modules/jigsaw.date.cli/ src/jigsaw.date.cli/module-info.java src/jigsaw.date.cli/com/javacodegeeks/jigsaw/date/cli/*.java

$ java --module-path automatic-modules:modules -m jigsaw.date.cli/com.javacodegeeks.jigsaw.date.cli.Main
System date is : 09-09-2017
System date is : 09-09-2017

$ jdeps --generate-module-info tmp automatic-modules/commons-lang3-3.4.jar
writing to tmp/commons.lang3/module-info.java

$ javac -d tmp/commons.lang3/ --source-path src/3rd-party/commons-lang3/ tmp/commons.lang3/module-info.java
tmp/commons.lang3/module-info.java:1: warning: [module] module name component lang3 should avoid terminal digits
module commons.lang3 {
              ^
1 warning

$ mkdir patched-automatic-modules
$ cp automatic-modules/commons-lang3-3.4.jar patched-automatic-modules

$ jar --update --file patched-automatic-modules/commons-lang3-3.4.jar --module-version=3.3.4-module -C tmp/commons.lang3/ module-info.class

$ mkdir application-modules

$ jar --create --file=application-modules/[email protected] --module-version=1.0 -C modules/jigsaw.date.service/ .
$ jar --create --main-class=com.javacodegeeks.jigsaw.date.cli.Main --file=application-modules/[email protected] --module-version=1.0 -C modules/jigsaw.date.cli/ .

$ jar --describe-module --file=application-modules/[email protected]
[email protected] jar:file:///home/jean-jay/Documents/projects/codegeeks/java9-jigsaw-project/manual-build/before/application-modules/[email protected]/!module-info.class
exports com.javacodegeeks.jigsaw.date.service
requires commons.lang3
requires java.base mandated

$ jar --describe-module --file=application-modules/[email protected]
[email protected] jar:file:///home/jean-jay/Documents/projects/codegeeks/java9-jigsaw-project/manual-build/before/application-modules/[email protected]/!module-info.class
requires java.base mandated
requires jigsaw.date.service
contains com.javacodegeeks.jigsaw.date.cli
main-class com.javacodegeeks.jigsaw.date.cli.Main

$ java -p application-modules:patched-automatic-modules -m jigsaw.date.cli
System date is : 09-09-2017
System date is : 09-09-2017
  • lines 1 & 2: we build the jigsaw.date.service and jigsaw.date.cli projects respectively. Note we specify the module-path (where required modules can be found) as the automatic-modules folder as we require commons-lang3-3.4. Java 9 (Jigsaw) is nice enough to convert it into an Automatic module. We also specify the output folder for the compiled modules to be modules.
  • lines 4-6: we execute our main class module, again specifying the module-path but this time it is a combination of automatic-modules and modules.
  • line 8: we generate a module-info.java file for commons-lang3-3.4.jar using jdeps and place the module-info.java file in the tmp folder.
  • line 11: we compile our module-info.java file into a module-info.class file using the source code of commons-lang3-3.4.jar located in the src folder.
  • line 18: we copy the original commons-lang3-3.4.jar file from the automatic-modulesfolder to the patched-automatic-modules folder after creating said folder.
  • line 20: we update the commons-lang3-3.4.jar inside patched-automatic-modules with the compiled module-info.class file.
  • line 24 & 25: we make 2 jar files from our application modules jigsaw.date.service and jigsaw.date.cli.
  • lines 27-38: we use the jar describe utility to describe the modules and their API’s to us for confirmation.
  • lines 40-42: we run the modules.

The creation of a module-info.java and subsequent compilation of said module descriptor and patching of the commons-lang3-3.4.jar is only required for the run time image we will be creating at the end of the tutorial.

8.2 Maven Build

The maven-build project directory has the following structure to it: (excluding target as the target folder will be generated on maven build)

Directory structure of the maven-build project

Before running any build we need to publish the patched automatic jar (commons-lang3-3.4.jar) from the manual-build project to our local maven repository. This must be done so that when we run the maven build mvn clean install package maven will use the adjusted commons-lang3-3.4.jar (contains a module-info.class) for our maven-build version of the project.

The patched automatic jar can be found in <project-root-folder>/manual-build/after/patched-automatic-modules/commons-lang3-3.4.jar and can be installed to our local maven repository with the following command: (replace file path appropriately)

Installing our patched automatic module

mvn install:install-file -Dfile=<path-toproject>/java9-jigsaw-project/manual-build/after/patched-automatic-modules/commons-lang3-3.4.jar -DgroupId=org.apache.commons -DartifactId=commons-lang3 -Dversion=3.4-module -Dpackaging=jar

Snippets of the pom.xmlfiles are following for the parent maven project and each maven module:

Snippet of Jigsaw Date pom.xml (Parent project)

...
<modules>
		<module>jigsaw-date-cli</module>
		<module>jigsaw-date-service</module>
	</modules>

	<properties>
		<maven.compiler.plugin>3.6.0</maven.compiler.plugin>
		<maven.toolchains.plugin>1.1</maven.toolchains.plugin>
		<maven.jar.plugin>2.3.1</maven.jar.plugin>
		<maven.dependency.plugin.version>3.0.1</maven.dependency.plugin.version>

		<maven.compiler.source>1.9</maven.compiler.source>
		<maven.compiler.target>1.9</maven.compiler.target>
		<maven.compiler.release>9</maven.compiler.release>
	</properties>

	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>${maven.compiler.plugin}</version>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-toolchains-plugin</artifactId>
					<version>${maven.toolchains.plugin}</version>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-jar-plugin</artifactId>
					<version>${maven.jar.plugin}</version>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-dependency-plugin</artifactId>
					<version>${maven.dependency.plugin.version}</version>
				</plugin>
			</plugins>
		</pluginManagement>

		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-toolchains-plugin</artifactId>
				<configuration>
					<toolchains>
						<jdk>
							<version>1.9</version>
							<vendor>oracle</vendor>
						</jdk>
					</toolchains>
				</configuration>
				<executions>
					<execution>
						<?m2e ignore ?>
						<goals>
							<goal>toolchain</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
...

 
Snippet of Jigsaw Date Service pom.xml

...
<properties>
		<org.apache.commons.lang.version>3.4-module</org.apache.commons.lang.version>
	</properties>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.apache.commons</groupId>
				<artifactId>commons-lang3</artifactId>
				<version>${org.apache.commons.lang.version}</version>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependencies>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<outputDirectory>${project.build.directory}/../../target/modules</outputDirectory>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-dependency-plugin</artifactId>
				<executions>
					<execution>
						<id>copy-dependencies</id>
						<phase>package</phase>
						<goals>
							<goal>copy-dependencies</goal>
						</goals>
						<configuration>
							<outputDirectory>${project.build.directory}/../../target/modules</outputDirectory>
							<overWriteReleases>false</overWriteReleases>
							<overWriteSnapshots>false</overWriteSnapshots>
							<overWriteIfNewer>true</overWriteIfNewer>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
...
  • line 3: we specify a dependency on the patched automatic module
  • line 29 & 43: we specify that the build artifact and any dependencies be copied to the <project-root-folder>/maven-build/target/modules

 
Snippet of Jigsaw Date Cli pom.xml

...
<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>com.javacodegeeks</groupId>
				<artifactId>jigsaw-date-service</artifactId>
				<version>${project.version}</version>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<dependencies>
		<dependency>
			<groupId>com.javacodegeeks</groupId>
			<artifactId>jigsaw-date-service</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<outputDirectory>${project.build.directory}/../../target/modules</outputDirectory>
					<archive>
						<manifest>
							<mainClass>com.javacodegeeks.jigsaw.date.cli.Main</mainClass>
						</manifest>
					</archive>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-dependency-plugin</artifactId>
				<executions>
					<execution>
						<id>copy-dependencies</id>
						<phase>package</phase>
						<goals>
							<goal>copy-dependencies</goal>
						</goals>
						<configuration>
							<outputDirectory>${project.build.directory}/../../target/modules</outputDirectory>
							<overWriteReleases>false</overWriteReleases>
							<overWriteSnapshots>false</overWriteSnapshots>
							<overWriteIfNewer>true</overWriteIfNewer>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
...
  • lines 12-17: we specify a dependency on the jigsaw.date.service module
  • line 29 & 43: we specify that the build artifact and any dependencies be copied to the <project-root-folder>/maven-build/target/modules

Ensure you are in the <project-root-folder>/maven-build and execute mvn clean install package. The project will build and all built artifacts will be deposited into <project-root-folder>/maven-build/target/modules. You should see 3 module jars if successful:

  • jigsaw-date-cli-0.0.1-SNAPSHOT.jar
  • jigsaw-date-service-0.0.1-SNAPSHOT.jar
  • commons-lang3-3.4-module.jar

9. Running the Sample Application

Running the maven-build version (once built) can be done by navigating into the following folder <project-root-folder>/maven-build and executing:

Running maven built project

java -jar --module-path target/modules -m jigsaw.date.cli/com.javacodegeeks.jigsaw.date.cli.Main
System date is : 09-09-2017
System date is : 09-09-2017

10. Runtime Image

In this section we will create a run-time image from our manual-build project. This can only be done once all the previous steps for the manual build have completed successfully, therefore we will use the after folder in manual-build which guarantees all previous steps have been completed successfully.

Once the image has been built a new folder image.jigsaw.date.cli should have been created in the after folder. On my system the folder size is roughly 47.3mb proving how much jlink can drastically reduce the size of a Java run time image needed.

Building and Running a Runtime Image

$ jlink -v --module-path $JAVA_HOME/jmods:patched-automatic-modules:modules --add-modules jigsaw.date.cli,jigsaw.date.service --output image.jigsaw.date.cli  --launcher launch=jigsaw.date.cli/com.javacodegeeks.jigsaw.date.cli.Main
commons.lang3 file:///home/jean-jay/Documents/projects/codegeeks/java9-jigsaw-project/manual-build/after/patched-automatic-modules/commons-lang3-3.4.jar
java.base file:///home/jean-jay/runtimes/jdk-9/jmods/java.base.jmod
jigsaw.date.cli file:///home/jean-jay/Documents/projects/codegeeks/java9-jigsaw-project/manual-build/after/modules/jigsaw.date.cli/
jigsaw.date.service file:///home/jean-jay/Documents/projects/codegeeks/java9-jigsaw-project/manual-build/after/modules/jigsaw.date.service/

Providers:
  java.base provides java.nio.file.spi.FileSystemProvider used by java.base
$ ./image.jigsaw.date.cli/bin/java --list-modules
[email protected]
[email protected]
jigsaw.date.cli
jigsaw.date.service
$ ./image.jigsaw.date.cli/bin/launch
System date is : 09-09-2017
System date is : 09-09-2017
  • line 1: we issue the jlink command specifying the module path including our application module, patched automatic module and the JDK (jmod / platform modules). We also specify the output folder image.jigsaw.date.cli and a launcher script called launcher pointing to our main class. The launcher script will allow us to conveniently run our application from it. Because we specified verbose output we will see all the modules being added to the image and the locations from where they were taken being output to the screen.
  • line 9: we call the java executable from inside the image and ask it to list it’s modules for confirmation.
  • line 14: we call the launch script inside the image and we can see our system date being output in a nice formatted way.

11. Summary

In this tutorial we covered what project Jigsaw involves and what it brings to the Java platform. We dived into the mechanics of it and demonstrated how to structure, build and package an example project both from the command line and using the popular build an dependency management tool, Maven.

12. Download the Source Code

This was a Java 9 Jigsaw Project Tutorial

Download
You can download the full source code of this example here: Java 9 Jigsaw Project Tutorial

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

 

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

 

and many more ....

 

Receive Java & Developer job alerts in your Area from our partners over at ZipRecruiter

 

Want to take your Java skills to the next level?

Grab our programming books for FREE!

Here are some of the eBooks you will get:

  • Spring Interview QnA
  • Multithreading & Concurrency QnA
  • JPA Minibook
  • JVM Troubleshooting Guide
  • Advanced Java
  • Java Interview QnA
  • Java Design Patterns