{"id":1,"date":"2018-07-23T11:21:30","date_gmt":"2018-07-23T10:21:30","guid":{"rendered":"http:\/\/localhost:8888\/blog.opus.ch\/?p=1"},"modified":"2021-02-23T17:52:38","modified_gmt":"2021-02-23T16:52:38","slug":"introduction-to-jpms","status":"publish","type":"post","link":"https:\/\/opus.ch\/en\/introduction-to-jpms\/","title":{"rendered":"Introduction to the java platform module system (JPMS)"},"content":{"rendered":"<div class=\"wpb-content-wrapper\">[vc_row][vc_column][vc_column_text]With version 9 of Java, a new module system is introduced into the language. This module system is used internally for the JDK libraries but can be used by the application code as well. In contrast to other module systems like OSGi, the Java Platform Module System (JPMS) is an integral part of the language. Because of this, I hope there will be many modularized java applications in the future.<\/p>\n<p>Why should you modularize your code? This question would be a topic for a blog post in itself, but the main two reasons that stuck with me are: Organize your code in reusable units and manage dependencies. Most of the time we reuse a set of classes together instead of a single one. With modules, we have a convenient way to achieve this. Dependencies in Java are buried inside import definitions. With modules, they are explicitly stated and can be reasoned about without the help of code analysis tools.<\/p>\n<p>Sample code for this post can be found on <a href=\"https:\/\/github.com\/michihausheer\/opus-blog\/tree\/master\/1-IntroToJPMS\" target=\"_blank\" rel=\"noopener\">GitHub<\/a>.<\/p>\n<h3><strong>Module Descriptor<\/strong><\/h3>\n<p>Let&#8217;s start with the definition of a module and its dependencies. A module is defined through the module descriptor file called <code>module-info.java<\/code>. This file must be located at the root of the source folder of the module.<\/p>\n<p>The following snippet shows an example of such a module descriptor.<\/p>\n<pre class=\"top-margin:24 bottom-margin:24 left-set:true left-margin:24 lang:java decode:true\">module opus.address {\r\n  exports com.opus.address;\r\n\r\n  requires opus.utils;\r\n  requires java.xml;\r\n}<\/pre>\n<p>The descriptor defines a module named <code>opus.address<\/code>. The name must be unique and follow the same conventions as java package names. The first line inside the curly brackets states that the module exports the package <code>com.opus.adress<\/code>\u00a0for use by other modules. Everything that is not explicitly exported by a module cannot be used by other modules of the application.<\/p>\n<h3><strong>Dependencies<\/strong><\/h3>\n<p>A module defines its dependencies through the <code>requires<\/code> keyword followed by the name of the module. When a module requires another one it \u201creads\u201d this module. Reading a module allows the dependent module to use all public elements of packages that are exported by the read module. Java visibility rules still apply to the exported classes and interfaces.<\/p>\n<p>Every module requires <code>java.base<\/code> implicitly. When a module uses other modules from the java library, it needs to read them explicitly\u00a0as <code>java.xml<\/code> in the above example.<\/p>\n<p>Readability is not transitive by default. Modules requiring <code>opus.address<\/code> do not automatically read <code>opus.utils<\/code>. If this is desired you need to add the <code>transitive<\/code> keyword as follows:<\/p>\n<pre class=\"lang:default decode:true\">requires transitive opus.utils;<\/pre>\n<p>Every module that is requiring <code>opus.address<\/code> automatically reads <code>opus.utils<\/code> now. This is called implied readability and is transitive by itself. If <code>opus.utils<\/code> would have a transitive dependency on a third module, this would too be automatically read by modules requiring <code>opus.address<\/code>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-45\" src=\"https:\/\/opus.ch\/wp-content\/uploads\/2018\/06\/blogjpms_cropped.png\" alt=\"\" width=\"1\" height=\"1\" \/><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-75 size-medium\" src=\"https:\/\/opus.ch\/wp-content\/uploads\/2018\/06\/blogjpms_deps-282x300.png\" alt=\"\" width=\"282\" height=\"300\" srcset=\"https:\/\/opus.ch\/wp-content\/uploads\/2018\/06\/blogjpms_deps-282x300.png 282w, https:\/\/opus.ch\/wp-content\/uploads\/2018\/06\/blogjpms_deps-565x600.png 565w, https:\/\/opus.ch\/wp-content\/uploads\/2018\/06\/blogjpms_deps.png 612w\" sizes=\"auto, (max-width: 282px) 100vw, 282px\" \/><\/p>\n<h3><strong>Services<\/strong><\/h3>\n<p>Services are an integral part of the modules system. They provide means to decouple API and implementation and are in this sense a kind of dependency injection (DI) or inversion of control (IoC) mechanism. They can even be used in conjunction with common DI frameworks like spring or guice which is greatly explained <a href=\"https:\/\/www.oreilly.com\/ideas\/handling-dependency-injection-using-java9-modularity\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n<h3><strong>Providing a service<\/strong><\/h3>\n<p>The following module descriptor shows the necessary parts to provide a service.<\/p>\n<pre class=\"lang:default decode:true\">module opus.address {\r\n  exports com.opus.address;\r\n\r\n  provides com.opus.address.AddressRepository with\r\n    com.opus.address.repository.AddressRepositoryImpl;\r\n}<\/pre>\n<p><code>AddressRepository<\/code> is the interface (API) of the service and <code>AddressRepositoryImpl<\/code> (guess what) the implementation of it. Note that the module does not export the package that contains the implementation. Therefore, the consumers of the service do know nothing about it.<\/p>\n<p>Another module could too provide an <code>AddressRepository<\/code> with a CSV data source like this:<\/p>\n<pre class=\"lang:default decode:true \">module opus.address.csv {\r\n  requires opus.address;\r\n\r\n  provides com.opus.address.AddressRepository with\r\n\u00a0   com.opus.address.csv.CSVAddressRepository;\r\n}<\/pre>\n<h3><strong>Consuming a service<\/strong><\/h3>\n<p>Consuming a service is done through a lookup in the service registry. Some of you might know the service registry from previous versions of the JDK where it was used to provide services via metadata. In Java 9 the service registry is repurposed for use with the module system.<\/p>\n<p>When a module provides a service, the module system registers it automatically within the service registry. Our code queries the registry for implementations of the service interface.<\/p>\n<pre class=\"lang:default decode:true\">Iterable&lt;AddressRepository&gt; repositories =\r\n  ServiceLoader.load(AddressRepository.class);<\/pre>\n<p>When you iterate over the returned iterator, the services are lazily instantiated for you by the service loader.<\/p>\n<p>To instruct the module system to make a service available within our module, we need to declare a uses dependency on it in the module descriptor.<\/p>\n<pre class=\"lang:default decode:true\">module opus.customer {\r\n  requires opus.address;\r\n\r\n  uses com.opus.address.AddressRepository;\r\n}<\/pre>\n<p>The uses dependencies are only resolved at runtime and don\u2019t lead to an error when there are no repository implementations available. Our code needs to handle the situation when no implementation is available.<\/p>\n<h3><strong>Wrap Up \/ Final Thoughts<\/strong><\/h3>\n<p>I hope this post gave you a basic understanding of how to define modules in Java 9 and how they can help you write modularized code. If you are interested in topics like JPMS, modularity in general or domain driven design (DDD) make sure you subscribe to the opus blog newsletter. I will post a new article about every second Friday. Next up: a series about modularity patterns with samples using the JPMS.[\/vc_column_text][\/vc_column][\/vc_row]\n<\/div>","protected":false},"excerpt":{"rendered":"<p>[vc_row][vc_column][vc_column_text]With version 9 of Java, a new module system is introduced into the language. This module system is used internally for the JDK libraries but can be used by the application code as well. In contrast to other module systems like OSGi, the Java Platform Module System (JPMS) is an integral part of the language.&hellip;<\/p>\n","protected":false},"author":2,"featured_media":75,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,5,6],"tags":[],"post_series":[],"class_list":["post-1","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","category-jpms","category-modularity","entry","has-media"],"_links":{"self":[{"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/posts\/1","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/comments?post=1"}],"version-history":[{"count":1,"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/posts\/1\/revisions"}],"predecessor-version":[{"id":1128,"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/posts\/1\/revisions\/1128"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/media\/75"}],"wp:attachment":[{"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/media?parent=1"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/categories?post=1"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/tags?post=1"},{"taxonomy":"post_series","embeddable":true,"href":"https:\/\/opus.ch\/en\/wp-json\/wp\/v2\/post_series?post=1"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}