blob: 970f8664aacff9267f76dabe073c92d40b96df30 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Modules :: Apache Isis</title>
<link rel="canonical" href="https://isis.apache.org/userguide/2.0.0-M3/fun/overview/modules.html">
<meta name="generator" content="Antora 2.2.0">
<link rel="stylesheet" href="../../../../_/css/site.css">
<link rel="stylesheet" href="../../../../_/css/site-custom.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,700,700i|Raleway:300,400,500,700,800|Montserrat:300,400,700" rel="stylesheet">
<link rel="home" href="https://isis.apache.org" title="Apache Isis">
</head>
<body class="article">
<header class="header">
<nav class="navbar">
<div class="navbar-brand">
<a class="navbar-item" href="https://isis.apache.org">
<span class="icon">
<img src="../../../../_/img/isis-logo-48x48.png"></img>
</span>
<span>Apache Isis</span>
</a>
<button class="navbar-burger" data-target="topbar-nav">
<span></span>
<span></span>
<span></span>
</button>
</div>
<div id="topbar-nav" class="navbar-menu">
<a class="navbar-end">
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Quick Start</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Starter Apps</span>
<a class="navbar-item" href="../../../../docs/latest/starters/helloworld.html">Hello World</a>
<a class="navbar-item" href="../../../../docs/latest/starters/simpleapp.html">Simple App</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Demos &amp; Tutorials</span>
<a class="navbar-item" href="../../../../docs/latest/demo/about.html">Demo App</a>
<a class="navbar-item" href="https://danhaywood.gitlab.io/isis-petclinic-tutorial-docs/petclinic/1.16.2/intro.html">Petclinic (tutorial)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Resources</span>
<a class="navbar-item" href="../../../../docs/latest/resources/cheatsheet.html">Cheatsheet</a>
<a class="navbar-item" href="../../../../docs/latest/resources/icons.html">Icons</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Guides</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Development</span>
<a class="navbar-item" href="../../../../setupguide/latest/about.html">Setup Guide</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Core</span>
<a class="navbar-item" href="../../../../userguide/latest/about.html">User Guide</a>
<a class="navbar-item" href="../../../../refguide/latest/about.html">Reference Guide</a>
<a class="navbar-item" href="../../../../testing/latest/about.html">Testing Guide</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Libraries</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">For Use in Apps</span>
<a class="navbar-item" href="../../../../subdomains/latest/about.html">Subdomain Libraries</a>
<a class="navbar-item" href="../../../../valuetypes/latest/about.html">Value Types</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Integrate between Apps</span>
<a class="navbar-item" href="../../../../mappings/latest/about.html">Bounded Context Mapping Libraries</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Other</span>
<a class="navbar-item" href="../../../../incubator/latest/about.html">Incubator</a>
<a class="navbar-item" href="../../../../legacy/latest/about.html">Legacy</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Components</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Viewers</span>
<a class="navbar-item" href="../../../../vw/latest/about.html">Wicket UI</a>
<a class="navbar-item" href="../../../../vro/latest/about.html">Restful Objects (REST)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Security</span>
<a class="navbar-item" href="../../../../security/latest/about.html">Security Guide</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Persistence</span>
<a class="navbar-item" href="../../../../pjdo/latest/about.html">DataNucleus (JDO)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Extensions</span>
<a class="navbar-item" href="../../../../extensions/latest/about.html">Extensions Catalog</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Support</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Contact</span>
<a class="navbar-item" href="../../../../docs/latest/support/slack-channel.html">Slack</a>
<a class="navbar-item" href="../../../../docs/latest/support/mailing-list.html">Mailing Lists</a>
<a class="navbar-item" href="https://issues.apache.org/jira/browse/ISIS">JIRA</a>
<a class="navbar-item" href="https://stackoverflow.com/questions/tagged/isis">Stack Overflow</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Releases</span>
<a class="navbar-item" href="../../../../docs/latest/downloads/how-to.html">Downloads</a>
<a class="navbar-item" href="../../../../relnotes/latest/about.html">Release Notes</a>
<a class="navbar-item" href="../../../../docs/latest/archive/1-x.html">Archive (1.x)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Framework</span>
<a class="navbar-item" href="../../../../conguide/latest/about.html">Contributors' Guide</a>
<a class="navbar-item" href="../../../../comguide/latest/about.html">Committers' Guide</a>
<a class="navbar-item" href="../../../../core/latest/about.html">Core Design</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">ASF</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="http://www.apache.org/">Apache Homepage</a>
<a class="navbar-item" href="https://www.apache.org/events/current-event">Events</a>
<a class="navbar-item" href="https://www.apache.org/licenses/">Licenses</a>
<a class="navbar-item" href="https://www.apache.org/security/">Security</a>
<a class="navbar-item" href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a>
<a class="navbar-item" href="https://www.apache.org/foundation/thanks.html">Thanks</a>
<hr class="navbar-divider"/>
<a class="navbar-item" href="https://whimsy.apache.org/board/minutes/Isis.html">PMC board minutes</a>
</div>
</div>
<a class="navbar-item" href="../../../../docs/latest/about.html">
<span class="icon">
<img src="../../../../_/img/home.png"></img>
</span>
</a>
</div>
</div>
</nav>
</header>
<div class="body ">
<div class="nav-container" data-component="userguide" data-version="2.0.0-M3">
<aside class="nav">
<div class="panels">
<div class="nav-panel-pagination">
<a class="page-previous disabled" rel="prev" href="" title=""><span></span></a>
<a class="page-next disabled" rel="next"
href="" title=""><span></span></a>
<!--
page.parent doesn't seem to be set...
<a class="page-parent disabled" rel="prev" href="" title=""><span></span></a>
-->
</div>
<div class="nav-panel-menu is-active" data-panel="menu">
<nav class="nav-menu">
<h3 class="title"><a href="../../about.html">User Guide</a></h3>
<ul class="nav-list">
<li class="nav-item" data-depth="0">
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../concepts-patterns.html">Concepts &amp; Patterns</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../overview.html">Overview</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../domain-entities-and-services.html">Domain Entities &amp; Services</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../object-members.html">Object Members</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../ui.html">UI Layout &amp; Hints</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../business-rules.html">Business Rules</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../drop-downs-and-defaults.html">Drop downs and Defaults</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../meta-annotations.html">Meta-annotations</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../view-models.html">View Models</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../mixins.html">Mixins</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../modules.html">Modules</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../btb/about.html">Beyond the Basics</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../btb/i18n.html">i18n</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../btb/headless-access.html">Headless Access</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../btb/hints-and-tips.html">Hints-n-Tips</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../btb/programming-model.html">Programming Model</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<span class="nav-text">Extensions</span>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../flyway/about.html">Flyway</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="nav-panel-explore" data-panel="explore">
<div class="context">
<span class="title">User Guide</span>
<span class="version">2.0.0-M3</span>
</div>
<ul class="components">
<li class="component">
<span class="title"> </span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../docs/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">BC Mappings Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../mappings/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Committers' Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../comguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Contributors' Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../conguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Design Docs</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../core/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Extensions Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../extensions/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Incubator Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../incubator/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">JDO/DataNucleus</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../pjdo/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Legacy Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../legacy/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Reference Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../refguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Release Notes</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../relnotes/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Restful Objects Viewer</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../vro/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Security Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../security/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Setup Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../setupguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Subdomains Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../subdomains/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Testing Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../testing/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component is-current">
<span class="title">User Guide</span>
<ul class="versions">
<li class="version is-current is-latest">
<a href="../../about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Value Types Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../valuetypes/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Wicket Viewer</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../../vw/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</aside>
</div>
<main role="main">
<div class="toolbar" role="navigation">
<button class="nav-toggle"></button>
<a href="../../../../docs/2.0.0-M3/about.html" class="home-link"></a>
<nav class="breadcrumbs" aria-label="breadcrumbs">
<ul>
<li><a href="../../about.html">User Guide</a></li>
<li><a href="modules.html">Modules</a></li>
</ul>
</nav>
<div class="edit-this-page"><a href="https://github.com/apache/isis/edit/2.0.0-M3/api/adoc/userguide/modules/fun/pages/overview/modules.adoc">Edit</a></div>
</div>
<article class="doc">
<a name="section-top"></a>
<h1 class="page">Modules</h1>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Enabling and ensuring modularity is a <a href="../concepts-patterns.html#modular" class="page">key principle</a> for the Apache Isis framework.
Modularity is the only way to ensure that a complex application domain does not over time degenerate into the infamous "big ball of mud", software that is difficult, dangerous and expensive to change.</p>
</div>
<div class="paragraph">
<p>Modules chunk up the overall application into smaller pieces, usually a pacakge and subpackages.
The smaller pieces can be either tiers (presentation / domain / persistence) or functional architectural layers (eg customer vs orders vs products vs invoice etc).
Because Apache Isis takes care of the presentation and persistence tiers, modules for us focuses just on the important bit: considering how the functionality within the domain model should be broken up into modules, and determining the dependencies between those modules.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="rules-of-thumb"><a class="anchor" href="#rules-of-thumb"></a>Rules of Thumb</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The two main rule of thumbs for dependencies are:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>there should be no cyclic dependencies (the module dependencies should form an acyclic graph), and</p>
</li>
<li>
<p>unstable modules should depend upon stable modules, rather than the other way around.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>By "unstable" we don&#8217;t mean buggy, rather this relates to its likelihood to change its structure or behaviour over time: in other words its stability as a core set of concepts upon which other stuff can depend.
Reference data (calendars, tax rates, lookups etc) are generally stable, as are "golden" concept such as counterparties / legal entities or financial accounts.
Transactional concepts such as invoices or agreements is perhaps more likely to change.
But this stuff is domain specific.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="decoupling"><a class="anchor" href="#decoupling"></a>Decoupling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Having broken up a domain into multiple modules, there is still a need for higher level modules to use lower level modules, and the application must still appear as a coherent whole to the end-user.</p>
</div>
<div class="paragraph">
<p>The key features that Apache Isis provides to support this are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>dependency injection of services</p>
<div class="paragraph">
<p>Both <a href="../../../../refguide/2.0.0-M3/applib-svc/about.html" class="page">framework-defined</a> domain services and application-defined services (eg repositories and factories) are injected everywhere, using the <code>@javax.inject.Inject</code> annotation (Spring&#8217;s <code>@Autowired</code> can also be used).</p>
</div>
<div class="paragraph">
<p>By "everywhere", we mean not just into domain services, but <em>also</em> injected into domain entities and view models.
This enables us to implement behaviourally complete domain objects (if we so wish).</p>
</div>
</li>
<li>
<p><a href="../overview.html#mixins" class="page">mixins</a> that allow functionality defined in one module to appear (in the UI) to be provided by some other module.</p>
<div class="paragraph">
<p>For example, a <em>Document</em> module might allow <code>Document</code> objects to be attached to any arbitrary domain object (such as <code>Order</code> or <code>Customer</code>) in other modules.
A mixin would allow the UI for a <code>Customer</code> to also display these attached <code>Document</code>s, even though the <em>Customer</em> module would have no knowledge of/dependency on the <em>Workflow</em> module.
(More on this example <a href="../overview.html#inverting-dependencies" class="page">below</a>).</p>
</div>
<div class="paragraph">
<p>Dependencies are also injected into mixins.
A common technique is to factor out from domain objects into mixins and then generalise.</p>
</div>
</li>
<li>
<p>the internal <a href="../../../../refguide/2.0.0-M3/applib-svc/EventBusService.html" class="page">event bus</a> allows modules to influence other modules.</p>
<div class="paragraph">
<p>A subscriber in one module can subscribe to events emitted by domain objects in another module.
These events can affect both the UI (eg hiding or disabling <a href="../overview.html#object-members" class="page">object members</a>, or allowing or vetoing interactions).</p>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>A good example of this last is supporting (what in an RDBMS we would call) referential integrity.
Suppose the <code>customers</code> module has a <code>Customer</code> object and a <code>EmailAddress</code> object, with a customer having a collection of email addresses.
A <code>communications</code> module might then use those email addresses to create <code>EmailCommunication</code>s.</p>
</div>
<div class="paragraph">
<p>If the <code>customers</code> module wants to delete an <code>EmailAddress</code> then the <code>communications</code> module will probably want to veto this because they are "in use" by those <code>EmailCommunication</code>s.
Or, it might conceivably perform a cascade delete of all associated communications.
Either way, the <code>communications</code> module receives an internal event representing the intention to delete the <code>EmailAddress</code>.
It can then act accordingly, either vetoing the interaction or performing the cascade delete.
The <code>customers</code> module for its part does not know anything about this other module.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="inverting-dependencies"><a class="anchor" href="#inverting-dependencies"></a>Inverting Dependencies</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If we get the dependencies wrong (that is, our initial guess on stability is proven incorrect over time) then there are a couple of techniques we can use:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>use the <a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">dependency inversion principle</a> to introduce an abstraction representing the dependency.</p>
</li>
<li>
<p>move functionality, eg by factoring it out into <a href="../overview.html#mixins" class="page">mixins</a> into the other module or into a third module which depends on the other modules that had a bidirectional relationship</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Mixins in particular allow dependencies to be inverted, so that the dependencies between modules can be kept acyclic and under control.</p>
</div>
<div class="paragraph">
<p>For example, suppose that we send out <code>Invoice</code>s to <code>Customer</code>s.
We want the invoices to know about customers, but not vice versa.
We could surface the set of invoices for a customer using a <code>Customer_invoices</code> mixin:</p>
</div>
<div class="imageblock plantuml">
<div class="content">
<img src="http://www.plantuml.com/plantuml/png/ZP9DQyCm38Rl_XKcby6WPUTIGbaEOx33RcEduTeY4V4Nbf8kZFttcJNfokQjyr5wtbUof1snIZmuApeq8C55dgG3juT4ukepve2xO4W8wj57bPIJsYeY-IPaVhTAzsqAWpTDi25jjmP8rxLi9kNBG8oSym_OTdoN07wX72xG8_g-pAHWOQ6UmTfmA7F4IJ6qKsQVEcGeKohYtm1T0j0p9A_isVUcCZagEy39hCo0P-Jf7wCQ4Guk6B2N9-Rm5VstaRqB4JEdMf3enu0QvjKUrzmCnC51UfcJ94ysPzJzh3mkBdl-bArMjQnkrjVL0c-MUlJLWPvbLEn1pjTJzb-dN669RsIbW-U4-u5paaCbTk1DFlKF" alt="diagram">
</div>
<div class="title">Figure 1. <code>invoices</code> module contributes to <code>customers</code></div>
</div>
<div class="paragraph">
<p>In the UI, when rendering a <code>Customer</code>, we would also be presented with the associated set of <code>Invoice</code>s.</p>
</div>
<div class="paragraph">
<p>We can also use mixins for dependencies that are in the other direction.
For example, suppose we have a mechanism to attach <code>Document</code>s to arbitrary domain objects.
The documents module does not depend on any other modules, but provides a <code>DocumentHolder</code> marker interface.
We can therefore attach documents to a <code>Customer</code> by having <code>Customer</code> implement this marker interface:</p>
</div>
<div class="imageblock plantuml">
<div class="content">
<img src="http://www.plantuml.com/plantuml/png/ZPFBQiCm44Nt-WhXJQ5WqtK88JI5Tj55TwMRbeaqjONrCD8egIdzzuh4TXuuJhISEVEuLz8o47YAHhDAIUHe6cgvGRD67zZTBcQGAYS3Ow5MjW4FXWiD8V1VnjDv156NtaKhLquxFvzB36AnuAiMx3ZGD9JohwgiwDaZNg2Cwg4tPUjnnZkDFVM1MhljE1V80s7P9lQzKeJZ53Hg6WZN06K9lGLz9AyT9pUW8mxDnXcqfAYzmQgDmgrn4lLrnupwKVRCiZ_6ciH1YLmw4KsQsr_kJj0t2EHFNUR5QOcUzzxlgFrpE2M-3gs6gPTX809HzS792juzeBJsnOcvp1SyUoYA-soecnt4JHGMEbMUfcSy4ywIL-j863YvZ4rlVsEJmNGH0pcJFbnd-bxlgeiUwHr2UIpopxC9R8bMfe_y3m00" alt="diagram">
</div>
<div class="title">Figure 2. <code>customers</code> depends upon contributions of <code>documents</code></div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="defining-modules"><a class="anchor" href="#defining-modules"></a>Defining Modules</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In the context of Java applications, modularity is a rather overloaded term.
We have Maven modules, Java 9 modules and we also have Spring <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html"><code>@Configuration</code></a>s, which define a set of domain services.</p>
</div>
<div class="paragraph">
<p>In the context of Apache Isis, a module is actually the last of these, a Spring module.</p>
</div>
<div class="paragraph">
<p>The <a href="../../../../docs/2.0.0-M3/starters/simpleapp.html" class="page">simpleapp starter app</a> provide some structure and illustrates the idioms.
To summarise:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>by convention, we have one <code>@Configuration</code> module per Maven module.</p>
<div class="paragraph">
<p>This is at the root package of the maven module.</p>
</div>
</li>
<li>
<p>all of the domain classes (domain objects and services) are part of that Maven module.</p>
<div class="paragraph">
<p>All are annotated or meta-annotated with Spring&#8217;s <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/stereotype/Component.html"><code>@Component</code></a> annotation, and Spring&#8217;s <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/ComponentScan.html"><code>@ComponentScan</code></a> is used to discover these from the classpath.</p>
</div>
</li>
<li>
<p>Spring&#8217;s <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Import.html"><code>@Import</code></a> is used to express a dependency between each "configuration" module.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>By convention, we have just one Spring module to each Maven module.
This means that the dependencies between Maven modules (using <code>&lt;dependency&gt;</code> are mirrored in the Spring module&#8217;s <code>@Import</code> statements).
We can therefore rely on Maven to ensure there are no cyclic dependencies: the application simply won&#8217;t compile if we introduce a cycle.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Details on how to actually define modules can be found <a href="../modules.html" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If the above convention is too officious,then you could choose to have multiple Spring modules per Maven module, but you will need to watch out for cycles.</p>
</div>
<div class="paragraph">
<p>In such cases (proprietary) tools such as <a href="https://structure101.com/">Structure 101</a> can be used to help detect and visualize such cycles.
Or, (open source) libraries such as <a href="https://www.archunit.org/">ArchUnit</a> or <a href="https://jqassistant.org/">jQAssistant</a> can help enforce architectural layering to prevent the issue arising in the first place.
(These tools can enforce other conventions, too, so are well worth exploring).</p>
</div>
</div>
</div>
</article>
<aside class="article-aside toc" role="navigation">
<p class="toc-title">On this page</p>
<div id="article-toc"></div>
</aside>
</main>
</div>
<footer class="footer">
<div class="content">
<div class="copyright">
<p>
Copyright © 2010~2020 The Apache Software Foundation, licensed under the Apache License, v2.0.
<br/>
Apache, the Apache feather logo, Apache Isis, and the Apache Isis project logo are all trademarks of The Apache Software Foundation.
</p>
</div>
<div class="revision">
<p>Revision: SNAPSHOT</p>
</div>
</div>
</footer>
<script src="../../../../_/js/site.js"></script>
<script async src="../../../../_/js/vendor/highlight.js"></script>
<script src="../../../../_/js/vendor/jquery-3.4.1.min.js"></script>
<script src="../../../../_/js/vendor/jquery-ui-1.12.1.custom.widget-only.min.js"></script>
<script src="../../../../_/js/vendor/jquery.tocify.min.js"></script>
<script>
$(function() {
$("#article-toc").tocify( {
showEffect: "slideDown",
hashGenerator: "pretty",
hideEffect: "slideUp",
selectors: "h2, h3",
scrollTo: 120,
smoothScroll: true,
theme: "jqueryui",
highlightOnScroll: true
} );
});
</script>
</body>
</html>