You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2019/01/06 17:22:54 UTC

[27/51] [partial] isis-site git commit: ISIS-1899: updates site for 1.17.0

http://git-wip-us.apache.org/repos/asf/isis-site/blob/1685fcc5/content/guides/ugfun/ugfun.html
----------------------------------------------------------------------
diff --git a/content/guides/ugfun/ugfun.html b/content/guides/ugfun/ugfun.html
index 8c107e5..8d3b4f2 100644
--- a/content/guides/ugfun/ugfun.html
+++ b/content/guides/ugfun/ugfun.html
@@ -244,7 +244,7 @@ table.CodeRay td.code>pre{padding:0}
        </div> 
       </form> 
      </div> 
-     <p class="nav navbar-text navbar-right small">v1.16.2</p> 
+     <p class="nav navbar-text navbar-right small">v1.17.0</p> 
     </div> 
    </div> 
   </nav> 
@@ -340,7 +340,7 @@ table.CodeRay td.code>pre{padding:0}
        </div> 
        <div class="sectionbody"> 
         <div class="paragraph"> 
-         <p>This introductory chapter should give you a good about what Apache Isis actually <strong>is</strong>: the fundamental ideas and principles that it builds upon, how it compares with other frameworks, what the fundamental building blocks are for actually writing an Isis application, and what services and features the framework provides for you to leverage in your own apps.</p> 
+         <p>This introductory chapter should give you a good about what Apache Isis actually <strong>is</strong>: the fundamental ideas and principles that it builds upon, how it compares with other frameworks, what the fundamental building blocks are for actually writing an Apache Isis application, and what services and features the framework provides for you to leverage in your own apps.</p> 
         </div> 
         <div class="paragraph"> 
          <p>Parts of this chapter have been adapted from Dan Haywood’s 2009 book, 'Domain Driven Design using Naked Objects'. We’ve also added some new insights and made sure the material we’ve used is relevant to Apache Isis.</p> 
@@ -530,7 +530,7 @@ table.CodeRay td.code>pre{padding:0}
                 <p>Reenskaug then goes on to say that "this simple and powerful idea failed because …​ users were used to seeing [objects] from different perspectives. The visible and tangible object would get very complex if it should be able to show itself and be manipulated in many different ways."</p> 
                </div> 
                <div class="paragraph"> 
-                <p>In Apache Isis the responsibility of rendering an object is not the object itself, it is the framework. Rather, the object inspects the object and uses that to decide how to render the object. This is also extensible. In the (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a> the gmap3 wicket extension renders any object with latitude/longitude on a map, while fullcalendar2 renders any object with date(s) on a calendar.</p> 
+                <p>In Apache Isis the responsibility of rendering an object is not the object itself, it is the framework. Rather, the object inspects the object and uses that to decide how to render the object. This is also extensible. In the (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a> the gmap3 wicket extension renders any object with latitude/longitude on a map, while fullcalendar2 renders any object with date(s) on a calendar.</p> 
                </div> </td> 
              </tr> 
             </tbody>
@@ -649,7 +649,7 @@ table.CodeRay td.code>pre{padding:0}
            <p>It’s certainly true that to develop an Apache Isis application you will need to have good object oriented modelling skills. But given that all the mainstream languages for developing business systems are object oriented (Java, C#, Ruby), that’s not such a stretch.</p> 
           </div> 
           <div class="paragraph"> 
-           <p>However, what you’ll also find as you write your applications is that in some ways an Isis application is more aspect-oriented than it is object oriented. Given that aspect-orientation — as a programming paradigm at least — hasn’t caught on, that statement probably needs unpacking a little.</p> 
+           <p>However, what you’ll also find as you write your applications is that in some ways an Apache Isis application is more aspect-oriented than it is object oriented. Given that aspect-orientation — as a programming paradigm at least — hasn’t caught on, that statement probably needs unpacking a little.</p> 
           </div> 
           <div class="sect4"> 
            <h5 id="_aop_concepts">AOP Concepts</h5> 
@@ -672,13 +672,13 @@ table.CodeRay td.code>pre{padding:0}
             <p>Well, a different way to think of the naked objects pattern is that the visualization of a domain object within a UI is a cross-cutting concern. By following certain very standard programming conventions that represent the <em>Apache Isis Programming Model</em> (POJOs plus annotations), the framework is able to build a metamodel and from this can render your domain objects in a standard generic fashion. That’s a rather more interesting cross-cutting concern than boring old logging!</p> 
            </div> 
            <div class="paragraph"> 
-            <p>Apache Isis also draws heavily on the AOP concept of interceptors. Whenever an object is rendered in the UI, it is filtered with respect to the user’s permissions. That is, if a user is not authorized to either view or perhaps modify an object, then this is applied transparently by the framework. The (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s security module, mentioned previously, provides a rich user/role/permissions subdomain to use out of the box; but you can integrate with a different security mechanism if you have one already.</p> 
+            <p>Apache Isis also draws heavily on the AOP concept of interceptors. Whenever an object is rendered in the UI, it is filtered with respect to the user’s permissions. That is, if a user is not authorized to either view or perhaps modify an object, then this is applied transparently by the framework. The (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s security module, mentioned previously, provides a rich user/role/permissions subdomain to use out of the box; but you can integrate with a different security mechanism if you have one already.</p> 
            </div> 
            <div class="paragraph"> 
-            <p>Another example of interceptors are the (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s command and audit modules. The command module captures every user interaction that modifies the state of the system (the "cause" of a change) while the audit module captures every change to every object (the "effect" of a change). Again, this is all transparent to the user.</p> 
+            <p>Another example of interceptors are the (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s command and audit modules. The command module captures every user interaction that modifies the state of the system (the "cause" of a change) while the audit module captures every change to every object (the "effect" of a change). Again, this is all transparent to the user.</p> 
            </div> 
            <div class="paragraph"> 
-            <p>Apache Isis also has an internal event bus (you can switch between an underlying implementation of Gauva or Axon). A domain event is fired whenever an object is interacted with, and this allows any subscribers to influence the operation (or even veto it). This is a key mechanism in ensuring that Isis applications are maintainable, and we discuss it in depth in the section on <a href="../ugbtb/ugbtb.html#_ugbtb_decoupling">Decoupling</a>. But fundamentally its relying on this AOP concept of interceptors.</p> 
+            <p>Apache Isis also has an internal event bus (you can switch between an underlying implementation of Gauva or Axon). A domain event is fired whenever an object is interacted with, and this allows any subscribers to influence the operation (or even veto it). This is a key mechanism in ensuring that Apache Isis applications are maintainable, and we discuss it in depth in the section on <a href="../ugbtb/ugbtb.html#_ugbtb_decoupling">Decoupling</a>. But fundamentally its relying on this AOP concept of interceptors.</p> 
            </div> 
            <div class="paragraph"> 
             <p>Finally, Isis also a feature that is akin to AOP mix-ins. A "contributed action" is one that is implemented on a domain service but that appears to be a behaviour of rendered domain object. In other words, we can dissociate behaviour from data. That’s not always the right thing to do of course. In Richard Pawson’s description of the <a href="../ugfun/ugfun.html#_ugfun_core-concepts_philosophy_naked-objects-pattern">naked objects pattern</a> he talks about "behaviourally rich" objects, in other words where the business functionality encapsulated the data. But on the other hand sometimes the behaviour and data structures change at different rates. The <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">single responsibility principle</a> says we should only lump code together that changes at the same rate. Apache Isis' support for contributions (not only contributed actions, but also contributed properties and contributed collections) enables this
 . And again, to loop back to the topic of this section, it’s an AOP concept that being implemented by the framework.</p> 
@@ -977,10 +977,10 @@ table.CodeRay td.code>pre{padding:0}
            <p>The most obvious difference when developing an Apache Isis application is its deliberate lack of an explicit controller layer; non- <em>CRUD</em> behavior is automatically made available in its generic object-oriented _UI_s. More sophisticated UIs can be built either by <a href="../ugvw/ugvw.html#_ugvw_extending">extending Apache Isis' Wicket viewer</a> or by writing a bespoke UI leveraging the REST (hypermedia) API automatically exposed by <a href="../ugvro/ugvro.html">Isis' Restful Objects viewer</a>. Other frameworks can also be used to implement REST APIs, of course, but generally they require a significant amount of development to get anywhere near the level of sophistication provided automatically by Apache Isis' REST API.</p> 
           </div> 
           <div class="paragraph"> 
-           <p>Although these frameworks all provide their own ecosystems of extensions, Apache Isis' equivalent <a href="http://platform.incode.org" target="_blank">Incode Platform</a> modules (non-ASF) tend to work at a higher-level of abstraction. For example, each of these frameworks will integrate with various security mechanism, but the (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s security module provides a full subdomain of users, roles, features and permissions that can be plugged into any Isis application. Similarly, the <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s command and audit modules in combination provide a support for auditing and traceability that can also be used for out of the box profiling. Again, these addons can be plugged into any Isis app.</p> 
+           <p>Although these frameworks all provide their own ecosystems of extensions, Apache Isis' equivalent <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a> modules (non-ASF) tend to work at a higher-level of abstraction. For example, each of these frameworks will integrate with various security mechanism, but the (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s security module provides a full subdomain of users, roles, features and permissions that can be plugged into any Apache Isis application. Similarly, the <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s command and audit modules in combination provide a support for auditing and traceability that can also be used for out of the box profiling. Again, these addons can be plugged into any Isis app.</p> 
           </div> 
           <div class="paragraph"> 
-           <p>In terms of testing support, each of these other frameworks provide mechanisms to allow the webapp to be tested from within a JUnit test harness. Apache Isis' support is similar. Where Apache Isis differs though is that it enables end-to-end testing without the need for slow and fragile Selenium tests. Instead, Apache Isis provides a "<a href="../ugtst/ugtst.html#_ugtst_integ-test-support_wrapper-factory">WrapperFactory</a>" domain service that allows the generic UI provided to in essence be simulated. On a more pragmatic level, the <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s fakedata module does "what it says on the tin", allowing both unit- and integration-tests to focus on the salient data and fake out the rest.</p> 
+           <p>In terms of testing support, each of these other frameworks provide mechanisms to allow the webapp to be tested from within a JUnit test harness. Apache Isis' support is similar. Where Apache Isis differs though is that it enables end-to-end testing without the need for slow and fragile Selenium tests. Instead, Apache Isis provides a "<a href="../ugtst/ugtst.html#_ugtst_integ-test-support_wrapper-factory">WrapperFactory</a>" domain service that allows the generic UI provided to in essence be simulated. On a more pragmatic level, the <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s fakedata module does "what it says on the tin", allowing both unit- and integration-tests to focus on the salient data and fake out the rest.</p> 
           </div> 
          </div> 
          <div class="sect3"> 
@@ -1054,7 +1054,7 @@ table.CodeRay td.code>pre{padding:0}
            <p>When combined with CQRS we see a command that triggers a business operation, and an event that results from it. So, a <code>PlaceOrderCommand</code> command can result in an <code>OrderPlacedEvent</code> event. A subscriber to this event might then generate a further command to act upon some other system (eg to dispatch the system). Note that the event might be dispatched and consumed in-process or alternatively this might occur out-of-process. If the latter, then the subscriber will operate within a separate transaction, meaning the usual eventual consistency concerns and also compensating actions if a rollback is required. CQRS/event sourcing advocates point out — correctly — that this is just how things are in the "real world" too.</p> 
           </div> 
           <div class="paragraph"> 
-           <p>In Apache Isis every business action (and indeed, property and collection) emits domain events through the <a href="../rgsvc/rgsvc.html#_rgsvc_core-domain-api_EventBusService"><code>EventBusService</code></a>, and can optionally also be published through the <a href="../rgsvc/rgsvc.html#_rgsvc_persistence-layer-spi_PublisherService"><code>PublisherService</code></a>. The former are dispatched and consumed in-process and within the same transaction, and for this reason the <a href="../rgcms/rgcms.html#_rgcms_classes_super_AbstractSubscriber">subscribers</a> can also veto the events. The latter are intended for out-of-process consumption; the (obsolete) <a href="http://github.com/isisaddons-legacy/isis-module-publishing">Isis addons' publishing</a> and the (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s publishmq modules provide implementations for dispatching either through a RDBMS database table, or directly through to an <a href="h
 ttp://camel.apache.org">ActiveMQ</a> message queue (eg wired up to <a href="http://camel.apache.org">Apache Camel</a> event bus).</p> 
+           <p>In Apache Isis every business action (and indeed, property and collection) emits domain events through the <a href="../rgsvc/rgsvc.html#_rgsvc_core-domain-api_EventBusService"><code>EventBusService</code></a>, and can optionally also be published through the <a href="../rgsvc/rgsvc.html#_rgsvc_persistence-layer-spi_PublisherService"><code>PublisherService</code></a>. The former are dispatched and consumed in-process and within the same transaction, and for this reason the <a href="../rgcms/rgcms.html#_rgcms_classes_super_AbstractSubscriber">subscribers</a> can also veto the events. The latter are intended for out-of-process consumption; the (obsolete) <a href="http://github.com/isisaddons-legacy/isis-module-publishing">Isis addons' publishing</a> and the (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s publishmq modules provide implementations for dispatching either through a RDBMS database table, or directly through t
 o an <a href="http://camel.apache.org">ActiveMQ</a> message queue (eg wired up to <a href="http://camel.apache.org">Apache Camel</a> event bus).</p> 
           </div> 
          </div> 
          <div class="sect3"> 
@@ -1076,7 +1076,7 @@ table.CodeRay td.code>pre{padding:0}
            <p>However, there is a difference in philosophy in that MW is not a full-stack framework and does not (in their words) try to "own the UI". Rather they support a huge variety of UI technologies and allow the domain object to be rendered in any of them.</p> 
           </div> 
           <div class="paragraph"> 
-           <p>In contrast, Apache Isis is full-stack and does generate a complete UI; we then allow you to customize or extend this UI (as per the various (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a> modules), and we also provide a full REST API through the <a href="../ugvro/ugvro.html">Restful Objects viewer</a></p> 
+           <p>In contrast, Apache Isis is full-stack and does generate a complete UI; we then allow you to customize or extend this UI (as per the various (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a> modules), and we also provide a full REST API through the <a href="../ugvro/ugvro.html">Restful Objects viewer</a></p> 
           </div> 
           <div class="paragraph"> 
            <p>Also, it’s worth noting that MetaWidget does have an elegant pipeline architecture, with APIs to allow even its metamodel to be replaced. It would be feasible and probably quite straightforward to use Apache Isis' own metamodel as an implementation of the MetaWidget API. This would allow MetaWidget to be able to render an Apache Isis domain application.</p> 
@@ -1110,7 +1110,7 @@ table.CodeRay td.code>pre{padding:0}
            <p>Apache Wicket, and therefore Apache Isis in this configuration, is a stateful architecture. As a platform it is certainly capable of supporting user bases of several thousand (with perhaps one or two hundred concurrent); however it isn’t an architecture that you should try to scale up to tens of thousands of concurrent users.</p> 
           </div> 
           <div class="paragraph"> 
-           <p>The UI generated by the Wicket viewer is well suited to many line-of-business apps, but it’s also worth knowing that (with a little knowledge of the Wicket APIs) it relatively straightforward to extend. As described in <a href="../ugfun/ugfun.html#_ugfun_available-domain-services_isis-addons">Isis addons</a> chapter, the viewer already has integrations with the (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s gmap3, fullcalendar2 and excel Wicket components. We are also aware of integrations with SVG images (for floor maps of shopping center) and of custom widgets displaying a catalogue (text and images) of medical diseases.</p> 
+           <p>The UI generated by the Wicket viewer is well suited to many line-of-business apps, but it’s also worth knowing that (with a little knowledge of the Wicket APIs) it relatively straightforward to extend. As described in <a href="../ugfun/ugfun.html#_ugfun_available-domain-services_isis-addons">Isis addons</a> chapter, the viewer already has integrations with the (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s gmap3, fullcalendar2 and excel Wicket components. We are also aware of integrations with SVG images (for floor maps of shopping center) and of custom widgets displaying a catalogue (text and images) of medical diseases.</p> 
           </div> 
           <div class="paragraph"> 
            <p>Deploying on Apache Isis means that the framework also manages object persistence. For many line-of-business applications this will mean using a relational database. It is also possible (courtesy of its integratinon with <a href="http://www.datanucleus.org">DataNucleus</a>) to deploy an Isis app to a NoSQL store such as Neo4J or MongoDB; and it is also possible to deploy to cloud platforms such as <a href="https://cloud.google.com/appengine/docs">Google App Engine (GAE)</a>.</p> 
@@ -1397,7 +1397,7 @@ table.CodeRay td.code>pre{padding:0}
             </div> 
            </div> 
            <div class="paragraph"> 
-            <p>The (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a> provide SPI implementations of the common cross-cutting concerns. They also provide a number of APIs for domain objects to invoke (not shown in the diagram). You can also write your own domain services as well, for example to interface with some external CMS system, say.</p> 
+            <p>The (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a> provide SPI implementations of the common cross-cutting concerns. They also provide a number of APIs for domain objects to invoke (not shown in the diagram). You can also write your own domain services as well, for example to interface with some external CMS system, say.</p> 
            </div> 
           </div> 
          </div> 
@@ -2035,7 +2035,7 @@ table.CodeRay td.code>pre{padding:0}
            <p>This can be particularly useful for <a href="../ugfun/ugfun.html#_ugfun_programming-model_view-models_jaxb">JAXB-style view models</a> which are used as DTOs and so must have no dependencies on the rest of the Apache Isis framework.</p> 
           </div> 
           <div class="paragraph"> 
-           <p>It can also be more generally useful to allow one module to influence/fine-tune the title of entities provided by some other module. The obvious use case is when reusing library modules, eg as provided by (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>.</p> 
+           <p>It can also be more generally useful to allow one module to influence/fine-tune the title of entities provided by some other module. The obvious use case is when reusing library modules, eg as provided by (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>.</p> 
           </div> 
          </div> 
          <div class="sect3"> 
@@ -2107,7 +2107,7 @@ table.CodeRay td.code>pre{padding:0}
           <p>We tend to use Maven modules as a way to group related domain objects together; we can then reason about all the classes in that module as a single unit. By convention there will be a single top-level package corresponding to the module.</p> 
          </div> 
          <div class="paragraph"> 
-          <p>For example, the (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s document module has a top-level package of <code>org.incode.module.document</code>. Within the module there may be various subpackages, but it’s the module that defines the namespace.</p> 
+          <p>For example, the (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s document module has a top-level package of <code>org.incode.module.document</code>. Within the module there may be various subpackages, but it’s the module that defines the namespace.</p> 
          </div> 
          <div class="paragraph"> 
           <p>The bootstrapping of Apache Isis also relies on module classes. (Currently) the only role of these classes is to identify a fully qualified package name, for example <code>org.incode.modules.document</code>. The framework then performs classpath scanning across all such packages to locate any domain entities provided by that module (though some modules have no entities), all domain services provided by the module (every module is likely to define at least one), and also any fixture scripts provided by the module.</p> 
@@ -2187,7 +2187,7 @@ table.CodeRay td.code>pre{padding:0}
            <pre class="CodeRay highlight"><code data-lang="bash">mvn archetype:generate  \
     -D archetypeGroupId=org.apache.isis.archetype \
     -D archetypeArtifactId=helloworld-archetype \
-    -D archetypeVersion=1.16.2 \
+    -D archetypeVersion=1.17.0 \
     -D groupId=com.mycompany \
     -D artifactId=myapp \
     -D version=1.0-SNAPSHOT \
@@ -2218,22 +2218,23 @@ table.CodeRay td.code>pre{padding:0}
          </div> 
          <div class="listingblock"> 
           <div class="content"> 
-           <pre>domainapp/
-├── application/
-│   ├── HelloWorldAppManifest.java
-│   └── isis.properties
-├── dom/
-│   ├── HelloWorldModule.java
-│   └── impl/
-│       ├── HelloWorldObject.java
-│       ├── HelloWorldObject.layout.xml
-│       ├── HelloWorldObject.png
-│       └── HelloWorldObjects.java
-└── app/
-    ├── HelloWorldApplication.java
-    └── welcome.html
-META-INF/
-└── persistence.xml</pre> 
+           <pre>src/
+└── main/
+    └── java/
+        ├── domainapp/
+        │   ├── application/
+        │   │   ├── HelloWorldAppManifest.java
+        │   │   ├── isis-non-changing.properties
+        │   │   └── menubars.layout.xml
+        │   └── dom/
+        │       ├── HelloWorldModule.java
+        │       └── impl/
+        │           ├── HelloWorldObject.java
+        │           ├── HelloWorldObject.layout.xml
+        │           ├── HelloWorldObject.png
+        │           └── HelloWorldObjects.java
+        └── META-INF/
+            └── persistence.xml</pre> 
           </div> 
          </div> 
          <div class="paragraph"> 
@@ -2266,7 +2267,8 @@ META-INF/
            <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">HelloWorldAppManifest</span> <span class="directive">extends</span> AppManifestAbstract {
     <span class="directive">public</span> <span class="directive">static</span> <span class="directive">final</span> Builder BUILDER = Builder
             .forModules(HelloWorldModule.class)
-            .withConfigurationPropertiesFile(HelloWorldAppManifest.class, <span class="string"><span class="delimiter">"</span><span class="content">isis.properties</span><span class="delimiter">"</span></span>)
+            .withConfigurationPropertiesFile(
+                HelloWorldAppManifest.class, <span class="string"><span class="delimiter">"</span><span class="content">isis-non-changing.properties</span><span class="delimiter">"</span></span>)
             .withAuthMechanism(<span class="string"><span class="delimiter">"</span><span class="content">shiro</span><span class="delimiter">"</span></span>);
 
     <span class="directive">public</span> HelloWorldAppManifest() {
@@ -2276,7 +2278,7 @@ META-INF/
           </div> 
          </div> 
          <div class="paragraph"> 
-          <p>Rather than implement <code>AppManifest</code> directly, <code>HelloWorldAppManifest</code> uses the builder provided by the convenience <code>AppManifestAbstract</code>); as you’ll find when you work on bigger applications, it’s common to have variations around the app manifest, so the builder makes it easy to create these variations without lots of boilerplate.</p> 
+          <p>Rather than implement <code>AppManifest</code> directly, <code>HelloWorldAppManifest</code> uses the builder provided by the convenience <code>AppManifestAbstract2</code>); as you’ll find when you work on bigger applications, it’s common to have variations around the app manifest, so the builder makes it easy to create these variations without lots of boilerplate.</p> 
          </div> 
          <div class="paragraph"> 
           <p>For now, we see that (using the builder) the app manifest defines three things:</p> 
@@ -2284,12 +2286,12 @@ META-INF/
          <div class="ulist"> 
           <ul> 
            <li> <p>a list of modules - there’s just one, <code>HelloWorldModule</code> for this class</p> </li> 
-           <li> <p>the location of a configuration file, <code>isis.properties</code>, read in as a resource from the classpath</p> </li> 
+           <li> <p>the location of a configuration file, <code>isis-non-changing.properties</code>, read in as a resource from the classpath</p> </li> 
            <li> <p>specifying an authentication/authorisation mechanism, in this case Apache Shiro integration.</p> </li> 
           </ul> 
          </div> 
          <div class="paragraph"> 
-          <p>In Apache Isis a module is simply an empty class, which is used simply to obtain a package name. The framework uses classpath scanning to find certain classes; rather than scan the entire classpath it limits its search to the package(s) obtained from the modules.</p> 
+          <p>In Apache Isis a module has various responsibilities, but the most important is simply its location. The framework uses classpath scanning to find certain classes; rather than scan the entire classpath it limits its search to the package(s) of the application’s module(s).</p> 
          </div> 
          <div class="paragraph"> 
           <p>The packages are scanned to identify three types of classes:</p> 
@@ -2320,10 +2322,10 @@ META-INF/
           </ul> 
          </div> 
          <div class="paragraph"> 
-          <p>The app manifest also identifies the <code>isis.properties</code> file (in the same package as <code>HelloWorldAppManifest</code>) as containing various configuration options. The helloworld application uses these for settings that are unlikely to change and so are loaded as a static resource from the classpath.</p> 
+          <p>The app manifest also identifies the <code>isis-non-changing.properties</code> file (in the same package as <code>HelloWorldAppManifest</code>) as containing various configuration options. The helloworld application uses these for settings that are unlikely to change and so are loaded as a static resource from the classpath.</p> 
          </div> 
          <div class="paragraph"> 
-          <p>You’ll find that there’s another file called <code>isis.properties</code> that’s in <code>WEB-INF/isis.properties</code>. This also provides configuration options (the framework simply combines them) but those in <code>WEB-INF/isis.properties</code> are restricted to settings that are likely to change from environment to environment, most notably JDBC URL connection strings. Separating these out makes it easy to reconfigure the application to run against different databases in different environments (dev, test, production etc).</p> 
+          <p>You’ll find that there’s also a similar file called <code>isis.properties</code>, which resides at <code>WEB-INF/isis.properties</code>. This also provides configuration options (the framework simply combines them) but those in <code>WEB-INF/isis.properties</code> are restricted to settings that are likely to change from environment to environment, most notably JDBC URL connection strings. Separating these out makes it easy to reconfigure the application to run against different databases in different environments (dev, test, production etc).</p> 
          </div> 
          <div class="paragraph"> 
           <p>Finally, the app manifest identifies Apache Shiro for authentication and authorisation. Shiro in turn is configured using the <code>WEB-INF/shiro.ini</code> file.</p> 
@@ -2342,6 +2344,9 @@ META-INF/
           </table> 
          </div> 
          <div class="paragraph"> 
+          <p>The <code>menubars.layout.xml</code> file also resides in the same package as the manifest; this defines the menubar structure.</p> 
+         </div> 
+         <div class="paragraph"> 
           <p>In the <code>domainapp.dom</code> module ("dom" stands for "domain object model") is the <code>HelloWorldModule</code>:</p> 
          </div> 
          <div class="listingblock"> 
@@ -2369,9 +2374,8 @@ META-INF/
                </div> </li> 
               <li> <p>is also annotated with Isis' own <code>@DomainObject</code>.</p> 
                <div class="paragraph"> 
-                <p>This isn’t mandatory, but since entities are the real building blocks on which Isis applications are built, it’s very common to use this annotation.</p> 
+                <p>This isn’t mandatory, but since entities are the real building blocks on which Apache Isis applications are built, it’s very common to use this annotation.</p> 
                </div> </li> 
-              <li> <p>also uses various Project Lombok annotations to remove boilerplate.</p> </li> 
              </ul> 
             </div> </li> 
            <li> <p><code>HelloWorldObject.layout.xml</code> defines the layout of the members (properties and actions) of the <code>HelloWorldObject</code>.</p> 
@@ -2398,52 +2402,49 @@ META-INF/
 <span class="tag">&lt;/persistence&gt;</span></code></pre> 
           </div> 
          </div> 
-         <div class="paragraph"> 
-          <p>Finally, in the <code>domainapp.webapp</code> we have <code>HelloWorldApplication</code>. This is required to bootstrap the Wicket viewer (it is configured in <code>WEB-INF/web.xml</code>). Internally it uses Google Guice to configure various static resources served up by Wicket:</p> 
-         </div> 
-         <div class="listingblock"> 
-          <div class="content"> 
-           <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">HelloWorldApplication</span> <span class="directive">extends</span> IsisWicketApplication {
-    ...
-    protected Module newIsisWicketModule() {
-        <span class="directive">final</span> Module isisDefaults = <span class="local-variable">super</span>.newIsisWicketModule();
-        <span class="directive">final</span> Module overrides = <span class="keyword">new</span> AbstractModule() {
-            <span class="annotation">@Override</span>
-            <span class="directive">protected</span> <span class="type">void</span> configure() {
-                ...
-            }
-        };
-        <span class="keyword">return</span> Modules.override(isisDefaults).with(overrides);
-    }
-}</code></pre> 
-          </div> 
-         </div> 
-         <div class="paragraph"> 
-          <p>The <code>configure()</code> method is the place to change the name of the application for example, or to change the initial about and welcome messages. The text of the welcome page shown by the Wicket viewer can be found in <code>welcome.html</code>, loaded from the classpath and in the same package as <code>HelloWorldApplication</code>.</p> 
+         <div class="admonitionblock note"> 
+          <table> 
+           <tbody>
+            <tr> 
+             <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> 
+             <td class="content"> 
+              <div class="paragraph"> 
+               <p>In previous versions of Apache Isis the simple app defined its own subclass of <code>IsisWicketApplication</code> in <code>src/main/java</code>. This is generally no longer required because configuration properties now exist that can be set instead.</p> 
+              </div> </td> 
+            </tr> 
+           </tbody>
+          </table> 
          </div> 
          <div class="paragraph"> 
           <p>Under <code>src/main/webapp</code> we have various resources that are used to configure the webapp, or that are served up by the running webapp:</p> 
          </div> 
          <div class="listingblock"> 
           <div class="content"> 
-           <pre>about/
-└── index.html
-css/
-└── application.css
-scripts/
-└── application.js
-swagger-ui/
-WEB-INF/
-├── isis.properties
-├── logging.properties
-├── shiro.ini
-└── web.xml</pre> 
+           <pre>src/
+└── main/
+    ├── webapp/
+    └── welcome.html
+        ├── about/
+        │   └── index.html
+        ├── css/
+        │   └── application.css
+        ├── scripts/
+        │   └── application.js
+        ├── swagger-ui/
+        └── WEB-INF/
+            ├── isis.properties
+            ├── logging.properties
+            ├── shiro.ini
+            └── web.xml</pre> 
           </div> 
          </div> 
          <div class="paragraph"> 
           <p>Most important of these is <code>WEB-INF/web.xml</code>, which bootstraps both the Wicket viewer and the Restful Objects viewer (the REST API derived from the domain object model).</p> 
          </div> 
          <div class="paragraph"> 
+          <p>The text of the welcome page shown by the Wicket viewer can be found in <code>welcome.html</code>. This is shown in the absence of a home page action/view model.</p> 
+         </div> 
+         <div class="paragraph"> 
           <p>The <code>about/index.html</code> is the page shown at the root of the package, providing links to either the Wicket viewer or to the Swagger UI. In a production application this is usually replaced with a page that does an HTTP 302 redirect to the Wicket viewer.</p> 
          </div> 
          <div class="paragraph"> 
@@ -2477,11 +2478,14 @@ WEB-INF/
          </div> 
          <div class="listingblock"> 
           <div class="content"> 
-           <pre>domainapp/
-└── dom/
-    └── impl/
-        ├── HelloWorldObjectTest_delete.java
-        └── HelloWorldObjectTest_updateName.java</pre> 
+           <pre>src/
+└── test/
+    └── java/
+        └── domainapp/
+            └── dom/
+                └── impl/
+                    ├── HelloWorldObjectTest_delete.java
+                    └── HelloWorldObjectTest_updateName.java</pre> 
           </div> 
          </div> 
          <div class="paragraph"> 
@@ -2847,7 +2851,7 @@ mvn clean install</code></pre>
            <pre class="CodeRay highlight"><code data-lang="bash">mvn archetype:generate  \
     -D archetypeGroupId=org.apache.isis.archetype \
     -D archetypeArtifactId=simpleapp-archetype \
-    -D archetypeVersion=1.16.2 \
+    -D archetypeVersion=1.17.0 \
     -D groupId=com.mycompany \
     -D artifactId=myapp \
     -D version=1.0-SNAPSHOT \
@@ -2946,170 +2950,230 @@ mvn clean install</code></pre>
           </div> 
           <div class="listingblock"> 
            <div class="content"> 
-            <pre>domainapp/
-└── application/
-    ├── DomainAppApplicationModule.java
-    ├── fixture/
-    │   ├── DomainAppFixtureScriptsSpecificationProvider.java
-    │   └── scenarios/
-    │       └── DomainAppDemo.java
-    ├── manifest/
-    │   ├── DomainAppAppManifest.java
-    │   ├── DomainAppAppManifestBypassSecurity.java
-    │   ├── DomainAppAppManifestWithFixtures.java
-    │   ├── DomainAppAppManifestWithFixturesBypassSecurity.java
-    │   └── menubars.layout.xml
-    └── services
-        └── homepage
-            ├── HomePageService.java
-            ├── HomePageViewModel.java
-            ├── HomePageViewModel.layout.xml
-            └── HomePageViewModel.layout.png</pre> 
-           </div> 
-          </div> 
-          <div class="paragraph"> 
-           <p>There are also supporting files in this package in <code>src/main/resources</code>:</p> 
-          </div> 
-          <div class="listingblock"> 
-           <div class="content"> 
-            <pre>domainapp/
-└── application/
-    └── manifest/
-        ├── authentication_shiro.properties
-        ├── isis.properties
-        ├── persistor_datanucleus.properties
-        ├── viewer_restfulobjects.properties
-        └── viewer_wicket.properties</pre> 
+            <pre>src/
+└── main/
+    └── java/
+        └── domainapp/
+            └── application/
+                ├── DomainAppApplicationModule.java
+                ├── fixture/
+                │   ├── DomainAppFixtureScriptsSpecificationProvider.java
+                │   └── scenarios/
+                │       └── DomainAppDemo.java
+                ├── manifest/
+                │   ├── DomainAppAppManifest.java
+                │   ├── DomainAppAppManifestBypassSecurity.java
+                │   ├── DomainAppAppManifestWithFixtures.java
+                │   ├── DomainAppAppManifestWithFixturesBypassSecurity.java
+                │   ├── isis-non-changing.properties
+                │   └── menubars.layout.xml
+                └── services
+                    ├── healthcheck
+                    │   └── HealthCheckServiceImpl.java
+                    └── homepage
+                        ├── HomePageService.java
+                        ├── HomePageViewModel.java
+                        ├── HomePageViewModel.layout.xml
+                        └── HomePageViewModel.layout.png</pre> 
            </div> 
           </div> 
-          <div class="paragraph"> 
-           <p>The <code>DomainAppAppManifest</code> is the key class here, typically being used to bootstrap the application. It is quite short:</p> 
-          </div> 
-          <div class="listingblock"> 
-           <div class="content"> 
-            <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">DomainAppAppManifest</span> <span class="directive">extends</span> AppManifestAbstract2 {
+          <div class="sect4"> 
+           <h5 id="_manifest">Manifest</h5> 
+           <div class="paragraph"> 
+            <p>The <code>DomainAppAppManifest</code> is the most important class here, typically being used to bootstrap the application. It is quite short:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">DomainAppAppManifest</span> <span class="directive">extends</span> AppManifestAbstract2 {
 
     <span class="directive">public</span> <span class="directive">static</span> <span class="directive">final</span> Builder BUILDER = Builder
             .forModule(<span class="keyword">new</span> DomainAppApplicationModule())
-            .withConfigurationPropertiesFile(DomainAppAppManifest.class,
-                    <span class="string"><span class="delimiter">"</span><span class="content">isis.properties</span><span class="delimiter">"</span></span>,
-                    <span class="string"><span class="delimiter">"</span><span class="content">authentication_shiro.properties</span><span class="delimiter">"</span></span>,
-                    <span class="string"><span class="delimiter">"</span><span class="content">persistor_datanucleus.properties</span><span class="delimiter">"</span></span>,
-                    <span class="string"><span class="delimiter">"</span><span class="content">viewer_restfulobjects.properties</span><span class="delimiter">"</span></span>,
-                    <span class="string"><span class="delimiter">"</span><span class="content">viewer_wicket.properties</span><span class="delimiter">"</span></span>)
+            .withConfigurationPropertiesFile(
+                    DomainAppAppManifest.class, <span class="string"><span class="delimiter">"</span><span class="content">isis-non-changing.properties</span><span class="delimiter">"</span></span>)
             .withAuthMechanism(<span class="string"><span class="delimiter">"</span><span class="content">shiro</span><span class="delimiter">"</span></span>);
 
     <span class="directive">public</span> DomainAppAppManifest() {
         <span class="local-variable">super</span>(BUILDER);
     }
 }</code></pre> 
+            </div> 
            </div> 
-          </div> 
-          <div class="paragraph"> 
-           <p>The manifest uses the builder defined by <code>AppManifestAbstract2</code> and references a single top-level (Isis) module, namely <code>DomainAppApplicationModule</code>:</p> 
-          </div> 
-          <div class="listingblock"> 
-           <div class="content"> 
-            <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">DomainAppApplicationModule</span> <span class="directive">extends</span> ModuleAbstract {
+           <div class="paragraph"> 
+            <p>Rather than implement <code>AppManifest</code> directly, <code>DomainAppAppManifest</code> uses the builder provided by the convenience <code>AppManifestAbstract2</code>), to define three things:</p> 
+           </div> 
+           <div class="ulist"> 
+            <ul> 
+             <li> <p>a list of modules - there’s just one, <code>DomainAppApplicationModule</code></p> </li> 
+             <li> <p>the location of a configuration file, <code>isis-non-changing.properties</code>, read in as a resource from the classpath</p> </li> 
+             <li> <p>specifying an authentication/authorisation mechanism, in this case Apache Shiro integration.</p> </li> 
+            </ul> 
+           </div> 
+           <div class="paragraph"> 
+            <p>The manifest uses the builder defined by <code>AppManifestAbstract2</code> and references a single top-level (Isis) module, namely <code>DomainAppApplicationModule</code>:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">DomainAppApplicationModule</span> <span class="directive">extends</span> ModuleAbstract {
     <span class="annotation">@Override</span>
     <span class="directive">public</span> <span class="predefined-type">Set</span>&lt;Module&gt; getDependencies() {
         <span class="keyword">return</span> Sets.&lt;Module&gt;newHashSet(<span class="keyword">new</span> SimpleModule());
     }
 }</code></pre> 
+            </div> 
+           </div> 
+           <div class="paragraph"> 
+            <p>where <code>SimpleModule</code> in defined in the <code>mypp-module-simple</code> module (below).</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>The primary purpose of the module class is to identify packages and subpackages that the framework should scan for entities and domain services. The transitive dependencies between modules are automatically resolved. The net effect is that all the domain services and entities in this module as well as those modules referenced are included into the app.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>Going back to the manifest, it also defines the <code>isis-non-changing.properties</code> configuration properties, loaded as a static resource from the classpath.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>You’ll find that there’s also a similar file called <code>isis.properties</code>, which resides at <code>WEB-INF/isis.properties</code>. This also provides configuration options (the framework simply combines them) but those in <code>WEB-INF/isis.properties</code> are restricted to settings that are likely to change from environment to environment, most notably JDBC URL connection strings. Separating these out makes it easy to reconfigure the application to run against different databases in different environments (dev, test, production etc).</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>Finally, the app manifest identifies Apache Shiro for authentication and authorisation. Shiro in turn is configured using the <code>WEB-INF/shiro.ini</code> file.</p> 
+           </div> 
+           <div class="admonitionblock tip"> 
+            <table> 
+             <tbody>
+              <tr> 
+               <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> 
+               <td class="content"> 
+                <div class="paragraph"> 
+                 <p>The security integration provided by Apache Isis and Shiro is quite sophisticated; to get started though you can just login using username: <code>sven</code>, password: <code>pass</code>.</p> 
+                </div> </td> 
+              </tr> 
+             </tbody>
+            </table> 
+           </div> 
+           <div class="paragraph"> 
+            <p>The <code>menubars.layout.xml</code> file also resides in the same package as the manifest; this defines the menubar structure.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>There are also several variations on the app manifest; these can be used to bootstrap the application with fixtures, or disabling security.</p> 
            </div> 
           </div> 
-          <div class="paragraph"> 
-           <p>where <code>SimpleModule</code> in defined in the <code>mypp-module-simple</code> module (below).</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>The primary purpose of the module class is to identify packages and subpackages that the framework should scan for entities and domain services. The transitive dependencies between modules are automatically resolved. The net effect is that all the domain services and entities in this module as well as those modules referenced are included into the app.</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>Going back to the manifest, it also defines a number of static configuration files, all loaded from the classpath. Each file contains configuration setting for a different part of the runtime (<code>isis.properties</code> for the core framework, shiro for security, datanucleus for the objectstore, and the two viewers).</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>The <code>menubars.layout.xml</code> file also resides in the same package as the manifest; this defines the menubar structure.</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>There are also several variations on the app manifest; these can be used to bootstrap the application with fixtures, or disabling security.</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>The <code>domainapp.application.services</code> package contains the <code>HomePageService</code> domain service. This simply has a single action annotated with <code>@HomePage</code>:</p> 
-          </div> 
-          <div class="listingblock"> 
-           <div class="content"> 
-            <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Action</span>(semantics = SemanticsOf.SAFE)
+          <div class="sect4"> 
+           <h5 id="_domain_services">Domain Services</h5> 
+           <div class="paragraph"> 
+            <p>The <code>domainapp.application.services</code> package contains two SPI implementations.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>The <code>HomePageService</code> domain service simply has a single action annotated with <code>@HomePage</code>:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@Action</span>(semantics = SemanticsOf.SAFE)
 <span class="annotation">@HomePage</span>
 <span class="directive">public</span> HomePageViewModel homePage() {
     <span class="keyword">return</span> factoryService.instantiate(HomePageViewModel.class);
 }</code></pre> 
+            </div> 
            </div> 
-          </div> 
-          <div class="paragraph"> 
-           <p>which returns the <code>HomePageViewModel</code> for use as the home page. The <code>HomePageViewModel</code> itself just renders a collection of <code>SimpleObject</code>s in a list (<code>HomePageViewModel.layout.xml</code> defines the UI layout).</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>The final package in the application module is <code>domainapp.application.fixture</code>. The important class here is <code>DomainAppDemo</code>, a fixture script that can be used to setup the application with some dummy data. This is used in the app itself when running in prototype mode (against an in-memory database), and can also be used by integration tests.</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>There is in fact also a domain service defined here, namely <code>DomainAppFixtureScriptsSpecificationProvider</code>. This is just used to configure the run fixture script menu item shown on the "Prototyping" menu.</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>The module also defines a number of BDD specs and integration tests, in <code>src/test/java</code>. The BDD specs (run using Cucumber) reside under <code>domain.application.bdd</code>:</p> 
-          </div> 
-          <div class="listingblock"> 
-           <div class="content"> 
-            <pre>domainapp/
-└── application/
-    └── bdd/
-        ├── specglue/
-        │   ├── BootstrappingGlue.java
-        │   └── CatalogOfFixturesGlue.java
-        └── specs/
-            ├── RunIntegBddSpecs.java
-            └── SimpleObjectSpec_listAllAndCreate.feature</pre> 
+           <div class="paragraph"> 
+            <p>which returns the <code>HomePageViewModel</code> for use as the home page. The <code>HomePageViewModel</code> itself just renders a collection of <code>SimpleObject</code>s in a list (<code>HomePageViewModel.layout.xml</code> defines the UI layout).</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>The other SPI implementation is the <code>HealthCheckServiceImpl</code> domain service, which is used to indicate if the application is running healthily. This is exposed as the <code>/restful/health</code> REST endpoint. The implementation itself simply runs a query on the <code>SimpleObjects</code> repository service, thus checking that the database is configured correctly and available.</p> 
            </div> 
           </div> 
-          <div class="paragraph"> 
-           <p>Here the <code>BootstrappingGlue</code> glue class inherits from the framework’s <code>HeadlessWithBootstrappingAbstract</code> class, and bootstraps using the <code>DomainAppApplicationModule</code> mentioned above.</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>There is just one feature file: <code>SimpleObjectSpec_listAllAndCreate.feature</code>, which is pretty simple:</p> 
-          </div> 
-          <div class="listingblock"> 
-           <div class="content"> 
-            <pre class="CodeRay highlight"><code data-lang="feature">@DomainAppDemo
+          <div class="sect4"> 
+           <h5 id="_fixtures">Fixtures</h5> 
+           <div class="paragraph"> 
+            <p>The final package in the application module is <code>domainapp.application.fixture</code>. The important class here is <code>DomainAppDemo</code>, a fixture script that can be used to setup the application with some dummy data. This is used in the app itself when running in prototype mode (against an in-memory database), and can also be used by integration tests.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>There is in fact also a domain service defined here, namely <code>DomainAppFixtureScriptsSpecificationProvider</code>. This is just used to configure the run fixture script menu item shown on the "Prototyping" menu.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>The module also defines a number of BDD specs and integration tests, in <code>src/test/java</code>. The BDD specs (run using Cucumber) reside under <code>domain.application.bdd</code>:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre>src/
+└── test/
+    └── java/
+        └── domainapp/
+            └── application/
+                └── bdd/
+                    ├── specglue/
+                    │   ├── BootstrappingGlue.java
+                    │   └── CatalogOfFixturesGlue.java
+                    └── specs/
+                        ├── RunIntegBddSpecs.java
+                        └── SimpleObjectSpec_listAllAndCreate.feature</pre> 
+            </div> 
+           </div> 
+           <div class="paragraph"> 
+            <p>Here the <code>BootstrappingGlue</code> glue class inherits from the framework’s <code>HeadlessWithBootstrappingAbstract</code> class, and bootstraps using the <code>DomainAppApplicationModule</code> mentioned above.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>There is just one feature file: <code>SimpleObjectSpec_listAllAndCreate.feature</code>, which is pretty simple:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre class="CodeRay highlight"><code data-lang="feature">@DomainAppDemo
 Feature: List and Create New Simple Objects
 
   Scenario: Existing simple objects can be listed and new ones created
     Given there are initially 10 simple objects
     When  I create a new simple object
     Then  there are 11 simple objects</code></pre> 
+            </div> 
            </div> 
-          </div> 
-          <div class="paragraph"> 
-           <p>The <code>@DomainAppDemo</code> annotation causes the <code>DomainAppDemo</code> fixture script to be run; this is the purpose of the <code>CatalogOfFixturesGlue</code> glue class.</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>The specs themselves are run by the <code>RunIntegBddSpecs.java</code> class, which specifies which packages to search for "glue". This is just standard Cucumber bootstrapping.</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>The integration tests meanwhile are in <code>domainapp.application.integtests</code>:</p> 
-          </div> 
-          <div class="listingblock"> 
-           <div class="content"> 
-            <pre>domainapp/
-└── application/
-    └── integtests/
-        ├── DomainAppIntegTestAbstract.java
-        └── Smoke_IntegTest.java</pre> 
+           <div class="paragraph"> 
+            <p>The <code>@DomainAppDemo</code> annotation causes the <code>DomainAppDemo</code> fixture script to be run; this is the purpose of the <code>CatalogOfFixturesGlue</code> glue class.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>The specs themselves are run by the <code>RunIntegBddSpecs.java</code> class, which specifies which packages to search for "glue". This is just standard Cucumber bootstrapping.</p> 
+           </div> 
+           <div class="paragraph"> 
+            <p>The integration tests meanwhile are in <code>domainapp.application.integtests</code>:</p> 
+           </div> 
+           <div class="listingblock"> 
+            <div class="content"> 
+             <pre>src/
+└── test/
+    └── java/
+        └── domainapp/
+            └── application/
+                └── integtests/
+                    ├── DomainAppIntegTestAbstract.java
+                    ├── mml/
+                    │   ├── approved/
+                    │   ├── received/
+                    │   └── MetaModelService_IntegTest.java
+                    └── smoke/
+                        └── Smoke_IntegTest.java</pre> 
+            </div> 
+           </div> 
+           <div class="paragraph"> 
+            <p>There are two different sets of tests.</p> 
+           </div> 
+           <div class="ulist"> 
+            <ul> 
+             <li> <p>The <code>Smoke_IntegTest</code> performs a number of high-level smoke tests, to check that the core functionality works correctly.</p> 
+              <div class="paragraph"> 
+               <p>This test inherits <code>DomainAppIntegTestAbstract</code>, which in turn inherits from <code>IntegrationTestAbstract3</code> and uses the <code>DomainAppApplicationModule</code> previously discussed.</p> 
+              </div> 
+              <div class="paragraph"> 
+               <p>Moreover, the <code>Smoke_IntegTest</code> uses the same <code>DomainAppDemo</code> fixture script. The application and the smoke tests therefore run with the exact same state, making debugging easy.</p> 
+              </div> </li> 
+             <li> <p>The <code>MetaModelService_IntegTest</code> demonstrates how to use approval tests to verify that the metamodel is unchanged between releases of Apache Isis.</p> 
+              <div class="paragraph"> 
+               <p>By default this test does nothing; it is activated by setting system properties ("lockdown.learn" or "lockdown.verify"). When in "learn" mode, the test calls the <code>MetaModelService</code> to export an XML representation of the internal metamodel. These can then be moved from the <code>received</code> directory to the <code>approved</code> directory, as "known-to-good".</p> 
+              </div> 
+              <div class="paragraph"> 
+               <p>Then, if Apache Isis is updated, then the "verify" test can be called to check that the metamodel created by the new version of the framework is the same as the previous version.</p> 
+              </div> </li> 
+            </ul> 
+           </div> 
+           <div class="paragraph"> 
+            <p>With regard to the naming of these various BDD specs and integration tests, they follow the naming convention required by the (non-ASF) <a href="http://github.com/danhaywood/java-mavenmixin-surefire">"surefire" mavenmixin</a> that configures the maven surefire plugin.</p> 
            </div> 
-          </div> 
-          <div class="paragraph"> 
-           <p>The <code>Smoke_IntegTest</code> inherits <code>DomainAppIntegTestAbstract</code>, which in turn inherits from <code>IntegrationTestAbstract3</code> and uses the <code>DomainAppApplicationModule</code> previously discussed. Moreover, the <code>Smoke_IntegTest</code> uses the same <code>DomainAppDemo</code> fixture script. The application and the smoke tests therefore run with the exact same state, making debugging easy.</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>With regard to the naming of these various BDD specs and integration tests, they follow the naming convention required by the (non-ASF) <a href="http://github.com/danhaywood/java-mavenmixin-surefire">"surefire" mavenmixin</a> that configures the maven surefire plugin.</p> 
           </div> 
          </div> 
          <div class="sect3"> 
@@ -3138,23 +3202,26 @@ Feature: List and Create New Simple Objects
           </div> 
           <div class="listingblock"> 
            <div class="content"> 
-            <pre>domainapp/
-└── modules/
-    └── simple/
-        ├── SimpleModule.java
-        ├── SimpleModuleManifest.java
-        ├── dom/
-        │   └── impl/
-        │       ├── SimpleObject.java
-        │       ├── SimpleObject.layout.xml
-        │       ├── SimpleObject.png
-        │       ├── SimpleObjectMenu.java
-        │       └── SimpleObjectRepository.java
-        └── fixture/
-            ├── SimpleObject_persona.java
-            └── SimpleObjectBuilder.java
-META-INF/
-└── persistence.xml</pre> 
+            <pre>src/
+└── main/
+    └── java/
+        ├── domainapp/
+        │   └── modules/
+        │       └── simple/
+        │           ├── SimpleModule.java
+        │           ├── SimpleModuleManifest.java
+        │           ├── dom/
+        │           │   └── impl/
+        │           │       ├── SimpleObject.java
+        │           │       ├── SimpleObject.layout.xml
+        │           │       ├── SimpleObject.png
+        │           │       ├── SimpleObjectMenu.java
+        │           │       └── SimpleObjectRepository.java
+        │           └── fixture/
+        │               ├── SimpleObject_persona.java
+        │               └── SimpleObjectBuilder.java
+        └── META-INF/
+            └── persistence.xml</pre> 
            </div> 
           </div> 
           <div class="paragraph"> 
@@ -3193,20 +3260,23 @@ META-INF/
           </div> 
           <div class="listingblock"> 
            <div class="content"> 
-            <pre>domainapp/
-└── modules/
-    └── simple/
-        ├── dom/
-        │   └── impl/
-        │       ├── SimpleObject_Test.java
-        │       └── SimpleObjectRepository_Test.java
-        └── integtests/
-            ├── SimpleModuleIntegTestAbstract.java
-            │   └── tests/
-            │       ├── SimpleObject_IntegTest.java
-            │       └── SimpleObjectMenu_IntegTest.java
-            └── specglue/
-                └── SimpleObjectMenuGlue.java</pre> 
+            <pre>src/
+└── test/
+    └── java/
+        └── domainapp/
+            └── modules/
+                └── simple/
+                    ├── dom/
+                    │   └── impl/
+                    │       ├── SimpleObject_Test.java
+                    │       └── SimpleObjectRepository_Test.java
+                    └── integtests/
+                        ├── SimpleModuleIntegTestAbstract.java
+                        │   └── tests/
+                        │       ├── SimpleObject_IntegTest.java
+                        │       └── SimpleObjectMenu_IntegTest.java
+                        └── specglue/
+                            └── SimpleObjectMenuGlue.java</pre> 
            </div> 
           </div> 
           <div class="paragraph"> 
@@ -3222,60 +3292,45 @@ META-INF/
          <div class="sect3"> 
           <h4 id="_myapp_webapp">5.2.4. myapp-webapp</h4> 
           <div class="paragraph"> 
-           <p>Finally, in the <code>myapp-webapp</code> module we have the classes and configuration to package and bootstrap the application as a webapp.</p> 
-          </div> 
-          <div class="paragraph"> 
-           <p>Under <code>src/main/java</code> there is:</p> 
-          </div> 
-          <div class="listingblock"> 
-           <div class="content"> 
-            <pre>domainapp/
-└── webapp/
-    ├── DomainApplication.java
-    └── welcome.html</pre> 
-           </div> 
-          </div> 
-          <div class="paragraph"> 
-           <p>The <code>DomainApplication</code> is required to bootstrap the Wicket viewer (it is configured in <code>WEB-INF/web.xml</code>, discussed below). Within <code>DomainApplication</code> is the bootstrapping of the Wicket viewer. Internally it uses Google Guice to configure various static resources served up by Wicket:</p> 
-          </div> 
-          <div class="listingblock"> 
-           <div class="content"> 
-            <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">DomainApplication</span> <span class="directive">extends</span> IsisWicketApplication {
-
-    <span class="directive">protected</span> Module newIsisWicketModule() {
-        <span class="directive">final</span> Module isisDefaults = <span class="local-variable">super</span>.newIsisWicketModule();
-        <span class="directive">final</span> Module overrides = <span class="keyword">new</span> AbstractModule() {
-            <span class="annotation">@Override</span>
-            <span class="directive">protected</span> <span class="type">void</span> configure() {
-                ...
-            }
-        };
-        <span class="keyword">return</span> Modules.override(isisDefaults).with(overrides);
-    }
-}</code></pre> 
-           </div> 
+           <p>Finally, in the <code>myapp-webapp</code> module we have the configuration to package and bootstrap the application as a webapp.</p> 
           </div> 
-          <div class="paragraph"> 
-           <p>The <code>configure()</code> method is the place to change the name of the application for example, or to change the initial about and welcome messages. The text of the welcome page shown by the Wicket viewer can be found in <code>welcome.html</code>, loaded from the classpath and in the same package as <code>DomainApplication</code>.</p> 
+          <div class="admonitionblock note"> 
+           <table> 
+            <tbody>
+             <tr> 
+              <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> 
+              <td class="content"> 
+               <div class="paragraph"> 
+                <p>In previous versions of Apache Isis the simple app defined its own subclass of <code>IsisWicketApplication</code> in <code>src/main/java</code>. This is generally no longer required because configuration properties now exist that can be set instead.</p> 
+               </div> </td> 
+             </tr> 
+            </tbody>
+           </table> 
           </div> 
           <div class="paragraph"> 
            <p>Under <code>src/main/webapp</code> we have various resources that are used to configure the webapp, or that are served up by the running webapp:</p> 
           </div> 
           <div class="listingblock"> 
            <div class="content"> 
-            <pre>about/
-└── index.html
-css/
-└── application.css
-scripts/
-└── application.js
-swagger-ui/
-WEB-INF/
-├── isis.properties
-├── logging.properties
-├── shiro.ini
-├── translations.po
-└── web.xml</pre> 
+            <pre>src/
+└── main/
+    └── webapp/
+        └── src/
+            └── main/
+                └── webapp/
+                    ├── about/
+                    │   └── index.html
+                    ├── css/
+                    │   └── application.css
+                    ├── scripts/
+                    │   └── application.js
+                    ├── swagger-ui/
+                    └── WEB-INF/
+                        ├── isis.properties
+                        ├── logging.properties
+                        ├── shiro.ini
+                        ├── translations.po
+                        └── web.xml</pre> 
            </div> 
           </div> 
           <div class="paragraph"> 
@@ -3293,7 +3348,7 @@ WEB-INF/
     <span class="tag">&lt;filter-class&gt;</span>org.apache.wicket.protocol.http.WicketFilter<span class="tag">&lt;/filter-class&gt;</span>
     <span class="tag">&lt;init-param&gt;</span>
       <span class="tag">&lt;param-name&gt;</span>applicationClassName<span class="tag">&lt;/param-name&gt;</span>
-      <span class="tag">&lt;param-value&gt;</span>domainapp.webapp.DomainApplication<span class="tag">&lt;/param-value&gt;</span>
+      <span class="tag">&lt;param-value&gt;</span>org.apache.isis.viewer.wicket.viewer.IsisWicketApplication<span class="tag">&lt;/param-value&gt;</span>
     <span class="tag">&lt;/init-param&gt;</span>
   <span class="tag">&lt;/filter&gt;</span>
   ...
@@ -3354,6 +3409,32 @@ WEB-INF/
            </ul> 
           </div> 
           <div class="paragraph"> 
+           <p>Under <code>src/main/resources</code> there is:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="content"> 
+            <pre>src/
+└── main/
+    └── resources/
+        └── docker/
+            └── Dockerfile</pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
+           <p>As you might expect, this is used to create a Docker image. The <code>Dockerfile</code> is very simple; the built webapp is deployed as the ROOT.war into Apache Tomcat:</p> 
+          </div> 
+          <div class="listingblock"> 
+           <div class="title">
+            Dockerfile
+           </div> 
+           <div class="content"> 
+            <pre class="CodeRay highlight"><code data-lang="Dockerfile">FROM incodehq/tomcat
+RUN rm -rf ${DEPLOYMENT_DIR}/ROOT
+COPY ${docker-plugin.resource.include} ${DEPLOYMENT_DIR}/ROOT.war
+EXPOSE 8080</code></pre> 
+           </div> 
+          </div> 
+          <div class="paragraph"> 
            <p>Now you know your way around the code generated by the archetype, lets see how to build the app and run it.</p> 
           </div> 
          </div> 
@@ -4178,7 +4259,7 @@ RepositoryService repositoryService;</code></pre>
               <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> 
               <td class="content"> 
                <div class="paragraph"> 
-                <p>Annotating action parameters with <a href="../rgant/rgant.html#_rgant-ParameterLayout_named"><code>@ParameterLayout#named()</code></a> can become somewhat tiresome. You can avoid doing this by configuring the (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s paraname8 metamodel extension.</p> 
+                <p>Annotating action parameters with <a href="../rgant/rgant.html#_rgant-ParameterLayout_named"><code>@ParameterLayout#named()</code></a> can become somewhat tiresome. You can avoid doing this by configuring the (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s paraname8 metamodel extension.</p> 
                </div> </td> 
              </tr> 
             </tbody>
@@ -5135,7 +5216,7 @@ AddressService addressService;
               <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> 
               <td class="content"> 
                <div class="paragraph"> 
-                <p>The (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s paraname8 metamodel extension allows the parameter name to be used in the UI, rather than the type.</p> 
+                <p>The (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s paraname8 metamodel extension allows the parameter name to be used in the UI, rather than the type.</p> 
                </div> </td> 
              </tr> 
             </tbody>
@@ -6461,7 +6542,7 @@ public <span class="type">class</span> <span class="class">ToDoItemV1_1</span> <
             </table> 
            </div> 
            <div class="paragraph"> 
-            <p>The (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s publishmq module provides an out-of-the-box solution of this design. It provides an implementation of the <a href="../rgsvc/rgsvc.html#_rgsvc_persistence-layer-spi_PublishingService"><code>PublishingService</code></a>, but which simply publishes instances of <a href="../rgcms/rgcms.html#_rgcms_schema-aim"><code>ActionInvocationMemento</code></a> to an ActiveMQ queue. Camel (or similar) can then be hooked up to consume these events from this queue, and use a processor to parse the action memento to determine what has changed on the source system. Thereafter, a subsequent Camel processor can then call back to the source - via the <a href="../ugvro/ugvro.html">Restful Objects viewer</a> - to enrich the message with additional details using a DTO.</p> 
+            <p>The (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s publishmq module provides an out-of-the-box solution of this design. It provides an implementation of the <a href="../rgsvc/rgsvc.html#_rgsvc_persistence-layer-spi_PublishingService"><code>PublishingService</code></a>, but which simply publishes instances of <a href="../rgcms/rgcms.html#_rgcms_schema-aim"><code>ActionInvocationMemento</code></a> to an ActiveMQ queue. Camel (or similar) can then be hooked up to consume these events from this queue, and use a processor to parse the action memento to determine what has changed on the source system. Thereafter, a subsequent Camel processor can then call back to the source - via the <a href="../ugvro/ugvro.html">Restful Objects viewer</a> - to enrich the message with additional details using a DTO.</p> 
            </div> 
           </div> 
          </div> 
@@ -7778,7 +7859,10 @@ public <span class="type">class</span> <span class="class">ToDoItemV1_1</span> <
              <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> 
              <td class="content"> 
               <div class="paragraph"> 
-               <p>If you’re running on Java 8, then note that it’s possible to write Isis applications without using <code>@ParameterLayout(named=…​)</code> annotation. Support for this can be found in the (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a>'s paraname8 metamodel extension (non-ASF). (In the future we’ll fold this into core). See also our guidance on <a href="../../migration-notes/migration-notes.html#_migration-notes_1.8.0-to-1.9.0_upgrading-to-java8">upgrading to Java 8</a>.</p> 
+               <p>If you’re running on Java 8, then note that it’s possible to write Isis applications without using <code>@ParameterLayout(named=…​)</code> annotation. Support for this can be found in the (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a>'s paraname8 metamodel extension (non-ASF). (In the future we’ll fold this into core).</p> 
+              </div> 
+              <div class="paragraph"> 
+               <p>See also our guidance on <a href="../../migration-notes/migration-notes.html#_migration-notes_1.8.0-to-1.9.0_upgrading-to-java8">upgrading to Java 8</a>.</p> 
               </div> </td> 
             </tr> 
            </tbody>
@@ -8605,7 +8689,7 @@ repositoryService.remove(customer);</code></pre>
          </div> 
         </div> 
         <div class="sect2"> 
-         <h3 id="__globally_defined_drop_downs">10.3. "Globally" defined drop-downs</h3> 
+         <h3 id="_globally_defined_drop_downs">10.3. "Globally" defined drop-downs</h3> 
          <div class="paragraph"> 
           <p>Very often the set of available choices depends on the data type of the property/action parameter, rather than the individual property/parameter itself. And similarly the algorithm to search for references again may well depend only on that reference type.</p> 
          </div> 
@@ -8912,7 +8996,7 @@ repositoryService.remove(customer);</code></pre>
           </ul>
          </div> 
          <div class="paragraph"> 
-          <p>The (non-ASF) <a href="http://platform.incode.org" target="_blank">Incode Platform</a> provides a number of reusable modules for Apache Isis, focusing either on specific technologies, technical cross-cutting concerns, or providing business logic for generic subdomains. Some of these modules implement SPIs defined by the framework.</p> 
+          <p>The (non-ASF) <a href="http://platform.incode.org" target="_blank" rel="noopener">Incode Platform</a> provides a number of reusable modules for Apache Isis, focusing either on specific technologies, technical cross-cutting concerns, or providing business logic for generic subdomains. Some of these modules implement SPIs defined by the framework.</p> 
          </div> 
          <div class="admonitionblock warning"> 
           <table>