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 2020/09/02 22:00:17 UTC

[isis] 17/17: ISIS-2222: now runs, though background commands broken

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

danhaywood pushed a commit to branch ISIS-2222
in repository https://gitbox.apache.org/repos/asf/isis.git

commit f0c523370920f526e760fef83026a34c70c4b9e0
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Sep 2 22:59:24 2020 +0100

    ISIS-2222: now runs, though background commands broken
---
 .../apache/isis/core/config/IsisConfiguration.java | 13 +++-
 .../command/CommandDtoServiceInternalDefault.java  | 14 ++--
 .../Action/command/ActionCommandJdo.java           | 13 +++-
 .../demo/domain/src/main/resources/application.yml |  5 +-
 examples/demo/web/pom.xml                          |  6 ++
 .../src/main/java/demoapp/web/DemoAppManifest.java | 11 +++-
 .../web/quartz/AutowiringSpringBeanJobFactory.java | 30 +++++++++
 ...ackgroundCommandsQuartzJobConfigurerModule.java | 77 ++++++++++++++++++++++
 .../java/demoapp/webapp/wicket/DemoAppWicket.java  |  3 +-
 .../impl/IsisModuleExtCommandLogImpl.java          |  6 ++
 .../BackgroundCommandServiceJdoRepository.java     | 12 +++-
 .../extensions/commandlog/impl/jdo/CommandJdo.java | 48 +++++++-------
 .../commandlog/impl/jdo/CommandServiceJdo.java     |  6 +-
 .../impl/jdo/CommandServiceJdoRepository.java      | 26 +++-----
 .../commandlog/impl/ui/CommandServiceMenu.java     | 13 ++--
 .../quartz/jobs/RunBackgroundCommandsJob.java      | 18 ++---
 16 files changed, 227 insertions(+), 74 deletions(-)

diff --git a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
index 5df2204..e17dacb 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
@@ -2058,7 +2058,7 @@ public class IsisConfiguration {
             /**
              * The base path at which the Wicket viewer is mounted.
              */
-            @javax.validation.constraints.Pattern(regexp="^[/].*[/]$") @NotNull @NotEmpty
+            @javax.validation.constraints.Pattern(regexp="^[/](.*[/]|)$") @NotNull @NotEmpty
             private String basePath = "/wicket/";
 
             /**
@@ -3059,6 +3059,17 @@ public class IsisConfiguration {
             private List<String> exposedHeaders = listOf("Authorization");
         }
 
+        private final Quartz quartz = new Quartz();
+        @Data
+        public static class Quartz {
+            private final RunBackgroundCommands runBackgroundCommands = new RunBackgroundCommands();
+            @Data
+            public static class RunBackgroundCommands {
+                private String user = "isisModuleExtQuartzRunBackgroundCommandsUser";
+                private List<String> roles = listOf("isisModuleExtQuartzRunBackgroundCommandsRole");
+            }
+        }
+
         private final CommandReplay commandReplay = new CommandReplay();
         @Data
         public static class CommandReplay {
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoServiceInternalDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoServiceInternalDefault.java
index e33e91b..12da090 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoServiceInternalDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandDtoServiceInternalDefault.java
@@ -161,17 +161,17 @@ public class CommandDtoServiceInternalDefault implements CommandDtoServiceIntern
             final PropertyDto propertyDto,
             final ManagedObject valueAdapter) {
 
-        final String actionIdentifier = CommandUtil.memberIdentifierFor(property);
-        final ObjectSpecification onType = property.getOnType();
-        final String objectType = onType.getSpecId().asString();
-        final String localId = property.getIdentifier().toNameIdentityString();
+        val actionIdentifier = CommandUtil.memberIdentifierFor(property);
+        val onType = property.getOnType();
+        val objectType = onType.getSpecId().asString();
+        val localId = property.getIdentifier().toNameIdentityString();
         propertyDto.setLogicalMemberIdentifier(objectType + "#" + localId);
         propertyDto.setMemberIdentifier(actionIdentifier);
 
-        final ObjectSpecification valueSpec = property.getSpecification();
-        final Class<?> valueType = valueSpec.getCorrespondingClass();
+        val valueSpec = property.getSpecification();
+        val valueType = valueSpec.getCorrespondingClass();
 
-        final ValueWithTypeDto newValue = CommonDtoUtils.newValueWithTypeDto(
+        val newValue = CommonDtoUtils.newValueWithTypeDto(
                 valueType, UnwrapUtil.single(valueAdapter), bookmarkService);
         propertyDto.setNewValue(newValue);
     }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo.java b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo.java
index 3d1745d..a385c5c 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/annotDomain/Action/command/ActionCommandJdo.java
@@ -18,6 +18,9 @@
  */
 package demoapp.dom.annotDomain.Action.command;
 
+import java.util.concurrent.ExecutorService;
+
+import javax.inject.Inject;
 import javax.jdo.annotations.DatastoreIdentity;
 import javax.jdo.annotations.IdGeneratorStrategy;
 import javax.jdo.annotations.IdentityType;
@@ -35,6 +38,8 @@ import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.Publishing;
 import org.apache.isis.applib.annotation.SemanticsOf;
+import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.applib.services.wrapper.control.AsyncControl;
 
 import lombok.Getter;
 import lombok.Setter;
@@ -161,15 +166,21 @@ public class ActionCommandJdo implements HasAsciiDocDescription {
             "@Action(command = ENABLED, commandExecuteIn = BACKGROUND)"
     )
     public ActionCommandJdo updatePropertyInBackground(final String value) {
-        setPropertyUpdateInBackground(value);
+        AsyncControl<Void> control = AsyncControl.control();
+        ActionCommandJdo actionCommandJdo = this.wrapperFactory.asyncWrap(this, control);
+        actionCommandJdo.updatePropertyUsingAnnotation(value);
+        // setPropertyUpdateInBackground(value);
         return this;
     }
     public String default0UpdatePropertyInBackground() {
         return getPropertyUpdateInBackground();
     }
+
+    @Inject WrapperFactory wrapperFactory;
 //end::background[]
 
 
 //tag::class[]
+
 }
 //end::class[]
diff --git a/examples/demo/domain/src/main/resources/application.yml b/examples/demo/domain/src/main/resources/application.yml
index b24f0c1..f8abeb7 100644
--- a/examples/demo/domain/src/main/resources/application.yml
+++ b/examples/demo/domain/src/main/resources/application.yml
@@ -127,7 +127,10 @@ server:
 spring:
   banner:
     location: banner.txt
-    
+
+  quartz:
+    job-store-type: memory
+
 vaadin:
   compatibilityMode: false
   whitelisted-packages: com.vaadin
diff --git a/examples/demo/web/pom.xml b/examples/demo/web/pom.xml
index 552c40f..c7f5253 100644
--- a/examples/demo/web/pom.xml
+++ b/examples/demo/web/pom.xml
@@ -57,6 +57,12 @@
 			<artifactId>isis-extensions-cors-impl</artifactId>
 		</dependency>
 
+		<!-- Extensions -->
+		<dependency>
+			<groupId>org.apache.isis.extensions</groupId>
+			<artifactId>isis-extensions-quartz-impl</artifactId>
+		</dependency>
+
 	</dependencies>
 
 </project>
\ No newline at end of file
diff --git a/examples/demo/web/src/main/java/demoapp/web/DemoAppManifest.java b/examples/demo/web/src/main/java/demoapp/web/DemoAppManifest.java
index ca51477..2029608 100644
--- a/examples/demo/web/src/main/java/demoapp/web/DemoAppManifest.java
+++ b/examples/demo/web/src/main/java/demoapp/web/DemoAppManifest.java
@@ -26,7 +26,9 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
+import org.apache.isis.extensions.commandlog.impl.IsisModuleExtCommandLogImpl;
 import org.apache.isis.extensions.cors.impl.IsisModuleExtCorsImpl;
+import org.apache.isis.extensions.quartz.IsisModuleExtQuartzImpl;
 import org.apache.isis.extensions.secman.encryption.jbcrypt.IsisModuleExtSecmanEncryptionJbcrypt;
 import org.apache.isis.extensions.secman.jdo.IsisModuleExtSecmanPersistenceJdo;
 import org.apache.isis.extensions.secman.model.IsisModuleExtSecmanModel;
@@ -42,14 +44,21 @@ import lombok.extern.log4j.Log4j2;
 
 import demoapp.dom.DemoModule;
 import demoapp.dom._infra.fixtures.DemoFixtureScript;
+import demoapp.web.quartz.BackgroundCommandsQuartzJobConfigurerModule;
 
 /**
  * Makes the integral parts of the 'demo' web application.
  */
 @Configuration
 @Import({
+    // @Configuration's
     DemoModule.class, // shared demo core module
-    
+
+    // background commands
+    BackgroundCommandsQuartzJobConfigurerModule.class,
+    IsisModuleExtCommandLogImpl.class,
+    IsisModuleExtQuartzImpl.class,
+
     // SECURITY
     IsisModuleSecurityShiro.class,
 
diff --git a/examples/demo/web/src/main/java/demoapp/web/quartz/AutowiringSpringBeanJobFactory.java b/examples/demo/web/src/main/java/demoapp/web/quartz/AutowiringSpringBeanJobFactory.java
new file mode 100644
index 0000000..105309d
--- /dev/null
+++ b/examples/demo/web/src/main/java/demoapp/web/quartz/AutowiringSpringBeanJobFactory.java
@@ -0,0 +1,30 @@
+package demoapp.web.quartz;
+
+import org.quartz.spi.TriggerFiredBundle;
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.scheduling.quartz.SpringBeanJobFactory;
+
+final class AutowiringSpringBeanJobFactory
+        extends SpringBeanJobFactory
+        implements ApplicationContextAware {
+
+    private transient AutowireCapableBeanFactory beanFactory;
+
+    public void setApplicationContext(
+            final ApplicationContext context) {
+        beanFactory = context.getAutowireCapableBeanFactory();
+    }
+
+    @Override
+    protected Object createJobInstance(
+            final TriggerFiredBundle bundle)
+            throws Exception {
+        final Object job = super.createJobInstance(bundle);
+        beanFactory.autowireBean(job);
+        return job;
+    }
+
+
+}
diff --git a/examples/demo/web/src/main/java/demoapp/web/quartz/BackgroundCommandsQuartzJobConfigurerModule.java b/examples/demo/web/src/main/java/demoapp/web/quartz/BackgroundCommandsQuartzJobConfigurerModule.java
new file mode 100644
index 0000000..7144c2f
--- /dev/null
+++ b/examples/demo/web/src/main/java/demoapp/web/quartz/BackgroundCommandsQuartzJobConfigurerModule.java
@@ -0,0 +1,77 @@
+package demoapp.web.quartz;
+
+import javax.inject.Inject;
+
+import org.quartz.Job;
+import org.quartz.JobBuilder;
+import org.quartz.JobDataMap;
+import org.quartz.JobDetail;
+import org.quartz.JobKey;
+import org.quartz.SimpleTrigger;
+import org.quartz.Trigger;
+import org.quartz.spi.TriggerFiredBundle;
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.scheduling.quartz.JobDetailFactoryBean;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
+import org.springframework.scheduling.quartz.SpringBeanJobFactory;
+import org.springframework.stereotype.Service;
+
+import org.apache.isis.extensions.quartz.jobs.RunBackgroundCommandsJob;
+
+import lombok.val;
+import lombok.extern.log4j.Log4j2;
+
+@Configuration
+@Log4j2
+public class BackgroundCommandsQuartzJobConfigurerModule {
+
+    @Bean
+    public JobDetailFactoryBean jobDetail() {
+        val jobDetailFactory = new JobDetailFactoryBean();
+        jobDetailFactory.setJobClass(RunBackgroundCommandsJob.class);
+        jobDetailFactory.setDescription("Run background commands");
+        jobDetailFactory.setDurability(true);
+        return jobDetailFactory;
+    }
+
+    @Bean
+    public SimpleTriggerFactoryBean trigger(JobDetail job) {
+        val triggerFactory = new SimpleTriggerFactoryBean();
+        triggerFactory.setJobDetail(job);
+        triggerFactory.setRepeatInterval(10000); // 10seconds
+        triggerFactory.setStartDelay(15000);     // 15 seconds approx boot up time
+        triggerFactory.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
+        return triggerFactory;
+    }
+
+    @Bean
+    public SchedulerFactoryBean scheduler(Trigger trigger, JobDetail job, SpringBeanJobFactory springBeanJobFactory) {
+        val schedulerFactory = new SchedulerFactoryBean();
+        // schedulerFactory.setConfigLocation(new ClassPathResource("quartz.properties"));
+
+        schedulerFactory.setJobFactory(springBeanJobFactory);
+        schedulerFactory.setJobDetails(job);
+
+        schedulerFactory.setTriggers(trigger);
+
+        return schedulerFactory;
+    }
+
+    @Bean
+    public SpringBeanJobFactory springBeanJobFactory() {
+        val jobFactory = new AutowiringSpringBeanJobFactory();
+        jobFactory.setApplicationContext(applicationContext);
+        return jobFactory;
+    }
+
+    @Inject ApplicationContext applicationContext;
+}
+
diff --git a/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/DemoAppWicket.java b/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/DemoAppWicket.java
index 8e172b4..8f19227 100644
--- a/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/DemoAppWicket.java
+++ b/examples/demo/wicket/src/main/java/demoapp/webapp/wicket/DemoAppWicket.java
@@ -23,6 +23,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
 import org.springframework.context.annotation.Import;
 
+import org.apache.isis.extensions.quartz.IsisModuleExtQuartzImpl;
 import org.apache.isis.extensions.viewer.wicket.pdfjs.ui.IsisModuleExtPdfjsUi;
 import org.apache.isis.valuetypes.asciidoc.metamodel.IsisModuleValAsciidocMetaModel;
 import org.apache.isis.valuetypes.asciidoc.persistence.jdo.dn5.IsisModuleValAsciidocPersistenceJdoDn5;
@@ -53,7 +54,7 @@ import demoapp.web._infra.utils.ThereCanBeOnlyOne;
     IsisModuleExtPdfjsUi.class,
 
     // Persistence (JDO/DN5)
-    IsisModuleValAsciidocPersistenceJdoDn5.class,   //
+    IsisModuleValAsciidocPersistenceJdoDn5.class,
     IsisModuleValMarkdownPersistenceJdoDn5.class,
 
 })
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/IsisModuleExtCommandLogImpl.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/IsisModuleExtCommandLogImpl.java
index 58ab3c6..991b53d 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/IsisModuleExtCommandLogImpl.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/IsisModuleExtCommandLogImpl.java
@@ -1,8 +1,10 @@
 package org.apache.isis.extensions.commandlog.impl;
 
+import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
+import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandServiceJdo;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandServiceJdoRepository;
@@ -25,6 +27,10 @@ import org.apache.isis.extensions.commandlog.impl.background.BackgroundCommandSe
         , CommandServiceJdoRepository.class
         , CommandServiceMenu.class
 })
+@ComponentScan(
+        basePackageClasses= {
+                IsisModuleExtCommandLogImpl.class
+        })
 public class IsisModuleExtCommandLogImpl implements ModuleWithFixtures {
 
     public abstract static class ActionDomainEvent<S>
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/background/BackgroundCommandServiceJdoRepository.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/background/BackgroundCommandServiceJdoRepository.java
index 5b81684..2195292 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/background/BackgroundCommandServiceJdoRepository.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/background/BackgroundCommandServiceJdoRepository.java
@@ -3,11 +3,16 @@ package org.apache.isis.extensions.commandlog.impl.background;
 import java.util.List;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandServiceJdoRepository;
@@ -24,16 +29,17 @@ import lombok.extern.log4j.Log4j2;
  * thus has been annotated with {@link org.apache.isis.applib.annotation.DomainService}.  This means that there is no
  * need to explicitly register it as a service (eg in <tt>isis.properties</tt>).
  */
-@DomainService()
+@Service()
+@Named("isisExtensionsCommandLog.BackgroundCommandServiceJdoRepository")
+@Order(OrderPrecedence.MIDPOINT)
+@Qualifier("Jdo")
 @Log4j2
 public class BackgroundCommandServiceJdoRepository {
 
-    @Programmatic
     public List<CommandJdo> findByParent(CommandJdo parent) {
         return commandServiceRepository.findBackgroundCommandsByParent(parent);
     }
 
-    @Programmatic
     public List<CommandJdo> findBackgroundCommandsNotYetStarted() {
         return commandServiceRepository.findBackgroundCommandsNotYetStarted();
     }
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java
index baf6f58..2862b06 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdo.java
@@ -48,37 +48,37 @@ import lombok.extern.log4j.Log4j2;
 
 @javax.jdo.annotations.PersistenceCapable(
         identityType=IdentityType.APPLICATION,
-        schema = "isiscoreextcommandlog",
+        schema = "isisextcommandlog",
         table = "Command")
 @javax.jdo.annotations.Queries( {
     @javax.jdo.annotations.Query(
             name="findByTransactionId",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE transactionId == :transactionId "),
     @javax.jdo.annotations.Query(
             name="findBackgroundCommandsByParent",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE parent == :parent "
                     + "&& executeIn == 'BACKGROUND'"),
     @javax.jdo.annotations.Query(
             name="findCurrent",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE completedAt == null "
                     + "ORDER BY this.timestamp DESC"),
     @javax.jdo.annotations.Query(
             name="findCompleted",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE completedAt != null "
                     + "&& executeIn == 'FOREGROUND' "
                     + "ORDER BY this.timestamp DESC"),
     @javax.jdo.annotations.Query(
             name="findRecentBackgroundByTarget",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE targetStr == :targetStr "
                     + "&& executeIn == 'BACKGROUND' "
                     + "ORDER BY this.timestamp DESC, transactionId DESC "
@@ -86,7 +86,7 @@ import lombok.extern.log4j.Log4j2;
     @javax.jdo.annotations.Query(
             name="findByTargetAndTimestampBetween",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE targetStr == :targetStr " 
                     + "&& timestamp >= :from " 
                     + "&& timestamp <= :to "
@@ -94,65 +94,65 @@ import lombok.extern.log4j.Log4j2;
     @javax.jdo.annotations.Query(
             name="findByTargetAndTimestampAfter",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE targetStr == :targetStr " 
                     + "&& timestamp >= :from "
                     + "ORDER BY this.timestamp DESC"),
     @javax.jdo.annotations.Query(
             name="findByTargetAndTimestampBefore",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE targetStr == :targetStr " 
                     + "&& timestamp <= :to "
                     + "ORDER BY this.timestamp DESC"),
     @javax.jdo.annotations.Query(
             name="findByTarget",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE targetStr == :targetStr " 
                     + "ORDER BY this.timestamp DESC"),
     @javax.jdo.annotations.Query(
             name="findByTimestampBetween",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE timestamp >= :from " 
                     + "&&    timestamp <= :to "
                     + "ORDER BY this.timestamp DESC"),
     @javax.jdo.annotations.Query(
             name="findByTimestampAfter",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE timestamp >= :from "
                     + "ORDER BY this.timestamp DESC"),
     @javax.jdo.annotations.Query(
             name="findByTimestampBefore",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE timestamp <= :to "
                     + "ORDER BY this.timestamp DESC"),
     @javax.jdo.annotations.Query(
             name="find",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "ORDER BY this.timestamp DESC"),
     @javax.jdo.annotations.Query(
             name="findRecentByUser",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE user == :user "
                     + "ORDER BY this.timestamp DESC "
                     + "RANGE 0,30"),
     @javax.jdo.annotations.Query(
             name="findRecentByTarget",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE targetStr == :targetStr "
                     + "ORDER BY this.timestamp DESC, transactionId DESC "
                     + "RANGE 0,30"),
     @javax.jdo.annotations.Query(
             name="findForegroundFirst",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE executeIn == 'FOREGROUND' "
                     + "   && timestamp   != null "
                     + "   && startedAt   != null "
@@ -164,7 +164,7 @@ import lombok.extern.log4j.Log4j2;
     @javax.jdo.annotations.Query(
             name="findForegroundSince",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE executeIn == 'FOREGROUND' "
                     + "   && timestamp > :timestamp "
                     + "   && startedAt != null "
@@ -173,7 +173,7 @@ import lombok.extern.log4j.Log4j2;
     @javax.jdo.annotations.Query(
             name="findReplayableHwm",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE executeIn == 'REPLAYABLE' "
                     + "ORDER BY this.timestamp DESC "
                     + "RANGE 0,2"),
@@ -182,7 +182,7 @@ import lombok.extern.log4j.Log4j2;
     @javax.jdo.annotations.Query(
             name="findForegroundHwm",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE executeIn == 'FOREGROUND' "
                     + "   && startedAt   != null "
                     + "   && completedAt != null "
@@ -193,14 +193,14 @@ import lombok.extern.log4j.Log4j2;
     @javax.jdo.annotations.Query(
             name="findBackgroundCommandsNotYetStarted",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE executeIn == 'BACKGROUND' "
                     + "   && startedAt == null "
                     + "ORDER BY this.timestamp ASC "),
         @javax.jdo.annotations.Query(
                 name="findReplayableInErrorMostRecent",
                 value="SELECT "
-                        + "FROM CommandJdo "
+                        + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                         + "WHERE executeIn   == 'REPLAYABLE' "
                         + "  && (replayState != 'PENDING' || "
                         + "      replayState != 'OK'      || "
@@ -210,7 +210,7 @@ import lombok.extern.log4j.Log4j2;
     @javax.jdo.annotations.Query(
             name="findReplayableMostRecentStarted",
             value="SELECT "
-                    + "FROM CommandJdo "
+                    + "FROM org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo "
                     + "WHERE executeIn == 'REPLAYABLE' "
                     + "   && startedAt != null "
                     + "ORDER BY this.timestamp DESC "
@@ -221,7 +221,7 @@ import lombok.extern.log4j.Log4j2;
         @javax.jdo.annotations.Index(name = "CommandJdo_startedAt_e_c_IDX", members = {"startedAt", "executeIn", "completedAt"}),
 })
 @DomainObject(
-        objectType = "isisextcommandlog.Command",
+        objectType = "isisExtensionsCommandLog.Command",
         editing = Editing.DISABLED
 )
 @DomainObjectLayout(named = "Command")
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandServiceJdo.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandServiceJdo.java
index 4072f65..75e2dd2 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandServiceJdo.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandServiceJdo.java
@@ -20,15 +20,15 @@ import org.apache.isis.applib.services.command.spi.CommandService;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.repository.RepositoryService;
 
+import lombok.extern.log4j.Log4j2;
+
 @Service
 @Named("isisExtensionsCommandLog.CommandServiceJdo")
 @Order(OrderPrecedence.MIDPOINT)
 @Qualifier("Jdo")
+@Log4j2
 public class CommandServiceJdo implements CommandService {
 
-    @SuppressWarnings("unused")
-    private static final Logger LOG = LoggerFactory.getLogger(CommandServiceJdo.class);
-
     /**
      * {@inheritDoc}
      */
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandServiceJdoRepository.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandServiceJdoRepository.java
index 70d2cf9..61eae44 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandServiceJdoRepository.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandServiceJdoRepository.java
@@ -8,14 +8,15 @@ import java.util.Optional;
 import java.util.UUID;
 
 
+import javax.inject.Inject;
 import javax.inject.Named;
+import javax.inject.Provider;
 
 import org.joda.time.LocalDate;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
-import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
@@ -27,8 +28,6 @@ import org.apache.isis.applib.services.command.CommandContext;
 import org.apache.isis.applib.services.command.CommandWithDto;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.util.schema.CommandDtoUtils;
-import org.apache.isis.extensions.commandlog.impl.jdo.QCommandJdo;
-import org.apache.isis.extensions.commandlog.impl.jdo.ReplayState;
 import org.apache.isis.persistence.jdo.applib.services.IsisJdoSupport_v3_2;
 import org.apache.isis.schema.cmd.v2.CommandDto;
 import org.apache.isis.schema.cmd.v2.CommandsDto;
@@ -37,6 +36,7 @@ import org.apache.isis.schema.common.v2.OidDto;
 
 import lombok.val;
 import lombok.var;
+import lombok.extern.log4j.Log4j2;
 
 /**
  * Provides supporting functionality for querying and persisting
@@ -46,6 +46,7 @@ import lombok.var;
 @Named("isisExtensionsCommandLog.CommandServiceJdoRepository")
 @Order(OrderPrecedence.MIDPOINT)
 @Qualifier("Jdo")
+@Log4j2
 public class CommandServiceJdoRepository {
 
     public List<CommandJdo> findByFromAndTo(
@@ -103,10 +104,10 @@ public class CommandServiceJdoRepository {
 
 
     private void persistCurrentCommandIfRequired() {
-        if(commandContext == null || commandService == null) {
+        if(commandContextProvider == null || commandService == null) {
             return;
         } 
-        final Command command = commandContext.getCommand();
+        final Command command = commandContextProvider.get().getCommand();
         final CommandJdo commandJdo = commandService.asUserInitiatedCommandJdo(command);
         if(commandJdo == null) {
             return;
@@ -364,16 +365,9 @@ public class CommandServiceJdoRepository {
 
 
 
-    @javax.inject.Inject
-    CommandServiceJdo commandService;
-
-    @javax.inject.Inject
-    CommandContext commandContext;
-
-    @javax.inject.Inject
-    RepositoryService repositoryService;
-
-    @javax.inject.Inject
-    IsisJdoSupport_v3_2 isisJdoSupport;
+    @Inject CommandServiceJdo commandService;
+    @Inject Provider<CommandContext> commandContextProvider;
+    @Inject RepositoryService repositoryService;
+    @Inject IsisJdoSupport_v3_2 isisJdoSupport;
 
 }
diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/ui/CommandServiceMenu.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/ui/CommandServiceMenu.java
index 2958364..f03d94b 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/ui/CommandServiceMenu.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/ui/CommandServiceMenu.java
@@ -29,15 +29,15 @@ import org.apache.isis.extensions.commandlog.impl.jdo.CommandJdo;
 import org.apache.isis.extensions.commandlog.impl.jdo.CommandServiceJdoRepository;
 
 @DomainService(
-        nature = NatureOfService.VIEW,
-        objectType = "isisextcommandlog.CommandServiceMenu"
+    nature = NatureOfService.VIEW,
+    objectType = "isisExtensionsCommandLog.CommandServiceMenu"
 )
 @DomainServiceLayout(
-        named = "Activity"
-        , menuBar = DomainServiceLayout.MenuBar.SECONDARY
+    named = "Activity"
+    , menuBar = DomainServiceLayout.MenuBar.SECONDARY
 )
 @Service
-@Named("isisExtensionsCommandLog.CommandServiceJdoRepository")
+@Named("isisExtensionsCommandLog.CommandServiceMenu")
 @Order(OrderPrecedence.MIDPOINT)
 @Qualifier("Jdo")
 public class CommandServiceMenu {
@@ -101,10 +101,7 @@ public class CommandServiceMenu {
     }
 
 
-
     @Inject CommandServiceJdoRepository commandServiceRepository;
-
     @Inject ClockService clockService;
-
 }
 
diff --git a/extensions/core/quartz/impl/src/main/java/org/apache/isis/extensions/quartz/jobs/RunBackgroundCommandsJob.java b/extensions/core/quartz/impl/src/main/java/org/apache/isis/extensions/quartz/jobs/RunBackgroundCommandsJob.java
index cf640f2..c0391b8 100644
--- a/extensions/core/quartz/impl/src/main/java/org/apache/isis/extensions/quartz/jobs/RunBackgroundCommandsJob.java
+++ b/extensions/core/quartz/impl/src/main/java/org/apache/isis/extensions/quartz/jobs/RunBackgroundCommandsJob.java
@@ -1,11 +1,14 @@
 package org.apache.isis.extensions.quartz.jobs;
 
 
+import javax.inject.Inject;
+
 import com.google.common.base.Splitter;
 
 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
 
+import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.core.security.authentication.AuthenticationSession;
 import org.apache.isis.core.security.authentication.standard.SimpleSession;
 
@@ -22,19 +25,18 @@ public class RunBackgroundCommandsJob implements Job {
         final AuthenticationSession authSession = newAuthSession(context);
 
         log.debug("Running background commands");
-        new BackgroundCommandExecutionFromBackgroundCommandServiceJdo().execute(authSession, null);
-    }
-
-    protected String getKey(JobExecutionContext context, String key) {
-        return context.getMergedJobDataMap().getString(key);
+        backgroundCommandExecutionFromBackgroundCommandServiceJdo.execute(authSession, null);
     }
 
     protected AuthenticationSession newAuthSession(JobExecutionContext context) {
-        val user = getKey(context, "user");
-        val rolesStr = getKey(context, "roles");
-        val roles = Splitter.on(",").split(rolesStr);
+        val user = isisConfiguration.getExtensions().getQuartz().getRunBackgroundCommands().getUser();
+        val roles = isisConfiguration.getExtensions().getQuartz().getRunBackgroundCommands().getRoles();
+        log.debug("background user : {}", user);
+        log.debug("background roles: {}", roles);
         return new SimpleSession(user, roles);
     }
 
+    @Inject BackgroundCommandExecutionFromBackgroundCommandServiceJdo backgroundCommandExecutionFromBackgroundCommandServiceJdo;
+    @Inject IsisConfiguration isisConfiguration;
 
 }