You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2019/05/10 10:25:44 UTC

[isis] branch 2112_SpringBoot updated (ef099bd -> bf4261a)

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a change to branch 2112_SpringBoot
in repository https://gitbox.apache.org/repos/asf/isis.git.


    from ef099bd  ISIS-2112: convert IsisSessionFactoryDefault to spring-managed singleton
     new 20bc8b7  ISIS-2112: deprecate legacy event-bus
     new bf4261a  ISIS-2112: fixing service provisioning test setup

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/isis/applib/AbstractSubscriber.java |  72 -----
 .../applib/services/eventbus/EventBusService.java  | 305 +--------------------
 .../applib/services/publish/PublisherService.java  |   3 -
 .../services/publish/PublisherServiceLogging.java  |  36 +--
 .../QueryResultsCacheControlInternal.java          |  30 +-
 .../isis/applib/services/user/UserService.java     |   4 +-
 .../builder/IsisConfigurationBuilderDefault.java   |   3 +-
 .../tests/SpringServiceProvisioningTest.java       |  12 +-
 ...tamodelModule.java => IsisMetamodelModule.java} |   2 +-
 .../RepositoryServiceInternalDefault.java          |  37 +--
 .../services/user/UserServiceDefault.java          |   9 +-
 .../QueryResultsCacheUsingAxonTest.java            |  19 +-
 .../service/eventbus/EventBusServiceJdo.java       |   9 +-
 .../isis/core/wrapper/IsisWrapperModule.java}      |   5 +-
 .../isis/core/wrapper/WrapperFactoryDefault.java   |  12 +-
 .../org/apache/isis/runtime/spring/IsisBoot.java   |  14 +-
 ...sModule.java => IsisRuntimeServicesModule.java} |   2 +-
 .../AuthenticationSessionProviderDefault.java      |  11 +-
 .../eventbus/EventBusImplementationAbstract.java   |   1 +
 .../eventbus/EventBusServiceAbstract.java}         |   9 +-
 .../services/eventbus/EventBusServiceDefault.java  |   3 +-
 .../services/xactn/TransactionServiceDefault.java  |   9 +-
 .../{RuntimeModule.java => IsisRuntimeModule.java} |   2 +-
 .../system/session/IsisSessionFactoryDefault.java  |   7 +-
 .../system/session/SpecificationLoaderFactory.java |   4 +-
 .../session/SpecificationLoaderProducerBean.java   |   6 +-
 .../java/domainapp/dom/events/EventSubscriber.java |   7 -
 27 files changed, 94 insertions(+), 539 deletions(-)
 delete mode 100644 core/applib/src/main/java/org/apache/isis/applib/AbstractSubscriber.java
 rename core/metamodel/src/main/java/org/apache/isis/core/metamodel/{MetamodelModule.java => IsisMetamodelModule.java} (51%)
 copy core/{applib/src/test/java/org/apache/isis/applib/SomeDomainClass.java => runtime-extensions/src/main/java/org/apache/isis/core/wrapper/IsisWrapperModule.java} (91%)
 rename core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/{RuntimeServicesModule.java => IsisRuntimeServicesModule.java} (94%)
 copy core/{applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java => runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceAbstract.java} (97%)
 rename core/runtime/src/main/java/org/apache/isis/core/runtime/{RuntimeModule.java => IsisRuntimeModule.java} (95%)


[isis] 02/02: ISIS-2112: fixing service provisioning test setup

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch 2112_SpringBoot
in repository https://gitbox.apache.org/repos/asf/isis.git

commit bf4261a0b32c9a3dd60c458ba1d462e1ceed2537
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri May 10 12:25:35 2019 +0200

    ISIS-2112: fixing service provisioning test setup
    
    - event-bus disabled for now
    - IsisSessionFactory provisioned by Spring !
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-2112
---
 .../isis/config/builder/IsisConfigurationBuilderDefault.java |  3 ++-
 .../isis/testdomain/tests/SpringServiceProvisioningTest.java | 12 +++++++++---
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/core/config/src/main/java/org/apache/isis/config/builder/IsisConfigurationBuilderDefault.java b/core/config/src/main/java/org/apache/isis/config/builder/IsisConfigurationBuilderDefault.java
index 0a5e751..d78c213 100644
--- a/core/config/src/main/java/org/apache/isis/config/builder/IsisConfigurationBuilderDefault.java
+++ b/core/config/src/main/java/org/apache/isis/config/builder/IsisConfigurationBuilderDefault.java
@@ -120,7 +120,8 @@ final class IsisConfigurationBuilderDefault implements IsisConfigurationBuilder
 
     private void addTopLevelDefaultConfigurationResource() {
         addConfigurationResource(ConfigurationConstants.DEFAULT_CONFIG_FILE, 
-                NotFoundPolicy.FAIL_FAST, ContainsPolicy.IGNORE);
+                NotFoundPolicy.CONTINUE, 
+                ContainsPolicy.IGNORE);
     }
 
     private void addDefaultConfigurationResources() {
diff --git a/core/detached-tests/src/test/java/org/apache/isis/testdomain/tests/SpringServiceProvisioningTest.java b/core/detached-tests/src/test/java/org/apache/isis/testdomain/tests/SpringServiceProvisioningTest.java
index 7a33cf5..d7f22cb 100644
--- a/core/detached-tests/src/test/java/org/apache/isis/testdomain/tests/SpringServiceProvisioningTest.java
+++ b/core/detached-tests/src/test/java/org/apache/isis/testdomain/tests/SpringServiceProvisioningTest.java
@@ -20,6 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
+import java.util.Set;
 import java.util.TreeSet;
 import java.util.stream.Collectors;
 
@@ -35,13 +36,12 @@ import org.apache.isis.commons.internal.resources._Resources;
 import org.apache.isis.commons.ioc.BeanAdapter;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.testdomain.jdo.JdoTestApplication;
-import org.apache.isis.testdomain.jdo.JdoTestDomainIntegTest;
 
 import lombok.val;
 
 @ExtendWith(SpringExtension.class)
 @SpringBootTest(classes = {JdoTestApplication.class})
-class SpringServiceProvisioningTest extends JdoTestDomainIntegTest {
+class SpringServiceProvisioningTest /*extends JdoTestDomainIntegTest*/ {
 
     @BeforeEach
     void setUp() {
@@ -61,10 +61,16 @@ class SpringServiceProvisioningTest extends JdoTestDomainIntegTest {
         val singletonSet = new TreeSet<>(_Json.readJsonList(String.class, singletonJson));
         
         // same as managedServices.containsAll(singletonSet) but more verbose in case of failure        
-        assertEquals(singletonSet.toString(), _Sets.intersectSorted(managedServices, singletonSet).toString());
+        assertEquals(setToString(singletonSet), setToString(_Sets.intersectSorted(managedServices, singletonSet)));
         
         //TODO also test for request-scoped service (requires a means to mock a request-context)
         
     }
+    
+    private static String setToString(Set<?> set){
+        return set.stream()
+                .map(Object::toString)
+                .collect(Collectors.joining("\n"));
+    }
         
 }


[isis] 01/02: ISIS-2112: deprecate legacy event-bus

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch 2112_SpringBoot
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 20bc8b7d4c445dc5686bf6d4b0317694df607469
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri May 10 12:06:54 2019 +0200

    ISIS-2112: deprecate legacy event-bus
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-2112
---
 .../org/apache/isis/applib/AbstractSubscriber.java |  72 -----
 .../applib/services/eventbus/EventBusService.java  | 305 +--------------------
 .../applib/services/publish/PublisherService.java  |   3 -
 .../services/publish/PublisherServiceLogging.java  |  36 +--
 .../QueryResultsCacheControlInternal.java          |  30 +-
 .../isis/applib/services/user/UserService.java     |   4 +-
 ...tamodelModule.java => IsisMetamodelModule.java} |   2 +-
 .../RepositoryServiceInternalDefault.java          |  37 +--
 .../services/user/UserServiceDefault.java          |   9 +-
 .../QueryResultsCacheUsingAxonTest.java            |  19 +-
 .../service/eventbus/EventBusServiceJdo.java       |   9 +-
 .../isis/core/wrapper/IsisWrapperModule.java}      |   4 +-
 .../isis/core/wrapper/WrapperFactoryDefault.java   |  12 +-
 .../org/apache/isis/runtime/spring/IsisBoot.java   |  14 +-
 ...sModule.java => IsisRuntimeServicesModule.java} |   2 +-
 .../AuthenticationSessionProviderDefault.java      |  11 +-
 .../eventbus/EventBusImplementationAbstract.java   |   1 +
 .../eventbus/EventBusServiceAbstract.java}         |   9 +-
 .../services/eventbus/EventBusServiceDefault.java  |   3 +-
 .../services/xactn/TransactionServiceDefault.java  |   9 +-
 .../{RuntimeModule.java => IsisRuntimeModule.java} |   2 +-
 .../system/session/IsisSessionFactoryDefault.java  |   7 +-
 .../system/session/SpecificationLoaderFactory.java |   4 +-
 .../session/SpecificationLoaderProducerBean.java   |   6 +-
 .../java/domainapp/dom/events/EventSubscriber.java |   7 -
 25 files changed, 83 insertions(+), 534 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/AbstractSubscriber.java b/core/applib/src/main/java/org/apache/isis/applib/AbstractSubscriber.java
deleted file mode 100644
index f16c3de..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/AbstractSubscriber.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  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 org.apache.isis.applib;
-
-import javax.annotation.PostConstruct;
-
-import org.apache.isis.applib.annotation.DomainServiceLayout;
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.services.eventbus.EventBusService;
-import org.apache.isis.applib.services.factory.FactoryService;
-import org.apache.isis.applib.services.message.MessageService;
-import org.apache.isis.applib.services.repository.RepositoryService;
-import org.apache.isis.applib.services.title.TitleService;
-import org.apache.isis.applib.services.user.UserService;
-import org.apache.isis.applib.services.xactn.TransactionService;
-
-/**
- * Convenience class for services that act as subscribers.
- */
-@DomainServiceLayout(
-        menuOrder = "1"
-        )
-public abstract class AbstractSubscriber {
-
-    @PostConstruct
-    public void postConstruct() {
-        eventBusService.register(this);
-    }
-
-    @Programmatic
-    public void preDestroy() {
-        eventBusService.unregister(this);
-    }
-
-    @javax.inject.Inject
-    protected MessageService messageService;
-
-    @javax.inject.Inject
-    protected TitleService titleService;
-
-    @javax.inject.Inject
-    protected RepositoryService repositoryService;
-
-    @javax.inject.Inject
-    protected FactoryService factoryService;
-
-    @javax.inject.Inject
-    protected UserService userService;
-
-    @javax.inject.Inject
-    protected TransactionService transactionService;
-
-    @javax.inject.Inject
-    protected EventBusService eventBusService;
-
-}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
index d1f2fc9..01d0782 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
@@ -1,4 +1,4 @@
-/**
+/*
  *  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.
@@ -16,311 +16,16 @@
  */
 package org.apache.isis.applib.services.eventbus;
 
-import java.util.Collections;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Consumer;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.commons.internal.collections._Sets;
-import org.apache.isis.core.plugins.eventbus.EventBusPlugin;
-import org.apache.isis.core.plugins.eventbus.EventBusPlugin.EventListener;
-
 /**
- * A service implementing an Event Bus, allowing arbitrary events to be posted and
- * subscribed to.
- *
- * <p>
- *      Only domain services (not domain entities or view models) should be registered; only they are guaranteed to be
- *      instantiated and resident in memory.
- * </p>
- *
- * <p>
- *     It <i>is</i> possible to register request-scoped services, however they should register their proxy
- *     rather than themselves.  This ensures that the actual subscribers are all singletons.  This implementation uses
- *     reference counting to keep track of whether there are any concurrent instances of a request-scoped service
- *     (keeps things nice and symmetrical).
- * </p>
+ * A service implementing an Event Bus, allowing arbitrary events to be posted.
+ * @since 2.0.0
  */
-public abstract class EventBusService {
-
-    /**
-     * A no-op implementation to use as a default for domain objects that are being
-     * instantiated and for which the event bus service has not yet been injected.
-     */
-    public static class Noop extends EventBusService {
-        @Override
-        public void register(Object domainService) {}
-        @Override
-        public void unregister(Object domainService) {}
-        @Override
-        public void post(Object event) {}
-        @Override
-        public EventBusPlugin getEventBusImplementation() {
-            return null;
-        }
-        @Override
-        protected EventBusPlugin newEventBus() { return null; }
-    }
-
-    public static final EventBusService NOOP = new Noop();
-
-    // -- init, shutdown
-
-    /**
-     * Cannot do the setup of the event bus here (so this is asymmetric with <code>@PreDestroy</code>) because there is
-     * no guarantee of the order in which <code>@PostConstruct</code> is called on any request-scoped services.  We
-     * therefore allow all services (singleton or request-scoped) to {@link #register(Object) register} themselves
-     * with this service in their <code>@PostConstruct</code> and do the actual instantiation of the guava
-     * {@link com.google.common.eventbus.EventBus} and registering of subscribers lazily, in {@link #getEventBusImplementation()}.
-     * This lifecycle method ({@link #init(Map)}) is therefore a no-op.
-     *
-     * <p>
-     *     The guava {@link com.google.common.eventbus.EventBus} can however (and is) be torndown in the
-     *     <code>@PreDestroy</code> {@link #shutdown()} lifecycle method.
-     * </p>
-     */
-    @Programmatic
-    @PostConstruct
-    public void init() {
-        hasPosted = false; // reset state
-    }
-
-    @Programmatic
-    @PreDestroy
-    public void shutdown() {
-        teardownEventBus();
-    }
-
-
-
-    // -- register, unregister
-
-    /**
-     * Both singleton and request-scoped domain services can register on the event bus; this should be done in their
-     * <code>@PostConstruct</code> callback method.
-     *
-     * <p>
-     *     <b>Important:</b> Request-scoped services should register their proxy, not themselves.  This is because it is
-     *     the responsibility of the proxy to ensure that the correct underlying (thread-local) instance of the service
-     *     is delegated to.  If the actual instance were to be registered, this would cause a memory leak and all sorts
-     *     of other unexpected issues.
-     * </p>
-     *
-     * <p>
-     *     Also, request-scoped services should <i>NOT</i> unregister themselves.  This is because the
-     *     <code>@PreDestroy</code> lifecycle method is called at the end of each transaction.  The proxy needs to
-     *     remain registered on behalf for any subsequent transactions.
-     * </p>
-     *
-     * <p>For example:</p>
-     * <pre>
-     *     @RequestScoped @DomainService
-     *     public class SomeSubscribingService {
-     *
-     *         @javax.inject.Inject private EventBusService ebs;
-     *         @javax.inject.Inject private SomeSubscribingService proxy;
-     *
-     *         @PostConstruct
-     *         public void startRequest() {
-     *              // register with bus
-     *              ebs.register(proxy);
-     *         }
-     *         @PreDestroy
-     *         public void endRequest() {
-     *              //no-op
-     *         }
-     *     }
-     * </pre>
-     *
-     * <p>
-     *     The <code>@PostConstruct</code> callback is the correct place to register for both singleton and
-     *     request-scoped services.  For singleton domain services, this is done during the initial bootstrapping of
-     *     the system.  For request-scoped services, this is done for the first transaction.  In fact, because
-     *     singleton domain services are initialized <i>within a current transaction</i>, the request-scoped services
-     *     will actually be registered <i>before</i> the singleton services.  Each subsequent transaction will have the
-     *     request-scoped service re-register with the event bus, however the event bus stores its subscribers in a
-     *     set and so these re-registrations are basically a no-op.
-     * </p>
-     *
-     * @param domainService
-     */
-    @Programmatic
-    public void register(final Object domainService) {
-        doRegister(domainService);
-    }
-
-    /**
-     * Extracted out only to make it easier for subclasses to override {@link #register(Object)} if there were ever a
-     * need to.
-     */
-    protected void doRegister(Object domainService) {
-        if(eventBusImplementation == null) {
-            subscribers.add(domainService);
-        } else {
-            eventBusImplementation.register(domainService);
-        }
-    }
-
-
-    /**
-     * Notionally allows subscribers to unregister from the event bus; however this is a no-op.
-     *
-     * <p>
-     *     It is safe for singleton services to unregister from the bus, however this is only ever called when the
-     *     app is being shutdown so there is no real effect.  For request-scoped services meanwhile that (as
-     *     explained in {@link #register(Object)}'s documentation) actually register their proxy, it would be an error
-     *     to unregister the proxy; subsequent transactions (for this thread or others) must be routed through that
-     *     proxy.
-     * </p>
-     */
-    @Programmatic
-    public void unregister(final Object domainService) {
-        // intentionally no-op
-    }
-
-
-
-    // -- subscribers
-
-    private final Set<Object> subscribers = _Sets.newConcurrentHashSet();
-
-
-    /**
-     * Returns an immutable snapshot of the current subscribers.
-     */
-    @Programmatic
-    public Set<Object> getSubscribers() {
-        return Collections.unmodifiableSet(_Sets.newLinkedHashSet(subscribers));
-    }
-
-    // -- post
-
-    private boolean hasPosted;
+public interface EventBusService {
 
     /**
      * Post an event.
      */
-    @Programmatic
-    public void post(Object event) {
-        if(skip(event)) {
-            return;
-        }
-        hasPosted = true;
-        getEventBusImplementation().post(event);
-    }
-
-
-    protected boolean hasPosted() {
-        return hasPosted;
-    }
-
-    // -- getEventBus
-
-    /**
-     * Lazily populated in {@link #getEventBusImplementation()} as result of the first {@link #post(Object)}.
-     */
-    protected EventBusPlugin eventBusImplementation;
-
-    public <T> EventListener<T> addEventListener(final Class<T> targetType, Consumer<T> onEvent) {
-        return Optional.ofNullable(getEventBusImplementation())
-                .map(impl->impl.addEventListener(targetType, onEvent))
-                .orElse(null);
-    }
-
-    public <T> void removeEventListener(EventListener<T> eventListener) {
-        // do not trigger setupEventBus()
-        if(eventBusImplementation!=null) {
-            eventBusImplementation.removeEventListener(eventListener);
-        }
-    }
-
-    /**
-     * Lazily populates the event bus for the current {@link #getSubscribers() subscribers}.
-     */
-    @Programmatic
-    protected EventBusPlugin getEventBusImplementation() {
-        setupEventBus();
-        return eventBusImplementation;
-    }
-
-    /**
-     * Set of subscribers registered with the event bus.
-     *
-     * <p>
-     * Lazily populated in {@link #setupEventBus()}.
-     * </p>
-     */
-    private Set<Object> registeredSubscribers;
-
-    /**
-     * Populates {@link #eventBusImplementation} with the {@link #registeredSubscribers currently registered subscribers}.
-     *
-     * <p>
-     *     Guava event bus will throw an exception if attempt to unsubscribe any subscribers that were not subscribed.
-     *     It is therefore the responsibility of this service to remember which services were registered
-     *     at the start of the request, and to unregister precisely this same set of services at the end.
-     * </p>
-     *
-     * <p>
-     *     That said, the Guava event bus is only ever instantiated once (it is in essence an application-scoped singleton),
-     *     and so once created it is not possible for any subscribers to be registered.  For this reason, the
-     *     {@link #register(Object)} will throw an exception if any attempt is made to register once the event bus
-     *     has been instantiated.
-     * </p>
-     */
-    protected void setupEventBus() {
-        if(eventBusImplementation != null) {
-            return;
-        }
-        this.eventBusImplementation = newEventBus();
-
-        registeredSubscribers = getSubscribers();
-
-        for (Object subscriber : this.registeredSubscribers) {
-            eventBusImplementation.register(subscriber);
-        }
-    }
-
-    protected void teardownEventBus() {
-        if(registeredSubscribers != null) {
-            for (Object subscriber : this.registeredSubscribers) {
-                eventBusImplementation.unregister(subscriber);
-            }
-        }
-
-        this.eventBusImplementation = null;
-    }
-
-
-
-    // -- hook methods (newEventBus, skip)
-
-    /**
-     * Mandatory hook method for subclass to instantiate an appropriately configured Guava event bus.
-     */
-    protected abstract EventBusPlugin newEventBus();
-
-
-    /**
-     * A hook to allow subclass implementations to skip the publication of certain events.
-     *
-     * <p>
-     * For example, the <tt>EventBusServiceJdo</tt> does not publish events if the method
-     * is called by JDO/DataNucleus infrastructure, eg during hydration or commits.
-     */
-    protected boolean skip(Object event) {
-        return false;
-    }
-
-
-
-
-
+    public void post(Object event);
 
 }
 
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/publish/PublisherService.java b/core/applib/src/main/java/org/apache/isis/applib/services/publish/PublisherService.java
index 9c1d7ca..6dc8f51 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/publish/PublisherService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/publish/PublisherService.java
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.applib.services.publish;
 
-import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.services.iactn.Interaction;
 
 /**
@@ -35,10 +34,8 @@ public interface PublisherService {
      * XML representation of the execution.  The easiest way to do this is using {@link org.apache.isis.schema.utils.InteractionDtoUtils#newInteractionDto(Interaction.Execution)}.  There is
      * some flexibility here, though.
      */
-    @Programmatic
     void publish(final Interaction.Execution<?, ?> execution);
 
-    @Programmatic
     void publish(final PublishedObjects publishedObjects);
 }
 
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/publish/PublisherServiceLogging.java b/core/applib/src/main/java/org/apache/isis/applib/services/publish/PublisherServiceLogging.java
index 3b0e29a..88d9f75 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/publish/PublisherServiceLogging.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/publish/PublisherServiceLogging.java
@@ -18,64 +18,44 @@
  */
 package org.apache.isis.applib.services.publish;
 
-import javax.annotation.PostConstruct;
+import javax.inject.Singleton;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.services.iactn.Interaction;
 import org.apache.isis.schema.chg.v1.ChangesDto;
 import org.apache.isis.schema.ixn.v1.InteractionDto;
 import org.apache.isis.schema.utils.ChangesDtoUtils;
 import org.apache.isis.schema.utils.InteractionDtoUtils;
 
-@DomainService(
-        nature = NatureOfService.DOMAIN,
-        menuOrder = "" + Integer.MAX_VALUE
-        )
-public class PublisherServiceLogging implements PublisherService {
-
-    private static final Logger LOG = LoggerFactory.getLogger(PublisherServiceLogging.class);
-
+import lombok.extern.slf4j.Slf4j;
 
-    @PostConstruct
-    public void init() {
-    }
+@Singleton @Slf4j
+public class PublisherServiceLogging implements PublisherService {
 
     @Override
     public void publish(final Interaction.Execution<?, ?> execution) {
 
-        if(!LOG.isDebugEnabled()) {
+        if(!log.isDebugEnabled()) {
             return;
         }
 
         final InteractionDto interactionDto =
                 InteractionDtoUtils.newInteractionDto(execution, InteractionDtoUtils.Strategy.DEEP);
 
-        LOG.debug(InteractionDtoUtils.toXml(interactionDto));
+        log.debug(InteractionDtoUtils.toXml(interactionDto));
 
     }
 
     @Override
     public void publish(final PublishedObjects publishedObjects) {
 
-        if(!LOG.isDebugEnabled()) {
+        if(!log.isDebugEnabled()) {
             return;
         }
 
         final ChangesDto changesDto = publishedObjects.getDto();
 
-        LOG.debug(ChangesDtoUtils.toXml(changesDto));
+        log.debug(ChangesDtoUtils.toXml(changesDto));
     }
 
-    //TODO [ahuber] not used, remove?
-    //    @javax.inject.Inject
-    //    private CommandContext commandContext;
-    //
-    //    @javax.inject.Inject
-    //    private UserService userService;
-
 }
 
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheControlInternal.java b/core/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheControlInternal.java
index ec6752f..d1e34a6 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheControlInternal.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheControlInternal.java
@@ -16,11 +16,10 @@
  */
 package org.apache.isis.applib.services.queryresultscache;
 
-import javax.annotation.PostConstruct;
 import javax.inject.Singleton;
 
-import org.apache.isis.applib.AbstractSubscriber;
-import org.apache.isis.applib.annotation.Programmatic;
+import org.springframework.context.event.EventListener;
+
 import org.apache.isis.applib.fixturescripts.events.FixturesInstalledEvent;
 import org.apache.isis.applib.fixturescripts.events.FixturesInstallingEvent;
 
@@ -29,27 +28,20 @@ import org.apache.isis.applib.fixturescripts.events.FixturesInstallingEvent;
  * In separate class because {@link QueryResultsCache} itself is request-scoped
  */
 @Singleton
-public class QueryResultsCacheControlInternal extends AbstractSubscriber implements QueryResultCacheControl {
-
-    @PostConstruct
-    @Override
-    public void postConstruct() {
-
-        super.postConstruct();
-
-        eventBusService.addEventListener(FixturesInstallingEvent.class, ev->{
-            fixturesInstalling = true;
-        });
-
-        eventBusService.addEventListener(FixturesInstalledEvent.class, ev->{
-            fixturesInstalling = false;
-        });
+public class QueryResultsCacheControlInternal implements QueryResultCacheControl {
 
+    @EventListener(FixturesInstallingEvent.class)
+    public void onFixturesInstallingEvent(FixturesInstallingEvent ev) {
+        fixturesInstalling = true;
+    }
+    
+    @EventListener(FixturesInstalledEvent.class)
+    public void onFixturesInstallingEvent(FixturesInstalledEvent ev) {
+        fixturesInstalling = false;
     }
 
     private boolean fixturesInstalling;
 
-    @Programmatic
     @Override
     public boolean isFixturesInstalling() {
         return fixturesInstalling;
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/user/UserService.java b/core/applib/src/main/java/org/apache/isis/applib/services/user/UserService.java
index d5c5b62..80528bf 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/user/UserService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/user/UserService.java
@@ -19,7 +19,6 @@
 
 package org.apache.isis.applib.services.user;
 
-import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.security.UserMemento;
 
 public interface UserService {
@@ -27,7 +26,6 @@ public interface UserService {
     /**
      * Get the details about the current user.
      */
-    @Programmatic UserMemento getUser();
-
+    UserMemento getUser();
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/MetamodelModule.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/IsisMetamodelModule.java
similarity index 51%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/MetamodelModule.java
rename to core/metamodel/src/main/java/org/apache/isis/core/metamodel/IsisMetamodelModule.java
index 64b6c27..d9e4bb4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/MetamodelModule.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/IsisMetamodelModule.java
@@ -1,5 +1,5 @@
 package org.apache.isis.core.metamodel;
 
-public final class MetamodelModule {
+public final class IsisMetamodelModule {
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/repository/RepositoryServiceInternalDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/repository/RepositoryServiceInternalDefault.java
index 071dcc6..a0ed84f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/repository/RepositoryServiceInternalDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/repository/RepositoryServiceInternalDefault.java
@@ -19,18 +19,18 @@
 
 package org.apache.isis.core.metamodel.services.repository;
 
+import static org.apache.isis.config.internal._Config.getConfiguration;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 import javax.annotation.PostConstruct;
+import javax.inject.Singleton;
 
 import org.apache.isis.applib.PersistFailedException;
 import org.apache.isis.applib.RepositoryException;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.query.Query;
 import org.apache.isis.applib.query.QueryFindAllInstances;
 import org.apache.isis.applib.services.factory.FactoryService;
@@ -42,17 +42,12 @@ import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
 import org.apache.isis.core.metamodel.services.persistsession.PersistenceSessionServiceInternal;
 
-import static org.apache.isis.config.internal._Config.getConfiguration;
-
-@DomainService(
-        nature = NatureOfService.DOMAIN,
-        menuOrder = "" + Integer.MAX_VALUE
-        )
+@Singleton
 public class RepositoryServiceInternalDefault implements RepositoryService {
 
     private boolean autoFlush;
 
-    @Programmatic
+
     @PostConstruct
     public void init() {
         final boolean disableAutoFlush = getConfiguration().getBoolean(KEY_DISABLE_AUTOFLUSH, false);
@@ -62,7 +57,7 @@ public class RepositoryServiceInternalDefault implements RepositoryService {
 
     // //////////////////////////////////////
 
-    @Programmatic
+
     @Override
     public <T> T instantiate(final Class<T> domainClass) {
         return factoryService.instantiate(domainClass);
@@ -70,21 +65,21 @@ public class RepositoryServiceInternalDefault implements RepositoryService {
 
     // //////////////////////////////////////
 
-    @Programmatic
+
     @Override
     public boolean isPersistent(final Object domainObject) {
         final ObjectAdapter adapter = getObjectAdapterProvider().adapterFor(unwrapped(domainObject));
         return adapter.isRepresentingPersistent();
     }
 
-    @Programmatic
+
     @Override
     public boolean isDeleted(final Object domainObject) {
         final ObjectAdapter adapter = getObjectAdapterProvider().adapterFor(unwrapped(domainObject));
         return adapter.isDestroyed();
     }
 
-    @Programmatic
+
     @Override
     public <T> T persist(final T object) {
         if (isPersistent(object)) {
@@ -107,7 +102,7 @@ public class RepositoryServiceInternalDefault implements RepositoryService {
         return object;
     }
 
-    @Programmatic
+
     @Override
     public <T> T persistAndFlush(final T object) {
         persist(object);
@@ -116,7 +111,6 @@ public class RepositoryServiceInternalDefault implements RepositoryService {
     }
 
     @Override
-    @Programmatic
     public void remove(final Object domainObject) {
         removeIfNotAlready(domainObject);
     }
@@ -137,7 +131,6 @@ public class RepositoryServiceInternalDefault implements RepositoryService {
     }
 
     @Override
-    @Programmatic
     public void removeAndFlush(final Object domainObject) {
         remove(domainObject);
         transactionService.flushTransaction();
@@ -149,7 +142,7 @@ public class RepositoryServiceInternalDefault implements RepositoryService {
 
     // -- allInstances, allMatches, uniqueMatch, firstMatch
 
-    @Programmatic
+
     @Override
     public <T> List<T> allInstances(final Class<T> type, long... range) {
         return allMatches(new QueryFindAllInstances<T>(type, range));
@@ -157,7 +150,7 @@ public class RepositoryServiceInternalDefault implements RepositoryService {
 
     // //////////////////////////////////////
 
-    @Programmatic
+
     @Override
     public <T> List<T> allMatches(Class<T> ofType, final Predicate<? super T> predicate, long... range) {
         return _NullSafe.stream(allInstances(ofType, range))
@@ -165,7 +158,7 @@ public class RepositoryServiceInternalDefault implements RepositoryService {
                 .collect(Collectors.toCollection(ArrayList::new));
     }
 
-    @Programmatic
+
     @Override
     public <T> List<T> allMatches(final Query<T> query) {
         if(autoFlush) {
@@ -182,7 +175,7 @@ public class RepositoryServiceInternalDefault implements RepositoryService {
 
     // //////////////////////////////////////
 
-    @Programmatic
+
     @Override
     public <T> T uniqueMatch(final Class<T> type, final Predicate<T> predicate) {
         final List<T> instances = allMatches(type, predicate, 0, 2); // No need to fetch more than 2.
@@ -193,7 +186,7 @@ public class RepositoryServiceInternalDefault implements RepositoryService {
     }
 
 
-    @Programmatic
+
     @Override
     public <T> T uniqueMatch(final Query<T> query) {
         final List<T> instances = allMatches(query); // No need to fetch more than 2.
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/user/UserServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/user/UserServiceDefault.java
index ed34ddd..b1ddd99 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/user/UserServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/user/UserServiceDefault.java
@@ -24,10 +24,10 @@ import java.util.List;
 import java.util.Stack;
 
 import javax.inject.Inject;
+import javax.inject.Singleton;
 
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.security.RoleMemento;
 import org.apache.isis.applib.security.UserMemento;
 import org.apache.isis.applib.services.sudo.SudoService;
@@ -35,13 +35,9 @@ import org.apache.isis.applib.services.user.UserService;
 import org.apache.isis.core.security.authentication.AuthenticationSession;
 import org.apache.isis.core.security.authentication.AuthenticationSessionProvider;
 
-@DomainService(
-        nature = NatureOfService.DOMAIN,
-        menuOrder = "" + Integer.MAX_VALUE
-        )
+@Singleton
 public class UserServiceDefault implements UserService {
 
-    @Programmatic
     @Override
     public UserMemento getUser() {
 
@@ -121,7 +117,6 @@ public class UserServiceDefault implements UserService {
     /**
      * Not API; for use by the implementation of sudo/runAs (see {@link SudoService} etc.
      */
-    @Programmatic
     public UserAndRoleOverrides currentOverridesIfAny() {
         final Stack<UserAndRoleOverrides> userAndRoleOverrides = overrides.get();
         return !userAndRoleOverrides.empty()
diff --git a/core/plugins/eventbus-axon/src/test/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheUsingAxonTest.java b/core/plugins/eventbus-axon/src/test/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheUsingAxonTest.java
index 00ba9c4..59e5c46 100644
--- a/core/plugins/eventbus-axon/src/test/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheUsingAxonTest.java
+++ b/core/plugins/eventbus-axon/src/test/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheUsingAxonTest.java
@@ -21,12 +21,12 @@ import static org.junit.Assert.assertThat;
 
 import java.util.concurrent.Callable;
 
+import org.junit.Before;
+import org.junit.Test;
+
 import org.apache.isis.applib.fixturescripts.events.FixturesInstallingEvent;
 import org.apache.isis.applib.services.fixturespec.FixtureScriptsDefault;
 import org.apache.isis.core.plugins.eventbus.EventBusPluginForAxon;
-import org.apache.isis.core.runtime.services.eventbus.EventBusServiceDefault;
-import org.junit.Before;
-import org.junit.Test;
 
 public class QueryResultsCacheUsingAxonTest {
 
@@ -37,18 +37,7 @@ public class QueryResultsCacheUsingAxonTest {
     @Before
     public void setUp() throws Exception {
         queryResultsCache = new QueryResultsCacheInternal();
-        control = new QueryResultsCacheControlInternal() {
-        	{
-        		eventBusService = new EventBusServiceDefault() {
-        			{
-        				allowLateRegistration = true;
-        				eventBusImplementation = eventBusImplementationAxon 
-        						= new EventBusPluginForAxon();
-        			}
-				};
-        	}
-        };
-        control.postConstruct();
+        control = new QueryResultsCacheControlInternal();
         queryResultsCache.control = control;
     }
 
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java
index d7159c1..f26010e 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/service/eventbus/EventBusServiceJdo.java
@@ -16,9 +16,6 @@
  */
 package org.apache.isis.objectstore.jdo.datanucleus.service.eventbus;
 
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.core.runtime.services.eventbus.EventBusServiceDefault;
 import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis;
 import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis.Hint;
@@ -39,10 +36,7 @@ import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis.Hint;
  * with {@link org.apache.isis.applib.annotation.DomainService}.  Because it is implemented in the core, this means
  * that it is automatically registered and available for use; no further configuration is required.
  */
-@DomainService(
-        nature = NatureOfService.DOMAIN,
-        menuOrder = "0" // initialize first, so available for any services that persist objects in their @PostConstruct
-        )
+@Deprecated
 public class EventBusServiceJdo extends EventBusServiceDefault {
 
     /**
@@ -52,7 +46,6 @@ public class EventBusServiceJdo extends EventBusServiceDefault {
      * The {@link JDOStateManagerForIsis} sets a {@link JDOStateManagerForIsis#hint threadlocal}
      * if it has been called.
      */
-    @Programmatic
     @Override
     protected boolean skip(Object event) {
         return JDOStateManagerForIsis.hint.get() != Hint.NONE;
diff --git a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/RuntimeServicesModule.java b/core/runtime-extensions/src/main/java/org/apache/isis/core/wrapper/IsisWrapperModule.java
similarity index 90%
copy from core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/RuntimeServicesModule.java
copy to core/runtime-extensions/src/main/java/org/apache/isis/core/wrapper/IsisWrapperModule.java
index 0bbac3c..a47218b 100644
--- a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/RuntimeServicesModule.java
+++ b/core/runtime-extensions/src/main/java/org/apache/isis/core/wrapper/IsisWrapperModule.java
@@ -16,8 +16,8 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.runtime.services;
+package org.apache.isis.core.wrapper;
 
-public final class RuntimeServicesModule {
+public final class IsisWrapperModule {
 
 }
diff --git a/core/runtime-extensions/src/main/java/org/apache/isis/core/wrapper/WrapperFactoryDefault.java b/core/runtime-extensions/src/main/java/org/apache/isis/core/wrapper/WrapperFactoryDefault.java
index fc288f4..38c5426 100644
--- a/core/runtime-extensions/src/main/java/org/apache/isis/core/wrapper/WrapperFactoryDefault.java
+++ b/core/runtime-extensions/src/main/java/org/apache/isis/core/wrapper/WrapperFactoryDefault.java
@@ -26,11 +26,12 @@ import java.util.List;
 import java.util.Map;
 
 import javax.inject.Inject;
+import javax.inject.Singleton;
 
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.services.factory.FactoryService;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.WrappingObject;
 import org.apache.isis.applib.services.wrapper.events.ActionArgumentEvent;
 import org.apache.isis.applib.services.wrapper.events.ActionInvocationEvent;
 import org.apache.isis.applib.services.wrapper.events.ActionUsabilityEvent;
@@ -48,8 +49,6 @@ import org.apache.isis.applib.services.wrapper.events.PropertyAccessEvent;
 import org.apache.isis.applib.services.wrapper.events.PropertyModifyEvent;
 import org.apache.isis.applib.services.wrapper.events.PropertyUsabilityEvent;
 import org.apache.isis.applib.services.wrapper.events.PropertyVisibilityEvent;
-import org.apache.isis.applib.services.wrapper.WrapperFactory;
-import org.apache.isis.applib.services.wrapper.WrappingObject;
 import org.apache.isis.applib.services.wrapper.listeners.InteractionListener;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.core.metamodel.services.persistsession.PersistenceSessionServiceInternal;
@@ -71,10 +70,7 @@ import org.apache.isis.core.wrapper.proxy.ProxyCreator;
  * <tt>o.a.i.core:isis-core-wrapper</tt> on the classpath, the service is automatically registered; no further
  * configuration is required.
  */
-@DomainService(
-        nature = NatureOfService.DOMAIN,
-        menuOrder = "" + Integer.MAX_VALUE
-        )
+@Singleton
 public class WrapperFactoryDefault implements WrapperFactory {
 
     private final List<InteractionListener> listeners = new ArrayList<InteractionListener>();
diff --git a/core/runtime-extensions/src/main/java/org/apache/isis/runtime/spring/IsisBoot.java b/core/runtime-extensions/src/main/java/org/apache/isis/runtime/spring/IsisBoot.java
index b9259dc..0a07e1a 100644
--- a/core/runtime-extensions/src/main/java/org/apache/isis/runtime/spring/IsisBoot.java
+++ b/core/runtime-extensions/src/main/java/org/apache/isis/runtime/spring/IsisBoot.java
@@ -12,17 +12,19 @@ import org.springframework.context.annotation.FilterType;
 import org.apache.isis.applib.IsisApplibModule;
 import org.apache.isis.commons.internal.context._Context;
 import org.apache.isis.config.AppConfig;
-import org.apache.isis.core.metamodel.MetamodelModule;
-import org.apache.isis.core.runtime.RuntimeModule;
-import org.apache.isis.core.runtime.services.RuntimeServicesModule;
+import org.apache.isis.core.metamodel.IsisMetamodelModule;
+import org.apache.isis.core.runtime.IsisRuntimeModule;
+import org.apache.isis.core.runtime.services.IsisRuntimeServicesModule;
+import org.apache.isis.core.wrapper.IsisWrapperModule;
 
 @Configuration 
 @ComponentScan(
 		basePackageClasses= {
 				IsisApplibModule.class,
-				MetamodelModule.class,
-				RuntimeModule.class,
-				RuntimeServicesModule.class},
+				IsisMetamodelModule.class,
+				IsisRuntimeModule.class,
+				IsisRuntimeServicesModule.class,
+				IsisWrapperModule.class},
 		includeFilters= {
 				@Filter(type = FilterType.CUSTOM, classes= {BeanScanInterceptorForSpring.class})
 		})
diff --git a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/RuntimeServicesModule.java b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/IsisRuntimeServicesModule.java
similarity index 94%
rename from core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/RuntimeServicesModule.java
rename to core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/IsisRuntimeServicesModule.java
index 0bbac3c..f43d56d 100644
--- a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/RuntimeServicesModule.java
+++ b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/IsisRuntimeServicesModule.java
@@ -18,6 +18,6 @@
  */
 package org.apache.isis.core.runtime.services;
 
-public final class RuntimeServicesModule {
+public final class IsisRuntimeServicesModule {
 
 }
diff --git a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/authsess/AuthenticationSessionProviderDefault.java b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/authsess/AuthenticationSessionProviderDefault.java
index 0321983..798e284 100644
--- a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/authsess/AuthenticationSessionProviderDefault.java
+++ b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/authsess/AuthenticationSessionProviderDefault.java
@@ -18,19 +18,15 @@ package org.apache.isis.core.runtime.services.authsess;
 
 import java.util.List;
 
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.applib.annotation.Programmatic;
+import javax.inject.Singleton;
+
 import org.apache.isis.core.metamodel.services.user.UserServiceDefault;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.core.security.authentication.AuthenticationSession;
 import org.apache.isis.core.security.authentication.AuthenticationSessionProvider;
 import org.apache.isis.core.security.authentication.standard.SimpleSession;
 
-@DomainService(
-        nature = NatureOfService.DOMAIN,
-        menuOrder = "" + Integer.MAX_VALUE
-        )
+@Singleton
 public class AuthenticationSessionProviderDefault implements AuthenticationSessionProvider {
 
     /**
@@ -40,7 +36,6 @@ public class AuthenticationSessionProviderDefault implements AuthenticationSessi
      * In particular, we check if there are overrides, and if so return a {@link SimpleSession} to represent those
      * overrides.
      */
-    @Programmatic
     @Override
     public AuthenticationSession getAuthenticationSession() {
 
diff --git a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusImplementationAbstract.java b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusImplementationAbstract.java
index 29fafda..4fdfb0e 100644
--- a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusImplementationAbstract.java
+++ b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusImplementationAbstract.java
@@ -26,6 +26,7 @@ import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
 
+@Deprecated
 public abstract class EventBusImplementationAbstract implements EventBusPlugin {
 
     private static final Logger LOG = LoggerFactory.getLogger(EventBusImplementationAbstract.class);
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceAbstract.java
similarity index 97%
copy from core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
copy to core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceAbstract.java
index d1f2fc9..9f1475c 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/eventbus/EventBusService.java
+++ b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceAbstract.java
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package org.apache.isis.applib.services.eventbus;
+package org.apache.isis.core.runtime.services.eventbus;
 
 import java.util.Collections;
 import java.util.Map;
@@ -46,13 +46,14 @@ import org.apache.isis.core.plugins.eventbus.EventBusPlugin.EventListener;
  *     (keeps things nice and symmetrical).
  * </p>
  */
-public abstract class EventBusService {
+@Deprecated
+public abstract class EventBusServiceAbstract {
 
     /**
      * A no-op implementation to use as a default for domain objects that are being
      * instantiated and for which the event bus service has not yet been injected.
      */
-    public static class Noop extends EventBusService {
+    public static class Noop extends EventBusServiceAbstract {
         @Override
         public void register(Object domainService) {}
         @Override
@@ -67,7 +68,7 @@ public abstract class EventBusService {
         protected EventBusPlugin newEventBus() { return null; }
     }
 
-    public static final EventBusService NOOP = new Noop();
+    public static final EventBusServiceAbstract NOOP = new Noop();
 
     // -- init, shutdown
 
diff --git a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java
index 191ca92..b3a5e97 100644
--- a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java
+++ b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java
@@ -36,7 +36,8 @@ import static org.apache.isis.config.internal._Config.getConfiguration;
 /**
  * Holds common runtime logic for EventBusService implementations.
  */
-public abstract class EventBusServiceDefault extends EventBusService {
+@Deprecated
+public abstract class EventBusServiceDefault extends EventBusServiceAbstract {
 
     public static final String KEY_ALLOW_LATE_REGISTRATION = "isis.services.eventbus.allowLateRegistration";
     public static final String KEY_EVENT_BUS_IMPLEMENTATION = "isis.services.eventbus.implementation";
diff --git a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/xactn/TransactionServiceDefault.java b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/xactn/TransactionServiceDefault.java
index a51a85c..fcd46fe 100644
--- a/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/xactn/TransactionServiceDefault.java
+++ b/core/runtime-services/src/main/java/org/apache/isis/core/runtime/services/xactn/TransactionServiceDefault.java
@@ -22,8 +22,8 @@ package org.apache.isis.core.runtime.services.xactn;
 import java.util.concurrent.CountDownLatch;
 import java.util.function.Supplier;
 
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
+import javax.inject.Singleton;
+
 import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.xactn.Transaction;
 import org.apache.isis.applib.services.xactn.TransactionService;
@@ -34,10 +34,7 @@ import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
 
-@DomainService(
-        nature = NatureOfService.DOMAIN,
-        menuOrder = "" + Integer.MAX_VALUE
-        )
+@Singleton
 public class TransactionServiceDefault implements TransactionService {
 
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/RuntimeModule.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisRuntimeModule.java
similarity index 95%
rename from core/runtime/src/main/java/org/apache/isis/core/runtime/RuntimeModule.java
rename to core/runtime/src/main/java/org/apache/isis/core/runtime/IsisRuntimeModule.java
index fb70dbe..113281e 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/RuntimeModule.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/IsisRuntimeModule.java
@@ -16,6 +16,6 @@
  */
 package org.apache.isis.core.runtime;
 
-public final class RuntimeModule {
+public final class IsisRuntimeModule {
 
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryDefault.java
index 3a66029..e96b5af 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryDefault.java
@@ -84,10 +84,10 @@ public class IsisSessionFactoryDefault implements IsisSessionFactory {
     @Inject private ServiceRegistry serviceRegistry;
     @Inject private AuthenticationManager authenticationManager;
     @Inject private RuntimeEventService runtimeEventService;
+    @Inject private SpecificationLoader specificationLoader;
     
     private IsisLocaleInitializer localeInitializer;
     private IsisTimeZoneInitializer timeZoneInitializer;
-    private SpecificationLoader specificationLoader;
     private ServiceInitializer serviceInitializer;
 
     @PostConstruct
@@ -119,12 +119,9 @@ public class IsisSessionFactoryDefault implements IsisSessionFactory {
 
         serviceRegistry.validateServices();
 
-        this.specificationLoader = new SpecificationLoaderFactory().createSpecificationLoader();
-
         // ... and make IsisSessionFactory available via the IsisContext static for those
         // places where we cannot yet inject.
 
-        _Context.putSingleton(SpecificationLoader.class, specificationLoader);
         _Context.putSingleton(IsisSessionFactory.class, this);
 
         runtimeEventService.fireAppPreMetamodel();
@@ -167,7 +164,7 @@ public class IsisSessionFactoryDefault implements IsisSessionFactory {
 
         runtimeEventService.fireAppPostMetamodel();
 
-        initServicesAndRunFixtures();
+        //initServicesAndRunFixtures();
     }
 
     @Override
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/SpecificationLoaderFactory.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/SpecificationLoaderFactory.java
index ef7ff36..425fdaf 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/SpecificationLoaderFactory.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/SpecificationLoaderFactory.java
@@ -29,7 +29,6 @@ import org.apache.isis.core.metamodel.progmodel.ProgrammingModelAbstract.Depreca
 import org.apache.isis.core.metamodel.specloader.ReflectorConstants;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
-import org.apache.isis.core.runtime.system.IsisSystemException;
 import org.apache.isis.progmodels.dflt.JavaReflectorHelper;
 import org.apache.isis.progmodels.dflt.ProgrammingModelFacetsJava5;
 
@@ -42,8 +41,7 @@ final class SpecificationLoaderFactory {
     
     // -- CREATE SPECIFICATION LOADER
 
-    public SpecificationLoader createSpecificationLoader() 
-            throws IsisSystemException {
+    public SpecificationLoader createSpecificationLoader() {
 
         val metaModelRefiners = MetaModelRefiner.getAll();
         val configuration = getConfiguration();
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/SpecificationLoaderProducerBean.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/SpecificationLoaderProducerBean.java
index 4acaf7e..8c2a774 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/SpecificationLoaderProducerBean.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/SpecificationLoaderProducerBean.java
@@ -20,7 +20,6 @@
 package org.apache.isis.core.runtime.system.session;
 
 import javax.enterprise.inject.Produces;
-import javax.inject.Inject;
 import javax.inject.Singleton;
 
 import org.springframework.context.annotation.Bean;
@@ -43,15 +42,14 @@ import org.apache.isis.core.runtime.system.IsisSystemException;
 @Singleton
 public class SpecificationLoaderProducerBean {
 
-    @Inject IsisSessionFactory isisSessionFactory; // depends on
-    
     // let Spring manage destruction , init is handled by isisSessionFactory internally
 	@Bean(destroyMethod = "shutdown") 
 	@Produces @Singleton 
 	//XXX note: the resulting singleton is not life-cycle managed by CDI/Spring, 
 	//neither are InjectionPoints resolved by CDI/Spring
 	public SpecificationLoader produceSpecificationLoader() throws IsisSystemException {
-	    return _Context.getElseFail(SpecificationLoader.class);
+	    return _Context.computeIfAbsent(SpecificationLoader.class, 
+	            ()-> new SpecificationLoaderFactory().createSpecificationLoader());
 	}
 	
 }
diff --git a/example/application/demo/src/main/java/domainapp/dom/events/EventSubscriber.java b/example/application/demo/src/main/java/domainapp/dom/events/EventSubscriber.java
index a235ac9..635c19a 100644
--- a/example/application/demo/src/main/java/domainapp/dom/events/EventSubscriber.java
+++ b/example/application/demo/src/main/java/domainapp/dom/events/EventSubscriber.java
@@ -21,7 +21,6 @@ package domainapp.dom.events;
 import static domainapp.utils.DemoUtils.emphasize;
 
 import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 
 import org.apache.isis.applib.annotation.DomainService;
@@ -47,15 +46,9 @@ public class EventSubscriber {
 	@PostConstruct
 	public void init() {
 		log.info(emphasize("init"));
-		eventBusService.register(this);
 		eventBusService.post(new EventSubscriberEvent());
 	}
 
-	@PreDestroy
-	public void destroy() {
-		eventBusService.unregister(this);       
-	}
-
 	@Programmatic
 	//@com.google.common.eventbus.Subscribe
 	@org.axonframework.eventhandling.EventHandler