<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Java &#8211; Opus Software AG</title>
	<atom:link href="https://opus.ch/en/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>https://opus.ch/en/</link>
	<description>Anspruchsvolle Softwarelösungen</description>
	<lastBuildDate>Tue, 23 Feb 2021 16:52:38 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.4</generator>

<image>
	<url>https://opus.ch/wp-content/uploads/2021/01/cropped-opus_icon_vector-32x32.png</url>
	<title>Java &#8211; Opus Software AG</title>
	<link>https://opus.ch/en/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>DDD Concepts and Patterns – Value Object and Factory</title>
		<link>https://opus.ch/en/ddd-concepts-and-patterns-value-object-and-factory/</link>
					<comments>https://opus.ch/en/ddd-concepts-and-patterns-value-object-and-factory/#_comments</comments>
		
		<dc:creator><![CDATA[Michi Hausheer]]></dc:creator>
		<pubDate>Fri, 11 Jan 2019 08:24:21 +0000</pubDate>
				<category><![CDATA[DDD]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Patterns]]></category>
		<guid isPermaLink="false">http://blog.opus.ch/?p=420</guid>

					<description><![CDATA[This post is about the value object pattern and the factory pattern which are tactical patterns in domain driven design (DDD). Value objects define the second kind of domain objects besides entities. Their main characteristic is immutability: Attributes of a value object never change. Factories are responsible for creating new objects and validate them. They&#8230;]]></description>
										<content:encoded><![CDATA[<p>This post is about the value object pattern and the factory pattern which are tactical patterns in domain driven design (DDD). Value objects define the second kind of domain objects besides entities. Their main characteristic is immutability: Attributes of a value object never change.</p>
<p>Factories are responsible for creating new objects and validate them. They help us identify and separate this functionality from the other parts of a domain object.</p>
<h3>Value Objects</h3>
<p>Value objects do have attributes and methods as entities. Attributes of value objects are immutable though which implies that methods of value objects can only be queries, never commands that change the internal state of an object. We can pass value objects to clients through getters for example without worrying that they change them.</p>
<p>Many objects can be modeled as value objects instead of entities because they are defined through their attributes. These objects measure, quantify or describe things in the domain model. Because they are so easy to handle we should model as many value objects as possible.</p>
<h3>No identity, no lifecycle</h3>
<p>Value objects don’t have an identity that is used to compare them. We compare them by their attributes. When all attributes of a value object match another one they are considered equal. Therefore we can construct a value object from its attributes when needed and destroy it afterward.</p>
<p>Without the burden of maintaining an identity (create a unique id, associate it with other entities) value objects are a lot easier to handle than entities.</p>
<h3>Example</h3>
<p>An example of a value object is the material of a tabletop. The tabletop’s main material can be wood, stone or steel for example. Instead of adding attributes for kind (wood, steel), name (oak, chromium steel) and thickness directly to the table object let us create a value object called material.<br />
<img decoding="async" class="aligncenter wp-image-422" src="https://opus.ch/wp-content/uploads/2019/01/blogvalueobject.png" alt="" width="750" height="509" srcset="https://opus.ch/wp-content/uploads/2019/01/blogvalueobject.png 856w, https://opus.ch/wp-content/uploads/2019/01/blogvalueobject-300x204.png 300w, https://opus.ch/wp-content/uploads/2019/01/blogvalueobject-600x407.png 600w, https://opus.ch/wp-content/uploads/2019/01/blogvalueobject-768x521.png 768w" sizes="(max-width: 750px) 100vw, 750px" /><br />
Now the material is explicitly defined and named. We can interact with the table without thinking about the details of the material.</p>
<p>Maybe you decide the replace the tabletop with another after some years. However, because value objects are immutable, the material object cannot be changed. We replace it with the new one. Just like in the physical world, stone can&#8217;t be transformed into wood magically.</p>
<p>In code, the replacement boils down to setting new attributes and save them to persistence. If we modeled the material as an entity with identity, we first would need to delete the old material, generate a new id and associate it with the table object.</p>
<p>Now on to the second pattern of this post, the factory.</p>
<h3>Factory</h3>
<p>The factory pattern in DDD can be seen as a super pattern for the Gang of Four (GoF) creational patterns. Factories are concerned with creating new entities and value objects. They also validate the invariants for the newly created objects. We can place a factory on the entity or value object itself or an independent object.</p>
<p>Factories that are placed on the same object they create are either factory methods or prototype methods. The factory method creates a completely new object from the method parameters. The prototype method uses an existing instance to derive a new object.</p>
<p>When the creation logic is complex or has dependencies that are not needed by the created object it is best to create a separate factory. This factory could then provide multiple ways to create new instances.</p>
<h3>Wrap Up / Final Thoughts</h3>
<p>Value objects simplify our lives by releasing us from thinking about mutated state just like in the functional programming style. By combining them with entities, we can get a simple but powerful model within our code.</p>
<p>Factories draw a clear line between creation logic and other concerns in the code. When we name them explicitly and consistently, readability of our code should be improved.</p>
[Eva04] Eric Evans: Domain-Driven Design – Tackling Complexity in the Heart of Software (<a href="https://domainlanguage.com/" target="_blank" rel="noopener">homepage</a>)</p>
]]></content:encoded>
					
					<wfw:commentRss>https://opus.ch/en/ddd-concepts-and-patterns-value-object-and-factory/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
			</item>
		<item>
		<title>Modularity Patters with JPMS: Defautl Impl. and Module Facade</title>
		<link>https://opus.ch/en/modularity-patters-with-jpms-defautl-impl-and-module-facade/</link>
					<comments>https://opus.ch/en/modularity-patters-with-jpms-defautl-impl-and-module-facade/#_comments</comments>
		
		<dc:creator><![CDATA[Michi Hausheer]]></dc:creator>
		<pubDate>Mon, 08 Oct 2018 18:05:48 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JPMS]]></category>
		<category><![CDATA[Modularity]]></category>
		<category><![CDATA[Patterns]]></category>
		<guid isPermaLink="false">http://blog.opus.ch/?p=356</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[<div class="wpb-content-wrapper" id="wpb-content-root"><div class="vc_row wpb_row vc_row-fluid wpex-relative"><div class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner"><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element" >
		<div class="wpb_wrapper">
			<p>Continuing the series about modularization patterns with Java 9 today I would like to introduce the patterns Default Implementation and Module Facade [Kno12]. As its name suggests, the Default Implementation pattern is about providing implementations for abstract modules but also default configuration. Facades are a well-known pattern from [GoF] which can be applied to modules too as we will see.</p>
<h3>The Problem</h3>
<p>When we try to make modules flexible, we create abstract modules that separate implementations from abstractions and configurations. These now flexible modules are harder to use because users need multiple modules (abstraction and implementation) or external configuration.</p>
<p>Even if there is an implementation provided for a given abstraction, users should not depend on it. We need some mechanism that wires the implementation to the user.</p>
<h3>The Solution</h3>
<p>The solution to the above problem is to provide default implementations of abstractions and default configuration settings. We deploy default configurations normally within the same module, default implementations can be deployed within the same module or in a separate module.</p>
<p>We should also provide means to obtain default implementations without requiring users to depend on them directly. With the java platform module system (JPMS) we can use services to obtain default implementations as can be seen in the following sample.</p>
<h3>Default Implementation Sample</h3>
<p>The sales module of our ongoing webshop sample provides an API to apply a discount to the sales. Different implementations are provided by other modules that calculate a discount based on various criteria. In many use cases, however, there won’t be a discount applied. The customer needs to pay the full amount.</p>
<p><img decoding="async" class="aligncenter wp-image-367 size-large" src="https://opus.ch/wp-content/uploads/2018/10/blogdefaultimpl-600x294.png" alt="" width="600" height="294" srcset="https://opus.ch/wp-content/uploads/2018/10/blogdefaultimpl-600x294.png 600w, https://opus.ch/wp-content/uploads/2018/10/blogdefaultimpl-300x147.png 300w, https://opus.ch/wp-content/uploads/2018/10/blogdefaultimpl-768x376.png 768w, https://opus.ch/wp-content/uploads/2018/10/blogdefaultimpl.png 1221w" sizes="(max-width: 600px) 100vw, 600px" /></p>
<p>As you can see, the sales module provides a default implementation of the discount calculator. It covers the case where no discount needs to be calculated. From the three services that use the sales module, two provide an implementation of the discount calculator and one doesn’t. Another case that I don’t show here and which doesn’t provide an implementation could be the test module.</p>
<p>Without further actions, users need to create this default implementation themselves and therefore have a dependency on it. To prevent this undesired dependency, we have at least two options: Add a factory [GoF] or provide the discount calculator as a service. Because the factory pattern is already well-known, I  choose the service option for this sample.</p>
<p>The following module descriptor of the sales module declares a uses dependency on the discount calculator. At the same time, it provides the default implementation as a service.</p>
<pre class="lang:java decode:true ">module opus.sales {
    exports com.opus.sales;
    uses com.opus.sales.DiscountCalculator
    provides com.opus.sales.DiscountCalculator 
        with com.opus.sales.impl.DefaultDiscountCalculator;
}</pre>
<p>The default implementation will be used as long as no other module provides one with a higher priority. When a new requirement arises to provide a different implementation of the discount calculator, it can be implemented in a different module and plugged in the application without changing the sales module.</p>
<h3>Default Configuration</h3>
<p>In this <a href="http://blog.opus.ch/2018/09/modularity-patterns-with-jpms-published-interface-and-external-configuration/">post</a>, we saw the external configuration pattern which enhances the flexibility of the module. The sample was about configuring the URL of a REST call for different environments. Every developer that wants to use that module needs to provide a configuration for it which makes it harder to use.</p>
<p>To improve the situation, we could add a default configuration inside the module that points at some localhost URL. Then the developers would not need to provide a new configuration each time they want to reuse the module.</p>
<h3>Module Façade Pattern</h3>
<p>The Module Façade pattern [Kno12] seeks to improve the usability of multiple smaller modules. When we focus on flexibility and reuse, we tend to create many small modules. Those small modules become harder to use because of their fine granularity.</p>
<p>A module façade provides a common API for multiple smaller modules. It may also contain configuration for them and even add functionality itself.</p>
<h3>Sample Facade</h3>
<p>Suppose we want to manage different product categories as independent modules. For example, we could have a home electronics module and a pc module. They both share common functionality of the product base module but add their own search and filter options.</p>
<p><img loading="lazy" decoding="async" class="wp-image-361 aligncenter" src="https://opus.ch/wp-content/uploads/2018/10/blogmodulefacade.png" alt="" width="400" height="327" srcset="https://opus.ch/wp-content/uploads/2018/10/blogmodulefacade.png 612w, https://opus.ch/wp-content/uploads/2018/10/blogmodulefacade-300x245.png 300w, https://opus.ch/wp-content/uploads/2018/10/blogmodulefacade-600x490.png 600w" sizes="auto, (max-width: 400px) 100vw, 400px" /></p>
<p>To ease the use of those product category modules, we create a product module as a façade which includes the home electronics, pc and base modules. Users now only need to add a dependency on the façade without worrying about the different categories. When more categories are added, users automatically get access to them too without needing to modify their dependencies.</p>
<h3>Wrap Up / Final Thoughts</h3>
<p>When we want to use a module, it should work out of the box. If we need to find an implementation of an abstract module or need to add multiple dependencies to make it work, we are distracted from our actual task. If we design modules according to the two usability patterns default implementation and module façade, live for the users of our modules (which could be ourselves too) is greatly simplified.</p>
<p>[Kno12] K. Knoernschield: Java Application Architecture – Modularity Patterns with Examples Using OSGi (<a href="http://www.kirkk.com/modularity/" target="_blank" rel="noopener">homepage</a>)</p>
<p>[GoF] Design Patterns: Elements of Reusable Object-Oriented Software (<a href="https://en.wikipedia.org/wiki/Design_Patterns" target="_blank" rel="noopener">wiki</a>)</p>

		</div>
	</div>
</div></div></div></div>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://opus.ch/en/modularity-patters-with-jpms-defautl-impl-and-module-facade/feed/</wfw:commentRss>
			<slash:comments>24</slash:comments>
		
		
			</item>
		<item>
		<title>Modularity Patterns with JPMS: Published Interface and External Configuration</title>
		<link>https://opus.ch/en/modularity-patterns-with-jpms-published-interface-and-external-configuration/</link>
					<comments>https://opus.ch/en/modularity-patterns-with-jpms-published-interface-and-external-configuration/#_comments</comments>
		
		<dc:creator><![CDATA[Michi Hausheer]]></dc:creator>
		<pubDate>Fri, 14 Sep 2018 07:13:12 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JPMS]]></category>
		<category><![CDATA[Modularity]]></category>
		<category><![CDATA[Patterns]]></category>
		<guid isPermaLink="false">http://blog.opus.ch/?p=339</guid>

					<description><![CDATA[In this post, we look at two usability patterns: Published Interface and External Configuration. Usability patterns help to integrate modules with each other and generally simplify development with modules. When working with a module, the developer needs to know how he is supposed to use it. The published interface pattern acknowledges this and focuses on&#8230;]]></description>
										<content:encoded><![CDATA[<p>In this post, we look at two usability patterns: Published Interface and External Configuration. Usability patterns help to integrate modules with each other and generally simplify development with modules.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-342 size-medium" src="https://opus.ch/wp-content/uploads/2018/09/blogusability-300x157.png" alt="" width="300" height="157" srcset="https://opus.ch/wp-content/uploads/2018/09/blogusability-300x157.png 300w, https://opus.ch/wp-content/uploads/2018/09/blogusability-600x314.png 600w, https://opus.ch/wp-content/uploads/2018/09/blogusability.png 612w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<p>When working with a module, the developer needs to know how he is supposed to use it. The published interface pattern acknowledges this and focuses on a clearly defined API for modules. Another problem that we may face when using modules and especially re-using them is that we may need to change some configuration values. To allow this without recompilation of the module configuration can be located outside of the module as the external configuration pattern proposes.</p>
<h3>Published Interface</h3>
<p>The published interface pattern [Kno12] states that one should make the API of a module well known. What is part of the public API of the module and equally (or even more) important what is not? It is important to make this obvious for anyone using your modules. If we don&#8217;t, users (like ourselves next month) will certainly access elements of the module that we did not intend to. Afterward, we cannot change such elements easily without breaking code that uses the module.</p>
<p>Before the java module system, it was impossible to enforce usage of the public API. With the module system, we can publish it and prevent usage of elements by only exporting the required packages and providing services.</p>
<h3>The Sample</h3>
<p>Continuing the webshop sample let’s have a look at the customer component before refactoring it to modules. It contains implementations for consumers and business customers. They both implement a shared interface and users should use the factory to create them. The files are organized as follows:</p>
<pre class="lang:batch decode:true">com\opus\customer\
  Customer.java
  CustomerFactory.java

com\opus\customer\types\
  BusinessCustomer.java
  ConsumerCustomer.java</pre>
<p>Without the module system, it was possible for users to create the implementation types directly without using the factory. They could access the implementation types directly. Therefore, any change to these classes could have a big impact on users of the component.</p>
<p>Now we refactor to a module by adding the following module descriptor:</p>
<pre class="lang:java decode:true">module opus.customers {
    exports com.opus.customer;
}</pre>
<p>It is now impossible for users of our module to use the implementation classes directly. We have not only published the interface by explicitly stating exported packages but also prevent access to the others.</p>
<h3>External Configuration</h3>
<p>Another usability pattern introduced by [Kno12] is external configuration. It states that we should make modules externally configurable. When we create modules that are configurable the chances that they can be reused are increased.</p>
<h3>Sample</h3>
<p>In many projects, there are multiple stages or environments involved when deploying an application. Maybe there should be at least two, one for testing and the production. To deploy a module to multiple environments it needs to be configurable. For example, the sales module from the webshop application posts an event to a REST endpoint when a sale was completed. It, therefore, needs to know the URI of the endpoint which is different for each environment. We configure the URI externally through a properties file which we deploy next to the module JAR file.</p>
<pre class="lang:batch decode:true">Webshop\modules\sales\
    sales.jar
    config.properties</pre>
<p>With this setup, we can provide a different settings file for each environment. It probably would be easier to store the properties files inside the module, but then we would need to rebuild it for each environment.</p>
<h3>Wrap Up / Final Thoughts</h3>
<p>In this post, we saw two usability patterns that simplify usage and maintainability of modules. With the published interface we can ensure that our modules are used as intended. The external configuration allows for reusable modules that can be configured for different environments or even use cases.</p>
[Kno12] K. Knoernschield: Java Application Architecture – Modularity Patterns with Examples Using OSGi (<a href="http://www.kirkk.com/modularity/" target="_blank" rel="noopener">homepage</a>)</p>
]]></content:encoded>
					
					<wfw:commentRss>https://opus.ch/en/modularity-patterns-with-jpms-published-interface-and-external-configuration/feed/</wfw:commentRss>
			<slash:comments>26</slash:comments>
		
		
			</item>
		<item>
		<title>Modularity Patterns with JPMS: Independent Deployment</title>
		<link>https://opus.ch/en/modularity-patterns-with-jpms-independent-deployment/</link>
					<comments>https://opus.ch/en/modularity-patterns-with-jpms-independent-deployment/#_comments</comments>
		
		<dc:creator><![CDATA[Michi Hausheer]]></dc:creator>
		<pubDate>Fri, 31 Aug 2018 07:50:40 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JPMS]]></category>
		<category><![CDATA[Modularity]]></category>
		<category><![CDATA[Patterns]]></category>
		<guid isPermaLink="false">http://blog.opus.ch/?p=318</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[<div class="wpb-content-wrapper" id="wpb-content-root"><div class="vc_row wpb_row vc_row-fluid wpex-relative"><div class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner"><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element" >
		<div class="wpb_wrapper">
			<p>The next pattern that I would like to discuss is called “Independent Deployment” [Kno12]. It states that modules should be independently deployable units. For a module to be independently deployable, it cannot have any outgoing dependencies on other modules. In most cases, this is unrealistic, but the dependencies can be minimized.</p>
<p>Why should modules be independently deployable? If we want to reuse a module, every outgoing dependency is needed too. Therefore if we minimize outgoing dependencies, the module is going to be simpler to reuse.</p>
<p>Some dependencies are “lighter” than others and are preferable to “heavier” ones. For example, abstract classes and interfaces are light because they have a lower rate of change than their concrete implementations. A dependency on implementation can be avoided by defining an abstraction and use a wiring technic to get access to the implementation. With the java platform module system (JPMS) we can use services to implement the wiring.</p>
<p>Sample code for this post can be found on <a href="https://github.com/michihausheer/opus-blog/tree/master/4-IndependentDeploy" rel="noopener" target="_blank">GitHub</a>.</p>
<h3>The Sample</h3>
<p>In the first part of this series, I introduced the web shop as a sample of an application that we would like to modularize. Now we have the following modules in place.</p>
<pre class="lang:java decode:true">module opus.inventory {
  exports com.opus.inventory;

  requires com.opus.basket;
  requires opus.product;
}

module opus.basket {
  exports com.opus.basket;

  requires opus.product;
}</pre>
<p>The inventory module depends on baskets to calculate availability. Now imagine if we would like to reuse the inventory module in an application for inventory management where there are no sales with baskets going on. With this dependency in place, we would need to bring along the baskets module too, but there would never be any baskets.</p>
<h3>The Implementation</h3>
<p>The solution is to define an abstraction for availability adjustments. We create a new interface called <code>AvailabilityAdjuster</code> in the inventory module which is implemented by the basket module. Then we need to wire the implementation from the basket module to the inventory using a JPMS service. The inventory module now only depends on the abstract service interface which could be deployed within the inventory module itself or in a separate module.</p>
<pre class="lang:java decode:true">Module opus.inventory {
  exports com.opus.inventory;

  requires opus.product;

  uses com.opus.inventory.AvailabilityAdjuster;
}

module opus.baskets {
  exports com.opus.basket;

  requires opus.product;
  requires opus.inventory;

  provides com.opus.inventory.AvailabilityAdjuster
    with com.opus.basket.adjuster.AvailabilityAdjusterImpl
}</pre>
<p>This design allows us to deploy the inventory module independently. It is a bit more complex than the previous that allowed direct usage of the baskets module through. That’s a typical tension that we encounter in module design: To get the benefits of reusability, the use of some modules maybe gets harder. Therefore, I would aim for the simpler solution first. When the need arises to reuse some module, there is always the possibility to refactor.</p>
<h3>Another Option</h3>
<p>The sample above uses a callback to break (or invert actually) the dependency from the inventory to the baskets module. There is another possibility that may be better in some situations. We could implement escalation to break the dependency. As you may remember from the first part of this series the availability is used by the sales module that displays it to the user. If we move the responsibility to adjust availability according to the contents of the baskets to the sales module the dependency from inventory to baskets can be removed.</p>
<p><img loading="lazy" decoding="async" class="wp-image-320 size-large aligncenter" src="https://opus.ch/wp-content/uploads/2018/08/blogindependentdeploy-600x215.png" alt="" width="600" height="215" srcset="https://opus.ch/wp-content/uploads/2018/08/blogindependentdeploy-600x215.png 600w, https://opus.ch/wp-content/uploads/2018/08/blogindependentdeploy-300x108.png 300w, https://opus.ch/wp-content/uploads/2018/08/blogindependentdeploy-768x275.png 768w, https://opus.ch/wp-content/uploads/2018/08/blogindependentdeploy.png 1341w" sizes="auto, (max-width: 600px) 100vw, 600px" /></p>
<p>With this design, we move functionality to another module. The internal inventory system could implement the same concept of availability through, may be based on what is going to be delivered through the day. Then it may be undesirable to implement two solutions.</p>
<h3>Wrap Up / Final Thoughts</h3>
<p>Modules should simplify reuse of code. Therefore it should be possible to take individual modules and use them independently. That’s the goal of the independent deployment pattern. It advises how to design or adjust modules to make them reusable.</p>
<p>The JPMS enables us to remove dependencies by converting them into services which can be made optional to use or provided by a simple implementation. In our example, if the inventory system defines no availability adjusters, we can ignore this functionality and still reuse the module.</p>
<p><strong>[Kno12]</strong> K. Knoernschield: Java Application Architecture – Modularity Patterns with Examples Using OSGi (<a href="http://www.kirkk.com/modularity/" target="_blank" rel="noopener">homepage</a>)</p>

		</div>
	</div>
</div></div></div></div>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://opus.ch/en/modularity-patterns-with-jpms-independent-deployment/feed/</wfw:commentRss>
			<slash:comments>21</slash:comments>
		
		
			</item>
		<item>
		<title>Modularity Patterns with JPMS: Abstractions</title>
		<link>https://opus.ch/en/modularity-patterns-with-jpms-abstractions/</link>
					<comments>https://opus.ch/en/modularity-patterns-with-jpms-abstractions/#_comments</comments>
		
		<dc:creator><![CDATA[Michi Hausheer]]></dc:creator>
		<pubDate>Fri, 17 Aug 2018 07:51:33 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JPMS]]></category>
		<category><![CDATA[Modularity]]></category>
		<category><![CDATA[Patterns]]></category>
		<guid isPermaLink="false">http://blog.opus.ch/?p=271</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[<div class="wpb-content-wrapper" id="wpb-content-root"><div class="vc_row wpb_row vc_row-fluid wpex-relative"><div class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner"><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element" >
		<div class="wpb_wrapper">
			<p>While developing software in Java and other languages, we often create abstractions and separate them from the implementation. This practice has many benefits that we would like to take advantage of while designing modules. The Abstract Module and Separate Abstraction patterns from [Kno12] and API Modules from [Sand&amp;Bak17] deal with abstractions in the context of modules.</p>
<p>Sample code for this post can be found on <a href="https://github.com/michihausheer/opus-blog/tree/master/3-Abstractions" target="_blank" rel="noopener">GitHub</a>.</p>
<h3>Abstract Module</h3>
<p>The Abstract Module pattern states that users of modules should depend on abstractions, not implementations. When we depend on interfaces or abstract classes the implementation can change without affecting us. It may even be replaced completely by the maintainer of the module. Systems composed of modules that depend on abstractions of each other are flexible and easier to extend.</p>
<h3>Sample</h3>
<p>You may have come across the sample of payment methods in one form or another already. Let’s see how it looks like with Java 9 modules. If we have a webshop when we check out and complete a sale, there are multiple ways to pay. A first version of the checkout module depends directly on a credit card module and PayPal module as shown below.</p>
<pre class="lang:java decode:true">module opus.checkout {
  requires opus.creditcard;
  requires opus.paypal;
}

module opus.creditcard {
  exports com.opus.creditcard;
}

module opus.paypal {
  exports com.opus.paypal;
}</pre>
<p>As you probably imagine if we add new payment methods the checkout module needs to depend on them too. These dependencies introduce high coupling which we can avoid.</p>
<h3>The Refactoring</h3>
<p>To prevent coupling the checkout module to every payment method implementation we introduce a payment method abstraction. Now the modules containing payment methods depend on the checkout module.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-278" src="https://opus.ch/wp-content/uploads/2018/08/blogapimoduleinside.png" alt="" width="419" height="285" srcset="https://opus.ch/wp-content/uploads/2018/08/blogapimoduleinside.png 652w, https://opus.ch/wp-content/uploads/2018/08/blogapimoduleinside-300x204.png 300w, https://opus.ch/wp-content/uploads/2018/08/blogapimoduleinside-600x408.png 600w" sizes="auto, (max-width: 419px) 100vw, 419px" /></p>
<p>To make the payment methods usable from within the checkout module, we design the payment method abstraction as JPMS service with the interface <code>PaymentMethod</code>. The payment method modules provide this service with their implementation. Finally the <code>opus.checkout</code> module declares that it will use the payment method services as can be seen in the simplified module descriptors below.</p>
<pre class="lang:java decode:true ">module opus.checkout {
  exports com.opus.paymentmethod;
  uses com.opus.paymentmethod.PaymentMethod;
}

module opus.creditcard {
  requires opus.checkout;
  provides com.opus.paymentmethod.PaymentMethod 
    with com.opus.creditcard.CreditCardMethod;
}

module opus.paypal {
  provides com.opus.paymentmehtod.PaymentMethod
    with com.opus.paypal.PayPalMethod;

  requires opus.checkout;
}</pre>
<p>If we need to add more payment options, they can now easily be used by the checkout system without affecting its dependencies. It is also possible for the different implementers of payment methods to change without affecting (rebuild, deploy) the checkout module.</p>
<h3>API Modules</h3>
<p>The API Modules pattern [Sand&amp;Bak17] states that we should design the API of a module carefully and create dedicated API modules. The API of a module consists of all parts that are exported from it. We should make it as small as possible to gain resilient modules.</p>
<h3>Another Refactoring</h3>
<p>To apply the API Modules pattern we extend the previous sample with a separate API module called <code>opus.paymentmethod</code>. It contains only the interfaces for using the different payment methods and exports them.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-279" src="https://opus.ch/wp-content/uploads/2018/08/blogapimodule.png" alt="" width="510" height="268" srcset="https://opus.ch/wp-content/uploads/2018/08/blogapimodule.png 800w, https://opus.ch/wp-content/uploads/2018/08/blogapimodule-300x158.png 300w, https://opus.ch/wp-content/uploads/2018/08/blogapimodule-600x315.png 600w, https://opus.ch/wp-content/uploads/2018/08/blogapimodule-768x403.png 768w" sizes="auto, (max-width: 510px) 100vw, 510px" /></p>
<p>By using the JPMS service infrastructure, we don’t even need to export anything from the implementers. They have zero API and therefore no incoming dependency which allows us to change them without affecting any other module.</p>
<p>The API Modules pattern also states that most parts of the API should be abstractions. This statement aligns well with the goal of the Abstract Module pattern (depend on abstractions) discussed earlier. The API Modules pattern, therefore, can be seen as the inversion of the Abstract Module pattern. If modules only export abstractions other modules can depend only on them and not the implementations.</p>
<h3>Separate Abstractions</h3>
<p>The third pattern I would like to introduce is Separate Abstractions [Kno12]. It states that we should place abstractions and implementations in separate modules. If they live in the same module, they cannot change independently. Also, an implementation may require additional modules to provide its functionality which are not relevant for the abstraction.</p>
<h3>Sample</h3>
<p>Suppose our first design introduced an abstraction but located implementations in the same module. This module needs to depend on everything the implementations need like the opus.visaconnector. By refactoring the credit card implementation into its own module, we could remove this dependency from the module with the abstraction (<code>opus.checkout</code>). If there are many different implementations with multiple dependencies, extracting those implementations, helps to keep the modules clean an cohesive.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-298 size-full" src="https://opus.ch/wp-content/uploads/2018/08/blogabstractionssepdep_big.png" alt="" width="1341" height="520" srcset="https://opus.ch/wp-content/uploads/2018/08/blogabstractionssepdep_big.png 1341w, https://opus.ch/wp-content/uploads/2018/08/blogabstractionssepdep_big-300x116.png 300w, https://opus.ch/wp-content/uploads/2018/08/blogabstractionssepdep_big-600x233.png 600w, https://opus.ch/wp-content/uploads/2018/08/blogabstractionssepdep_big-768x298.png 768w" sizes="auto, (max-width: 1341px) 100vw, 1341px" /></p>
<p>Where should abstractions live then? If there is only one user of the abstraction, we could place it in the same module. Otherwise, we create a separate module on which multiple users can depend.</p>
<p>The implementations live in their own module. This module needs to depend on the abstraction which could be problematic when it is located in the same module as the user of it. To resolve this problem, we could create a separate abstract module even if there is only one user of it. We applied this already in the second refactoring of the payment method sample.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-300 size-full" src="https://opus.ch/wp-content/uploads/2018/08/blogabstractionsseparate_big.png" alt="" width="1527" height="443" srcset="https://opus.ch/wp-content/uploads/2018/08/blogabstractionsseparate_big.png 1527w, https://opus.ch/wp-content/uploads/2018/08/blogabstractionsseparate_big-300x87.png 300w, https://opus.ch/wp-content/uploads/2018/08/blogabstractionsseparate_big-600x174.png 600w, https://opus.ch/wp-content/uploads/2018/08/blogabstractionsseparate_big-768x223.png 768w" sizes="auto, (max-width: 1527px) 100vw, 1527px" /></p>
<h3>Wrap Up / Final Thoughts</h3>
<p>Abstractions are an integral part of software development. With modules, multiple questions arise regarding when to create them and where they should live. The patterns described in this post should help you answer those questions.</p>
<p>There is always a tension between (re-)usability and flexibility when designing modules. Modules that export abstractions and provide implementations too are easier to use. API only modules that separate abstractions from implementation are more flexible and have fewer dependencies but can be harder to use.</p>
<p><strong>[Kno12]</strong> K. Knoernschield: Java Application Architecture – Modularity Patterns with Examples Using OSGi (<a href="http://www.kirkk.com/modularity/" target="_blank" rel="noopener">homepage</a>)<br />
<strong>[Sand&amp;Bak17]</strong> Sander Mak &amp; Paul Bakker: Java 9 Modularity – Patterns and practices for developing maintainable applications (<a href="https://javamodularity.com/" target="_blank" rel="noopener">homepage</a>)</p>

		</div>
	</div>
</div></div></div></div>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://opus.ch/en/modularity-patterns-with-jpms-abstractions/feed/</wfw:commentRss>
			<slash:comments>24</slash:comments>
		
		
			</item>
		<item>
		<title>Modularity Patterns with JPMS: Acyclic Dependencies</title>
		<link>https://opus.ch/en/modularity-patterns-with-jpms-acyclic-dependencies/</link>
					<comments>https://opus.ch/en/modularity-patterns-with-jpms-acyclic-dependencies/#_comments</comments>
		
		<dc:creator><![CDATA[Michi Hausheer]]></dc:creator>
		<pubDate>Sat, 04 Aug 2018 10:11:23 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JPMS]]></category>
		<category><![CDATA[Modularity]]></category>
		<category><![CDATA[Patterns]]></category>
		<guid isPermaLink="false">http://blog.opus.ch/?p=180</guid>

					<description><![CDATA[Modularization is the process of organizing code into cohesive units. This process is sometimes tedious and hard to do consistently. Patterns can help to make modularization simpler by providing solutions for some common problems. [Kno12] and [Sand&#38;Bak17] are two books which describe patterns that are concerned with modularity. In this blog post series, I am&#8230;]]></description>
										<content:encoded><![CDATA[<p>Modularization is the process of organizing code into cohesive units. This process is sometimes tedious and hard to do consistently. Patterns can help to make modularization simpler by providing solutions for some common problems. [Kno12] and [Sand&amp;Bak17] are two books which describe patterns that are concerned with modularity. In this blog post series, I am going to show you how they can be applied using the Java Platform Module System (JPMS).</p>
<p>Sample code for this post can be found on <a href="https://github.com/michihausheer/opus-blog/tree/master/2-AcyclicDeps" target="_blank" rel="noopener">GitHub</a>.</p>
<h3>The Pattern: Acyclic Dependencies</h3>
<p>Dependencies between modules should never form a cycle. Different kinds of cycles include direct dependencies as well as indirect dependencies over three or more modules. In the diagram below there are two cycles, one between module 1 and 2 and the other indirectly over module 3.</p>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-197 aligncenter" src="https://opus.ch/wp-content/uploads/2018/08/blogcycles-1-300x175.png" alt="" width="300" height="175" srcset="https://opus.ch/wp-content/uploads/2018/08/blogcycles-1-300x175.png 300w, https://opus.ch/wp-content/uploads/2018/08/blogcycles-1-600x350.png 600w, https://opus.ch/wp-content/uploads/2018/08/blogcycles-1.png 652w" sizes="auto, (max-width: 300px) 100vw, 300px" /><br />
When refactoring existing code to modules, it is often the case that you discover cyclic dependencies between packages that you would like to separate in different modules. However, when you refactor towards acyclic dependencies usability and reuse of the code is improved as you will see in the example below.</p>
<h3>Implementation</h3>
<p>The simplest way to avoid cycles is to remove dependencies altogether. So before applying any of the methods to break cycles think through the involved dependencies. Are they absolutely required or is there a way to remove them?</p>
<p>If they are required, there are multiple ways to break a cycle in your module dependency graph. These are escalation, demotion, and call-back. The following sections show an example of each of these methods.</p>
<h3>The sample</h3>
<p>Imagine a web shop application that we want to modularize. It has three components: Product, Inventory, and Sale. When a product is displayed to the user during a session, the sales page checks the inventory for its availability. According to a business requirement, when there are multiple sales going on in parallel, we need to ensure that the availability is always guaranteed. Therefore, the inventory needs to take the baskets of these sales into account when calculating the availability. Baskets are located in the sale component. These dependencies form a cycle between the sale and inventory components as shown below.</p>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-195 aligncenter" src="https://opus.ch/wp-content/uploads/2018/08/blogcyclesweb-300x174.png" alt="" width="300" height="174" srcset="https://opus.ch/wp-content/uploads/2018/08/blogcyclesweb-300x174.png 300w, https://opus.ch/wp-content/uploads/2018/08/blogcyclesweb-600x348.png 600w, https://opus.ch/wp-content/uploads/2018/08/blogcyclesweb.png 672w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<h3>The Refactoring</h3>
<p>When we refactor the components to modules without change we end up with the following module descriptors:</p>
<pre class="top-margin:24 bottom-margin:24 left-set:true left-margin:24 lang:java decode:true">module opus.inventory {
  exports com.opus.inventory;

  requires opus.sale; &lt;--- cycle
  requires opus.product;
}

module opus.sale {
  exports com.opus.sale;

  requires opus.inventory; &lt;---- cycle
  requires opus.product;
}

module opus.product {
  exports com.opus.product;
}</pre>
<p>This code fails to compile because of the cycle. We need to break it by using one of the following methods.</p>
<h3>Escalation</h3>
<p>The first method is to use escalation. We design an additional module called sale process. This module has a dependency on both the inventory and sale module. When the system shows a product to the user, the sale process is responsible for calculating the availability. It asks the inventory for the stock count and checks the baskets from the sale module. With this change, we can remove the dependencies between sale and inventory altogether.</p>
<p><img loading="lazy" decoding="async" class=" wp-image-242 aligncenter" src="https://opus.ch/wp-content/uploads/2018/08/blogcyclesescalation-1-300x237.png" alt="" width="357" height="282" srcset="https://opus.ch/wp-content/uploads/2018/08/blogcyclesescalation-1-300x237.png 300w, https://opus.ch/wp-content/uploads/2018/08/blogcyclesescalation-1-600x473.png 600w, https://opus.ch/wp-content/uploads/2018/08/blogcyclesescalation-1.png 692w" sizes="auto, (max-width: 357px) 100vw, 357px" /></p>
<h3>Demotion</h3>
<p>Another way to break the cycle is to create a new module called basket. Both the sale and the inventory module depend on the basket module. We ask the inventory for the availability like before. The inventory, in turn, checks the baskets for ongoing sales.</p>
<pre class="top-margin:24 bottom-margin:24 left-set:true left-margin:24 lang:java decode:true ">module opus.basket {
  exports com.opus.basket;
}

module opus.inventory {
  exports com.opus.inventory;

  requires opus.basket;
}

module opus.sale {
  requires opus.inventory;
  requires opus.basket;
}</pre>
<p>This is called demotion. We demote functionality to a module on a lower level.</p>
<h3>Callback</h3>
<p>The third method to break cycles is to use a callback. To implement it we need a new JPMS service called <code>OngoingSalesCalculator</code> with a method <code>ongoingSalesCountFor(Product product)</code>. This interface is located inside the inventory module (or a separate module) and implemented within the sale module. The inventory uses the callback to calculate the availability now instead of checking the baskets directly.</p>
<pre class="top-margin:24 bottom-margin:24 left-set:true left-margin:24 lang:java decode:true ">module opus.inventory {
  exports com.opus.inventory;

  uses com.opus.inventory.OngoingSalesCalculator;
}

module opus.sale {
  requires opus.inventory;

  provides com.opus.inventory.OngoingSalesCalculator 
    with com.opus.sale.impl.OngoingSalesCalculatorImpl;
}</pre>
<p>With this callback in place, we can remove the dependency from the inventory module on the sales module. By using a JPMS service, we don’t need a main class or a framework to do the wiring. We obtain the callback service directly from the service loader inside the inventory module.</p>
<p>When looking at the above descriptors, it may seem that there is still a cycle between those modules. There is actually one but only at runtime. The inventory module does not depend on the sales module during development and compile time but uses the calculator service only at runtime.</p>
<h3>Wrap Up / Final Thoughts</h3>
<p>When an existing code base is refactored into modules, the resulting dependency graph may contain cycles. These not only prevent code reuse but make it harder to think about the code and change it. There are multiple ways to break cycles, three of which we have seen in this post. When we break the cycles, individual modules can be reused and should be simpler to maintain.</p>
<p>The next part of this series about modularity patterns will take a look at abstractions in the context of modules. We will discover three patterns which help us design resilient modules: Abstract Module, Separate Abstraction and API Modules.</p>
<p><strong>[Kno12]</strong> K. Knoernschield: Java Application Architecture – Modularity Patterns with Examples Using OSGi (<a href="http://www.kirkk.com/modularity/" target="_blank" rel="noopener">homepage</a>)<br />
<strong>[Sand&amp;Bak17]</strong> Sander Mak &amp; Paul Bakker: Java 9 Modularity – Patterns and practices for developing maintainable applications (<a href="https://javamodularity.com/" target="_blank" rel="noopener">homepage</a>)</p>
]]></content:encoded>
					
					<wfw:commentRss>https://opus.ch/en/modularity-patterns-with-jpms-acyclic-dependencies/feed/</wfw:commentRss>
			<slash:comments>25</slash:comments>
		
		
			</item>
		<item>
		<title>Introduction to the java platform module system (JPMS)</title>
		<link>https://opus.ch/en/introduction-to-jpms/</link>
					<comments>https://opus.ch/en/introduction-to-jpms/#_comments</comments>
		
		<dc:creator><![CDATA[Michi Hausheer]]></dc:creator>
		<pubDate>Mon, 23 Jul 2018 10:21:30 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JPMS]]></category>
		<category><![CDATA[Modularity]]></category>
		<guid isPermaLink="false">http://localhost:8888/blog.opus.ch/?p=1</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[<div class="wpb-content-wrapper" id="wpb-content-root"><div class="vc_row wpb_row vc_row-fluid wpex-relative"><div class="wpb_column vc_column_container vc_col-sm-12"><div class="vc_column-inner"><div class="wpb_wrapper">
	<div class="wpb_text_column wpb_content_element" >
		<div class="wpb_wrapper">
			<p>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>
<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>
<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>
<h3><strong>Module Descriptor</strong></h3>
<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>
<p>The following snippet shows an example of such a module descriptor.</p>
<pre class="top-margin:24 bottom-margin:24 left-set:true left-margin:24 lang:java decode:true">module opus.address {
  exports com.opus.address;

  requires opus.utils;
  requires java.xml;
}</pre>
<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> for use by other modules. Everything that is not explicitly exported by a module cannot be used by other modules of the application.</p>
<h3><strong>Dependencies</strong></h3>
<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 “reads” 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>
<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 as <code>java.xml</code> in the above example.</p>
<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>
<pre class="lang:default decode:true">requires transitive opus.utils;</pre>
<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>
<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>
<h3><strong>Services</strong></h3>
<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>
<h3><strong>Providing a service</strong></h3>
<p>The following module descriptor shows the necessary parts to provide a service.</p>
<pre class="lang:default decode:true">module opus.address {
  exports com.opus.address;

  provides com.opus.address.AddressRepository with
    com.opus.address.repository.AddressRepositoryImpl;
}</pre>
<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>
<p>Another module could too provide an <code>AddressRepository</code> with a CSV data source like this:</p>
<pre class="lang:default decode:true ">module opus.address.csv {
  requires opus.address;

  provides com.opus.address.AddressRepository with
    com.opus.address.csv.CSVAddressRepository;
}</pre>
<h3><strong>Consuming a service</strong></h3>
<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>
<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>
<pre class="lang:default decode:true">Iterable&lt;AddressRepository&gt; repositories =
  ServiceLoader.load(AddressRepository.class);</pre>
<p>When you iterate over the returned iterator, the services are lazily instantiated for you by the service loader.</p>
<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>
<pre class="lang:default decode:true">module opus.customer {
  requires opus.address;

  uses com.opus.address.AddressRepository;
}</pre>
<p>The uses dependencies are only resolved at runtime and don’t lead to an error when there are no repository implementations available. Our code needs to handle the situation when no implementation is available.</p>
<h3><strong>Wrap Up / Final Thoughts</strong></h3>
<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.</p>

		</div>
	</div>
</div></div></div></div>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://opus.ch/en/introduction-to-jpms/feed/</wfw:commentRss>
			<slash:comments>22</slash:comments>
		
		
			</item>
	</channel>
</rss>
