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 2015/08/07 12:11:37 UTC

[10/17] isis git commit: ISIS-848: sorting out GlobSpecs with integration tests

ISIS-848: sorting out GlobSpecs with integration tests

- updated the simpleapp:
  - bootstrapping of IntegTests (simplified)
  - isis.properties file
  - example DomainAppGlobSpecs
- RegisterEntities checks if GlobSpec is in use, and if so then only logs as debug a message if can't find any @PersistenceCapable's in any given package (ie not an error condition)
- cleaned up IsisSystemForTest so that the components created by IsisComponentProvider are used subsequently for installing fixtures and looking up services (rather than it using its own local copy which might be invalid if a globspec was provided)
- fixes to IsisComponentProviderDefault to ensure that RegisterEntities doesn't throw exception if a globSpec was provided, also to handle fixture overrides correctly otherwise


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/34912499
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/34912499
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/34912499

Branch: refs/heads/master
Commit: 34912499af7dd75aa4dc269af8a4239b3e62a196
Parents: 306002e
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Thu Aug 6 15:27:00 2015 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Thu Aug 6 15:27:00 2015 +0100

----------------------------------------------------------------------
 .../java/org/apache/isis/applib/GlobSpec.java   |  3 +-
 .../IsisComponentProviderDefault.java           | 24 +++++-
 .../integtestsupport/IsisSystemForTest.java     | 90 ++++++++++++--------
 .../IsisComponentProvider.java                  |  6 +-
 .../IsisComponentProviderAbstract.java          | 32 ++++---
 .../IsisComponentProviderUsingInstallers.java   | 15 ++--
 .../jdo/service/RegisterEntities.java           | 26 ++++--
 .../java/domainapp/glob/DomainAppGlobSpec.java  | 43 ++++++++--
 .../domainapp/glob/DomainAppGlobSpecBypass.java | 35 ++++++++
 .../glob/DomainAppGlobSpecNoFixtures.java       | 36 ++++++++
 .../bootstrap/SimpleAppSystemInitializer.java   | 29 ++-----
 .../src/main/webapp/WEB-INF/isis.properties     | 66 ++------------
 12 files changed, 245 insertions(+), 160 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/core/applib/src/main/java/org/apache/isis/applib/GlobSpec.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/GlobSpec.java b/core/applib/src/main/java/org/apache/isis/applib/GlobSpec.java
index c3939e3..ef245e2 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/GlobSpec.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/GlobSpec.java
@@ -112,7 +112,8 @@ public interface GlobSpec {
     public List<Class<?>> getModules();
 
     /**
-     * If non-null, overrides the value of <tt>isis.authentication</tt> configuration property.
+     * If non-null, overrides the value of <tt>isis.authentication</tt> configuration property to specify the
+     * authentication mechanism.
      *
      * <p>
      *     Ignored for integration tests (which always uses the 'bypass' mechanism).

http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisComponentProviderDefault.java
----------------------------------------------------------------------
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisComponentProviderDefault.java b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisComponentProviderDefault.java
index 36420c7..8fc168d 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisComponentProviderDefault.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisComponentProviderDefault.java
@@ -27,6 +27,8 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
 import org.apache.isis.applib.GlobSpec;
+import org.apache.isis.applib.fixtures.InstallableFixture;
+import org.apache.isis.applib.fixturescripts.FixtureScript;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.config.IsisConfigurationDefault;
 import org.apache.isis.core.commons.resource.ResourceStreamSourceContextLoaderClassPath;
@@ -68,6 +70,7 @@ public class IsisComponentProviderDefault extends IsisComponentProviderAbstract
             final DeploymentType deploymentType,
             final GlobSpec globSpecIfAny,
             final List<Object> servicesOverride,
+            final List<InstallableFixture> fixturesOverride,
             final IsisConfiguration configurationOverride,
             final ProgrammingModel programmingModelOverride,
             final MetaModelValidator metaModelValidatorOverride) {
@@ -75,19 +78,32 @@ public class IsisComponentProviderDefault extends IsisComponentProviderAbstract
 
         this.configuration = elseDefault(configurationOverride);
 
+        final String fixtureClassNamesCsv;
         if(globSpec != null) {
 
             specifyServicesAndRegisteredEntitiesUsing(globSpec);
 
-            specifyFixtureScriptsUsing(globSpec);
+            // required to prevent RegisterEntities validation from complaining
+            // if it can't find any @PersistenceCapable entities in a module
+            // that contains only services.
+            putConfigurationProperty(
+                    "isis.globSpec", globSpecIfAny.getClass().getName()
+            );
+
+            List<Class<? extends FixtureScript>> fixtureClasses = globSpec.getFixtures();
+            fixtureClassNamesCsv = fixtureClassNamesFrom(fixtureClasses);
+
             overrideConfigurationUsing(globSpec);
 
             this.services = createServices(configuration);
 
         } else {
+            fixtureClassNamesCsv = fixtureClassNamesFrom(fixturesOverride);
+
             this.services = elseDefault(servicesOverride, configuration);
         }
 
+        putConfigurationProperty(FixturesInstallerFromConfiguration.FIXTURES, fixtureClassNamesCsv);
         this.fixturesInstaller = createFixturesInstaller(configuration);
 
         // integration tests ignore globSpec for authentication and authorization.
@@ -99,6 +115,8 @@ public class IsisComponentProviderDefault extends IsisComponentProviderAbstract
 
     }
 
+
+
     //region > globSpec
 
     private List<Object> createServices(
@@ -205,7 +223,7 @@ public class IsisComponentProviderDefault extends IsisComponentProviderAbstract
     }
 
     @Override
-    public FixturesInstaller provideFixturesInstaller() throws IsisSystemException {
+    public FixturesInstaller provideFixturesInstaller()  {
         return fixturesInstaller;
     }
 
@@ -241,7 +259,7 @@ public class IsisComponentProviderDefault extends IsisComponentProviderAbstract
     public PersistenceSessionFactory providePersistenceSessionFactory(
             DeploymentType deploymentType,
             final ServicesInjectorSpi servicesInjectorSpi,
-            final RuntimeContextFromSession runtimeContext) throws IsisSystemException {
+            final RuntimeContextFromSession runtimeContext) {
         DataNucleusPersistenceMechanismInstaller installer = new DataNucleusPersistenceMechanismInstaller();
         return installer.createPersistenceSessionFactory(deploymentType, servicesInjectorSpi, getConfiguration(), runtimeContext);
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
----------------------------------------------------------------------
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
index c3a38a8..673f509 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
@@ -49,10 +49,12 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
 import org.apache.isis.core.runtime.authentication.AuthenticationManager;
 import org.apache.isis.core.runtime.authentication.AuthenticationRequest;
+import org.apache.isis.core.runtime.fixtures.FixturesInstaller;
 import org.apache.isis.core.runtime.fixtures.FixturesInstallerDelegate;
 import org.apache.isis.core.runtime.installerregistry.installerapi.PersistenceMechanismInstaller;
 import org.apache.isis.core.runtime.logging.IsisLoggingConfigurer;
 import org.apache.isis.core.runtime.services.ServicesInstaller;
+import org.apache.isis.core.runtime.services.ServicesInstallerFromAnnotation;
 import org.apache.isis.core.runtime.services.ServicesInstallerFromConfigurationAndAnnotation;
 import org.apache.isis.core.runtime.system.DeploymentType;
 import org.apache.isis.core.runtime.system.IsisSystem;
@@ -147,25 +149,27 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
 
     // //////////////////////////////////////
 
+    private org.apache.log4j.Level level = org.apache.log4j.Level.INFO;
+
+
+    // these fields 'xxxForComponentProvider' are used to initialize the IsisComponentProvider, but shouldn't be used thereafter.
+    private final GlobSpec globSpecForComponentProvider;
+    private final IsisConfiguration configurationForComponentProvider;
+    private final List<Object> servicesForComponentProvider;
+    private final List<InstallableFixture> fixturesForComponentProvider;
+    private final MetaModelValidator metaModelValidatorForComponentProvider;
+    private final ProgrammingModel programmingModelForComponentProvider;
+
+    // populated at #setupSystem
+    private IsisComponentProvider componentProvider;
 
     private IsisSystem isisSystem;
+
+    private final AuthenticationRequest authenticationRequestIfAny;
     private AuthenticationSession authenticationSession;
 
-    private final GlobSpec globSpecIfAny;
-    private final IsisConfiguration configurationOverride;
-    private final AuthenticationRequest authenticationRequest;
-    private final List<Object> servicesIfAny;
-    private final List<InstallableFixture> fixtures;
     private List <Listener> listeners;
-    
-    private org.apache.log4j.Level level = org.apache.log4j.Level.INFO;
-    
-    private final MetaModelValidator metaModelValidatorOverride;
-    private final ProgrammingModel programmingModelOverride;
-    
-    private DomainObjectContainer container;
 
-    
     ////////////////////////////////////////////////////////////
     // constructor
     ////////////////////////////////////////////////////////////
@@ -174,7 +178,9 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
 
         private AuthenticationRequest authenticationRequest = new AuthenticationRequestNameOnly("tester");
         
-        private IsisConfigurationDefault configuration;
+        private IsisConfigurationDefault configuration = new IsisConfigurationDefault();
+        private final IsisConfigurationDefault configurationAsPerGlobSpec = new IsisConfigurationDefault();
+
         private GlobSpec globSpecIfAny;
 
         private MetaModelValidator metaModelValidatorOverride;
@@ -229,7 +235,7 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
             }
 
             configuration.put(
-                    "isis.services.ServicesInstallerFromAnnotation.packagePrefix",
+                    ServicesInstallerFromAnnotation.PACKAGE_PREFIX_KEY,
                     Joiner.on(",").join(packagePrefixes)
             );
 
@@ -255,6 +261,9 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
          */
         @Deprecated
         public Builder withFixtures(InstallableFixture... fixtures) {
+            if(globSpecIfAny != null) {
+                throw new IllegalStateException("A globSpec has already been provided");
+            }
             this.fixtures.addAll(Arrays.asList(fixtures));
             return this;
         }
@@ -331,13 +340,13 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
             final List<Object> servicesIfAny,
             final List<InstallableFixture> fixtures,
             final List<Listener> listeners) {
-        this.globSpecIfAny = globSpecIfAny;
-        this.configurationOverride = configurationOverride;
-        this.programmingModelOverride = programmingModelOverride;
-        this.metaModelValidatorOverride = metaModelValidatorOverride;
-        this.authenticationRequest = authenticationRequest;
-        this.servicesIfAny = servicesIfAny;
-        this.fixtures = fixtures;
+        this.globSpecForComponentProvider = globSpecIfAny;
+        this.configurationForComponentProvider = configurationOverride;
+        this.programmingModelForComponentProvider = programmingModelOverride;
+        this.metaModelValidatorForComponentProvider = metaModelValidatorOverride;
+        this.authenticationRequestIfAny = authenticationRequest;
+        this.servicesForComponentProvider = servicesIfAny;
+        this.fixturesForComponentProvider = fixtures;
         this.listeners = listeners;
     }
 
@@ -382,19 +391,21 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
         
         if(firstTime) {
             IsisLoggingConfigurer isisLoggingConfigurer = new IsisLoggingConfigurer(getLevel());
-            isisLoggingConfigurer.configureLogging(".", new String[]{});
+            isisLoggingConfigurer.configureLogging(".", new String[] {});
 
-            IsisComponentProvider componentProvider = new IsisComponentProviderDefault(
+            componentProvider = new IsisComponentProviderDefault(
                     DeploymentType.UNIT_TESTING,
-                    globSpecIfAny,
-                    servicesIfAny,
-                    this.configurationOverride,
-                    this.programmingModelOverride,
-                    this.metaModelValidatorOverride
+                    globSpecForComponentProvider,
+                    servicesForComponentProvider,
+                    fixturesForComponentProvider,
+                    configurationForComponentProvider,
+                    programmingModelForComponentProvider,
+                    metaModelValidatorForComponentProvider
             );
 
             isisSystem = new IsisSystem(componentProvider);
 
+
             // ensures that a FixtureClock is installed as the singleton underpinning the ClockService
             FixtureClock.initialize();
 
@@ -403,7 +414,7 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
         }
 
         final AuthenticationManager authenticationManager = isisSystem.getSessionFactory().getAuthenticationManager();
-        authenticationSession = authenticationManager.authenticate(authenticationRequest);
+        authenticationSession = authenticationManager.authenticate(authenticationRequestIfAny);
 
         setContainer(getContainer());
 
@@ -417,9 +428,8 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
 
 
     private void wireAndInstallFixtures() {
-        FixturesInstallerDelegate fid = new FixturesInstallerDelegate(getPersistenceSession());
-        fid.addFixture(fixtures);
-        fid.installFixtures();
+        FixturesInstaller fixturesInstaller = componentProvider.provideFixturesInstaller();
+        fixturesInstaller.installFixtures();
     }
 
     private enum FireListeners {
@@ -431,7 +441,7 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
     }
 
     public DomainObjectContainer getContainer() {
-        for (Object service : servicesIfAny) {
+        for (Object service : isisSystem.getSessionFactory().getServices()) {
             if(service instanceof DomainObjectContainer) {
                 return (DomainObjectContainer) service;
             }
@@ -487,7 +497,7 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
     private void fireInitAndPreSetupSystem(boolean firstTime) throws Exception {
         if(firstTime) {
             for(Listener listener: listeners) {
-                listener.init(configurationOverride);
+                listener.init(componentProvider.getConfiguration());
             }
         }
         for(Listener listener: listeners) {
@@ -799,7 +809,10 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
     // (for each test, rather than at bootstrap)
     ////////////////////////////////////////////////////////////
 
-    
+    /**
+     * @deprecated - use {@link org.apache.isis.applib.fixturescripts.FixtureScripts} domain service instead.
+     */
+    @Deprecated
     public void installFixtures(final InstallableFixture... fixtures) {
         final FixturesInstallerDelegate fid = new FixturesInstallerDelegate(getPersistenceSession());
         for (InstallableFixture fixture : fixtures) {
@@ -845,9 +858,12 @@ public class IsisSystemForTest implements org.junit.rules.TestRule, DomainServic
 
     /**
      * @param container the container to set
+     *
+     * @deprecated
      */
+    @Deprecated
     public void setContainer(DomainObjectContainer container) {
-        this.container = container;
+        // no-op
     }
 
     

http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
index de394b5..6699119 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
@@ -43,12 +43,12 @@ public interface IsisComponentProvider {
 
     IsisConfiguration getConfiguration();
 
-    AuthenticationManager provideAuthenticationManager(DeploymentType deploymentType) throws IsisSystemException;
+    AuthenticationManager provideAuthenticationManager(DeploymentType deploymentType);
     AuthorizationManager provideAuthorizationManager(final DeploymentType deploymentType);
 
     List<Object> provideServices();
 
-    FixturesInstaller provideFixturesInstaller() throws IsisSystemException;
+    FixturesInstaller provideFixturesInstaller();
 
     SpecificationLoaderSpi provideSpecificationLoaderSpi(Collection<MetaModelRefiner> metaModelRefiners)
             throws IsisSystemException;
@@ -56,6 +56,6 @@ public interface IsisComponentProvider {
     PersistenceSessionFactory providePersistenceSessionFactory(
             final DeploymentType deploymentType,
             final ServicesInjectorSpi servicesInjectorSpi,
-            final RuntimeContextFromSession runtimeContext) throws IsisSystemException;
+            final RuntimeContextFromSession runtimeContext);
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderAbstract.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderAbstract.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderAbstract.java
index 0d57f61..9db01cc 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderAbstract.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderAbstract.java
@@ -22,20 +22,20 @@ package org.apache.isis.core.runtime.systemusinginstallers;
 import java.util.List;
 import java.util.Map;
 
+import javax.annotation.Nullable;
+
+import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.collect.Iterables;
 
 import org.apache.isis.applib.GlobSpec;
-import org.apache.isis.applib.fixturescripts.FixtureScript;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.lang.ClassUtil;
 import org.apache.isis.core.runtime.authentication.AuthenticationManager;
 import org.apache.isis.core.runtime.authorization.AuthorizationManager;
 import org.apache.isis.core.runtime.fixtures.FixturesInstaller;
-import org.apache.isis.core.runtime.fixtures.FixturesInstallerFromConfiguration;
 import org.apache.isis.core.runtime.services.ServicesInstallerFromAnnotation;
 import org.apache.isis.core.runtime.system.DeploymentType;
-import org.apache.isis.core.runtime.system.IsisSystemException;
 import org.apache.isis.objectstore.jdo.service.RegisterEntities;
 
 import static org.apache.isis.core.commons.ensure.Ensure.ensureThatState;
@@ -111,18 +111,22 @@ public abstract class IsisComponentProviderAbstract implements IsisComponentProv
         return Joiner.on(',').join(iter);
     }
 
-    protected void specifyFixtureScriptsUsing(final GlobSpec globSpec) {
-        List<Class<? extends FixtureScript>> fixtureClasses = globSpec.getFixtures();
-        final String fixtureClassNamesCsv = fixtureClassNamesFrom(fixtureClasses);
-        putConfigurationProperty(FixturesInstallerFromConfiguration.FIXTURES, fixtureClassNamesCsv);
-    }
-
-    private String fixtureClassNamesFrom(final List<Class<? extends FixtureScript>> fixtureClasses) {
-        if (fixtureClasses == null) {
+    protected String fixtureClassNamesFrom(final List<?> fixtures) {
+        if (fixtures == null) {
             return null;
         }
-        final Iterable<String> iter = Iterables.transform(fixtureClasses, ClassUtil.Functions.nameOf());
-        return Joiner.on(',').join(iter);
+        final Iterable<String> fixtureClassNames = Iterables.transform(fixtures, classNameOf());
+        return Joiner.on(',').join(fixtureClassNames);
+    }
+
+    private Function<Object, String> classNameOf() {
+        return new Function<Object, String>() {
+                        @Nullable @Override
+                        public String apply(final Object input) {
+                            Class<?> aClass = input instanceof Class ? (Class<?>)input: input.getClass();
+                            return aClass.getName();
+                        }
+                    };
     }
 
     protected void overrideConfigurationUsing(final GlobSpec globSpec) {
@@ -172,7 +176,7 @@ public abstract class IsisComponentProviderAbstract implements IsisComponentProv
     }
 
     @Override
-    public FixturesInstaller provideFixturesInstaller() throws IsisSystemException {
+    public FixturesInstaller provideFixturesInstaller() {
         return fixturesInstaller;
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderUsingInstallers.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderUsingInstallers.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderUsingInstallers.java
index 3d9261a..fc9ef58 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderUsingInstallers.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderUsingInstallers.java
@@ -20,8 +20,10 @@
 package org.apache.isis.core.runtime.systemusinginstallers;
 
 import java.util.Collection;
+import java.util.List;
 
 import org.apache.isis.applib.GlobSpec;
+import org.apache.isis.applib.fixturescripts.FixtureScript;
 import org.apache.isis.core.commons.factory.InstanceUtil;
 import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
 import org.apache.isis.core.metamodel.services.ServicesInjectorSpi;
@@ -29,13 +31,13 @@ import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
 import org.apache.isis.core.metamodel.specloader.ObjectReflectorInstaller;
 import org.apache.isis.core.runtime.authentication.AuthenticationManagerInstaller;
 import org.apache.isis.core.runtime.authorization.AuthorizationManagerInstaller;
+import org.apache.isis.core.runtime.fixtures.FixturesInstallerFromConfiguration;
 import org.apache.isis.core.runtime.installerregistry.InstallerLookup;
 import org.apache.isis.core.runtime.installerregistry.installerapi.PersistenceMechanismInstaller;
 import org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession;
 import org.apache.isis.core.runtime.services.ServicesInstaller;
 import org.apache.isis.core.runtime.services.ServicesInstallerFromAnnotation;
 import org.apache.isis.core.runtime.system.DeploymentType;
-import org.apache.isis.core.runtime.system.IsisSystemException;
 import org.apache.isis.core.runtime.system.SystemConstants;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
 import org.apache.isis.core.runtime.transaction.facetdecorator.standard.TransactionFacetDecoratorInstaller;
@@ -53,7 +55,6 @@ public class IsisComponentProviderUsingInstallers extends IsisComponentProviderA
     private ObjectReflectorInstaller reflectorInstaller;
     private PersistenceMechanismInstaller persistenceMechanismInstaller;
 
-
     public IsisComponentProviderUsingInstallers(
             final DeploymentType deploymentType,
             final InstallerLookup installerLookup) {
@@ -78,7 +79,9 @@ public class IsisComponentProviderUsingInstallers extends IsisComponentProviderA
             final String authorizationMechanism = globSpec.getAuthorizationMechanism();
             putConfigurationProperty(SystemConstants.AUTHORIZATION_INSTALLER_KEY, authorizationMechanism);
 
-            specifyFixtureScriptsUsing(globSpec);
+            List<Class<? extends FixtureScript>> fixtureClasses = globSpec.getFixtures();
+            final String fixtureClassNamesCsv = fixtureClassNamesFrom(fixtureClasses);
+            putConfigurationProperty(FixturesInstallerFromConfiguration.FIXTURES, fixtureClassNamesCsv);
 
             overrideConfigurationUsing(globSpec);
         }
@@ -133,8 +136,6 @@ public class IsisComponentProviderUsingInstallers extends IsisComponentProviderA
         configuration = this.installerLookup.getConfiguration();
 
         // eagerly calculate
-
-
         authenticationManager = authenticationInstaller.createAuthenticationManager();
         authorizationManager = authorizationInstaller.createAuthorizationManager();
         services = servicesInstaller.getServices();
@@ -156,7 +157,7 @@ public class IsisComponentProviderUsingInstallers extends IsisComponentProviderA
 
     @Override
     public SpecificationLoaderSpi provideSpecificationLoaderSpi(
-            final Collection<MetaModelRefiner> metaModelRefiners) throws IsisSystemException {
+            final Collection<MetaModelRefiner> metaModelRefiners) {
         return reflectorInstaller.createReflector(metaModelRefiners);
     }
 
@@ -165,7 +166,7 @@ public class IsisComponentProviderUsingInstallers extends IsisComponentProviderA
     public PersistenceSessionFactory providePersistenceSessionFactory(
             final DeploymentType deploymentType,
             final ServicesInjectorSpi servicesInjectorSpi,
-            final RuntimeContextFromSession runtimeContext) throws IsisSystemException {
+            final RuntimeContextFromSession runtimeContext) {
         return persistenceMechanismInstaller.createPersistenceSessionFactory(deploymentType, servicesInjectorSpi,
                 getConfiguration(),
                 runtimeContext);

http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java
index c772bea..e8540ce 100644
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java
@@ -49,6 +49,10 @@ public class RegisterEntities {
 
     // //////////////////////////////////////
 
+    // determines how to handle missing entities in a package
+    // if globSpec is in use, just log it (because we use packages also to indicate presence of services);
+    // if globSpec NOT in use, then treat this as an error.
+    private final boolean globSpecSpecified;
 
     //region > domPackages
     private final List<String> domPackages;
@@ -74,15 +78,16 @@ public class RegisterEntities {
                     PACKAGE_PREFIX_KEY));
         }
         domPackages = parseDomPackages(packagePrefixes);
+        this.globSpecSpecified = configuration.get("isis.globSpec") != null;
 
-        this.entityTypes = scanForEntityTypesIn(this.domPackages);
+        this.entityTypes = scanForEntityTypesIn(this.domPackages, this.globSpecSpecified);
     }
 
     private static List<String> parseDomPackages(String packagePrefixes) {
         return Collections.unmodifiableList(Lists.newArrayList(Iterables.transform(Splitter.on(",").split(packagePrefixes), trim())));
     }
 
-    private static Set<String> scanForEntityTypesIn(final List<String> domPackages) {
+    private static Set<String> scanForEntityTypesIn(final List<String> domPackages, final boolean globSpecSpecified) {
         final Set<String> entityTypes = Sets.newLinkedHashSet();
         for (final String packageName : domPackages) {
             Reflections reflections = new Reflections(packageName);
@@ -91,11 +96,18 @@ public class RegisterEntities {
                     reflections.getTypesAnnotatedWith(PersistenceCapable.class);
 
             if(!entitiesIn(entityTypesInPackage)) {
-                throw new IllegalArgumentException(String.format(
-                        "Bad configuration.\n\nCould not locate any @PersistenceCapable entities in package '%s'\n" +
-                                "Check value of '%s' key in WEB-INF/*.properties\n",
-                        packageName,
-                        PACKAGE_PREFIX_KEY));
+
+                if(globSpecSpecified) {
+                    if(LOG.isDebugEnabled()) {
+                        LOG.debug("Could not locate any @PersistenceCapable entities in module '%s'; ignoring\n", packageName);
+                    }
+                } else {
+                    throw new IllegalArgumentException(String.format(
+                            "Bad configuration.\n\nCould not locate any @PersistenceCapable entities in package '%s'\n" +
+                                    "Check value of '%s' key in WEB-INF/*.properties\n",
+                            packageName,
+                            PACKAGE_PREFIX_KEY));
+                }
             }
             for (Class<?> entityType : entityTypesInPackage) {
                 if(ignore(entityType)) {

http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpec.java
----------------------------------------------------------------------
diff --git a/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpec.java b/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpec.java
index 7501d0c..14a6896 100644
--- a/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpec.java
+++ b/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpec.java
@@ -22,36 +22,67 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
+import com.google.common.collect.Lists;
+
 import org.apache.isis.applib.GlobSpec;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 
 import domainapp.dom.DomainAppDomainModule;
+import domainapp.fixture.DomainAppFixturesProvider;
+import domainapp.fixture.scenarios.RecreateSimpleObjects;
 
-public final class DomainAppGlobSpec implements GlobSpec {
+/**
+ * Bootstrap the application.
+ */
+public class DomainAppGlobSpec implements GlobSpec {
 
+    /**
+     * Load all services and entities found in (the packages and subpackages within) these modules
+     */
     @Override
     public List<Class<?>> getModules() {
         return Arrays.asList(
-                DomainAppDomainModule.class,
-                DomainAppGlobSpec.class
+                DomainAppDomainModule.class, // entities and repositories
+                DomainAppFixturesProvider.class, // fixture configuration
+                DomainAppGlobSpec.class      // home page service
         );
     }
 
+    /**
+     * Use shiro for authentication.
+     *
+     * <p>
+     *     NB: this is ignored for integration tests, which always use "bypass".
+     * </p>
+     */
     @Override
     public String getAuthenticationMechanism() {
-        return null;
+        return "shiro";
     }
 
+    /**
+     * Use shiro for authorization.
+     *
+     * <p>
+     *     NB: this is ignored for integration tests, which always use "bypass".
+     * </p>
+     */
     @Override
     public String getAuthorizationMechanism() {
-        return null;
+        return "shiro";
     }
 
+    /**
+     * Run these fixtures.
+     */
     @Override
     public List<Class<? extends FixtureScript>> getFixtures() {
-        return null;
+        return Lists.newArrayList(RecreateSimpleObjects.class);
     }
 
+    /**
+     * No additional overrides
+     */
     @Override
     public Map<String, String> getConfigurationProperties() {
         return null;

http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpecBypass.java
----------------------------------------------------------------------
diff --git a/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpecBypass.java b/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpecBypass.java
new file mode 100644
index 0000000..9e3fe00
--- /dev/null
+++ b/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpecBypass.java
@@ -0,0 +1,35 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package domainapp.glob;
+
+/**
+ * Bypasses security, meaning any user/password combination can be used to login.
+ */
+public class DomainAppGlobSpecBypass extends DomainAppGlobSpec {
+
+    @Override
+    public String getAuthenticationMechanism() {
+        return "bypass";
+    }
+
+    @Override
+    public String getAuthorizationMechanism() {
+        return "bypass";
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpecNoFixtures.java
----------------------------------------------------------------------
diff --git a/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpecNoFixtures.java b/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpecNoFixtures.java
new file mode 100644
index 0000000..24f221a
--- /dev/null
+++ b/example/application/simpleapp/glob/src/main/java/domainapp/glob/DomainAppGlobSpecNoFixtures.java
@@ -0,0 +1,36 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package domainapp.glob;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.applib.fixturescripts.FixtureScript;
+
+/**
+ * Run the app but without setting up any fixtures.
+ */
+public class DomainAppGlobSpecNoFixtures extends DomainAppGlobSpec {
+
+    @Override
+    public List<Class<? extends FixtureScript>> getFixtures() {
+        return Collections.emptyList();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/example/application/simpleapp/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java
----------------------------------------------------------------------
diff --git a/example/application/simpleapp/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java b/example/application/simpleapp/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java
index 91244ec..85a92f7 100644
--- a/example/application/simpleapp/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java
+++ b/example/application/simpleapp/integtests/src/test/java/domainapp/integtests/bootstrap/SimpleAppSystemInitializer.java
@@ -18,37 +18,24 @@
  */
 package domainapp.integtests.bootstrap;
 
-import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.integtestsupport.IsisSystemForTest;
-import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPersistenceMechanismInstaller;
 import org.apache.isis.objectstore.jdo.datanucleus.IsisConfigurationForJdoIntegTests;
 
+import domainapp.glob.DomainAppGlobSpec;
+
 public class SimpleAppSystemInitializer {
 
     public static void initIsft() {
         IsisSystemForTest isft = IsisSystemForTest.getElseNull();
         if(isft == null) {
-            isft = new SimpleAppSystemBuilder().build().setUpSystem();
+            isft = new IsisSystemForTest.Builder()
+                    .withLoggingAt(org.apache.log4j.Level.INFO)
+                    .with(new DomainAppGlobSpec())
+                    .with(new IsisConfigurationForJdoIntegTests())
+                    .build()
+                    .setUpSystem();
             IsisSystemForTest.set(isft);
         }
     }
 
-    private static class SimpleAppSystemBuilder extends IsisSystemForTest.Builder {
-
-        public SimpleAppSystemBuilder() {
-            withLoggingAt(org.apache.log4j.Level.INFO);
-            with(testConfiguration());
-            with(new DataNucleusPersistenceMechanismInstaller());
-
-            // services annotated with @DomainService
-            withServicesIn( "domainapp" );
-        }
-
-        private static IsisConfiguration testConfiguration() {
-            final IsisConfigurationForJdoIntegTests testConfiguration = new IsisConfigurationForJdoIntegTests();
-
-            testConfiguration.addRegisterEntitiesPackagePrefix("domainapp.dom");
-            return testConfiguration;
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/34912499/example/application/simpleapp/webapp/src/main/webapp/WEB-INF/isis.properties
----------------------------------------------------------------------
diff --git a/example/application/simpleapp/webapp/src/main/webapp/WEB-INF/isis.properties b/example/application/simpleapp/webapp/src/main/webapp/WEB-INF/isis.properties
index 0ec356a..330c5b1 100644
--- a/example/application/simpleapp/webapp/src/main/webapp/WEB-INF/isis.properties
+++ b/example/application/simpleapp/webapp/src/main/webapp/WEB-INF/isis.properties
@@ -18,47 +18,14 @@
 
 #################################################################################
 #
-# specify system components.
-#
-# The values correspond to the named components in the installer-registry.properties file
-# in the org.apache.isis.core:isis-core-runtime JAR (in the org.apache.isis.core.runtime package)
-#
-# Although all configuration could reside in isis.properties, the recommendation is
-# to split out into component specific files:
-# 
-#    xxx_yyy.properties files
-#
-# where
-#    * xxx is the component type, and
-#    * yyy is the component name.
-#
-# For example, viewer_wicket.properties holds configuration information specific to the Wicket viewer.
+# use GlobSpec to specify modules, system components and fixtures
 #
 #################################################################################
 
 
-#
-#
-#
-isis.globspec=domainapp.glob.DomainAppGlobSpec
-
-
-
-
-#
-# configure authentication mechanism to use (to logon to the system)
-#
- 
-#isis.authentication=bypass
-isis.authentication=shiro
-
-
-#
-# configure authorization mechanism to use
-#
- 
-#isis.authorization=bypass
-isis.authorization=shiro
+isis.globSpec=domainapp.glob.DomainAppGlobSpec
+#isis.globSpec=domainapp.glob.DomainAppGlobSpecBypass
+#isis.globSpec=domainapp.glob.DomainAppGlobSpecNoFixtures
 
 
 
@@ -158,33 +125,10 @@ isis.value.format.date=dd-MM-yyyy
 
 #################################################################################
 #
-# Application Services and fixtures
+# Domain service Configuration
 #
 #################################################################################
 
-#
-# Specify the domain services.
-# 
-# These are the most important configuration properties in the system, as they define
-# the set of the classes for Isis to instantiate as domain service singletons.
-# From these domain service instances the rest of the metamodel is discovered, while the 
-# end-user gains access to other domain objects by invoking the actions of the domain services.
-#
-isis.services-installer=configuration-and-annotation
-isis.services.ServicesInstallerFromAnnotation.packagePrefix=domainapp
-
-# additional services/overriding default (@DomainService) implementations
-isis.services =
-
-
-
-# Specify the (optional) test fixtures
-#
-# Fixtures are used to seed the object store with an initial set of data.  For the 
-# in-memory object store, the fixtures are installed on every run.  For other
-# object stores, they are used only when the object store is first initialized.
-#
-isis.fixtures=domainapp.fixture.scenarios.RecreateSimpleObjects
 
 
 #