You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@batchee.apache.org by rm...@apache.org on 2018/03/25 16:36:21 UTC

incubator-batchee git commit: BATCHEE-132 ensure ServicesManager represents the 'container' of batchee and defines its lifecycle

Repository: incubator-batchee
Updated Branches:
  refs/heads/master aef149a0a -> 86c407c63


BATCHEE-132 ensure ServicesManager represents the 'container' of batchee and defines its lifecycle


Project: http://git-wip-us.apache.org/repos/asf/incubator-batchee/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-batchee/commit/86c407c6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-batchee/tree/86c407c6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-batchee/diff/86c407c6

Branch: refs/heads/master
Commit: 86c407c632408c5099318890d17feb08fbbd2a2c
Parents: aef149a
Author: Romain Manni-Bucau <rm...@apache.org>
Authored: Sun Mar 25 18:36:10 2018 +0200
Committer: Romain Manni-Bucau <rm...@apache.org>
Committed: Sun Mar 25 18:36:10 2018 +0200

----------------------------------------------------------------------
 .../batchee/container/impl/JobOperatorImpl.java | 75 +++++------------
 .../container/services/ServicesManager.java     | 87 ++++++++++++++++++--
 .../data/DefaultDataRepresentationService.java  |  5 +-
 .../apache/batchee/jmx/BatchEEMBeanImpl.java    | 32 +++----
 .../batchee/servlet/CleanUpWebappListener.java  | 26 ++----
 .../DefaultDataRepresentationServiceTest.java   |  2 +-
 6 files changed, 123 insertions(+), 104 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/86c407c6/jbatch/src/main/java/org/apache/batchee/container/impl/JobOperatorImpl.java
----------------------------------------------------------------------
diff --git a/jbatch/src/main/java/org/apache/batchee/container/impl/JobOperatorImpl.java b/jbatch/src/main/java/org/apache/batchee/container/impl/JobOperatorImpl.java
index af0f54d..9212839 100755
--- a/jbatch/src/main/java/org/apache/batchee/container/impl/JobOperatorImpl.java
+++ b/jbatch/src/main/java/org/apache/batchee/container/impl/JobOperatorImpl.java
@@ -16,18 +16,16 @@
  */
 package org.apache.batchee.container.impl;
 
-import org.apache.batchee.container.Init;
-import org.apache.batchee.container.services.BatchKernelService;
-import org.apache.batchee.container.services.InternalJobExecution;
-import org.apache.batchee.container.services.JobStatusManagerService;
-import org.apache.batchee.container.services.ServicesManager;
-import org.apache.batchee.container.status.JobStatus;
-import org.apache.batchee.jmx.BatchEE;
-import org.apache.batchee.jmx.BatchEEMBean;
-import org.apache.batchee.jmx.BatchEEMBeanImpl;
-import org.apache.batchee.spi.JobExecutionCallbackService;
-import org.apache.batchee.spi.JobXMLLoaderService;
-import org.apache.batchee.spi.PersistenceManagerService;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import javax.batch.operations.JobExecutionAlreadyCompleteException;
 import javax.batch.operations.JobExecutionIsRunningException;
@@ -44,52 +42,23 @@ import javax.batch.runtime.BatchStatus;
 import javax.batch.runtime.JobExecution;
 import javax.batch.runtime.JobInstance;
 import javax.batch.runtime.StepExecution;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import java.io.IOException;
-import java.io.StringWriter;
-import java.lang.management.ManagementFactory;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
-import static org.apache.batchee.container.util.ClassLoaderAwareHandler.makeLoaderAware;
+import org.apache.batchee.container.Init;
+import org.apache.batchee.container.services.BatchKernelService;
+import org.apache.batchee.container.services.InternalJobExecution;
+import org.apache.batchee.container.services.JobStatusManagerService;
+import org.apache.batchee.container.services.ServicesManager;
+import org.apache.batchee.container.status.JobStatus;
+import org.apache.batchee.spi.JobExecutionCallbackService;
+import org.apache.batchee.spi.JobXMLLoaderService;
+import org.apache.batchee.spi.PersistenceManagerService;
 
 
-public class JobOperatorImpl implements JobOperator, AutoCloseable {
+public class JobOperatorImpl implements JobOperator {
     private static final Logger LOGGER = Logger.getLogger(JobOperatorImpl.class.getName());
 
     static {
         Init.doInit();
-
-        if (Boolean.parseBoolean(ServicesManager.value("org.apache.batchee.jmx", "true"))) {
-            try {
-                final MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
-                final String app = ServicesManager.value("org.apache.batchee.jmx.application", "");
-                final ObjectName name;
-                if (app.isEmpty()) {
-                    name = new ObjectName(BatchEEMBean.DEFAULT_OBJECT_NAME);
-                } else {
-                    name = new ObjectName(BatchEEMBean.DEFAULT_OBJECT_NAME + ",application=" + app);
-                }
-
-                if (platformMBeanServer.isRegistered(name)) {
-                    platformMBeanServer.unregisterMBean(name);
-                }
-
-                platformMBeanServer.registerMBean(
-                    new BatchEE(
-                        makeLoaderAware(BatchEEMBean.class, new Class<?>[]{ BatchEEMBean.class }, BatchEEMBeanImpl.INSTANCE)),
-                    name);
-            } catch (final Exception e) {
-                throw new IllegalStateException(e);
-            }
-        }
     }
 
     private final BatchKernelService kernelService;
@@ -115,10 +84,6 @@ public class JobOperatorImpl implements JobOperator, AutoCloseable {
         this(ServicesManager.find());
     }
 
-    public void close() throws Exception {
-
-    }
-
     @Override
     public long start(final String jobXMLName, final Properties jobParameters) throws JobStartException, JobSecurityException {
         /*

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/86c407c6/jbatch/src/main/java/org/apache/batchee/container/services/ServicesManager.java
----------------------------------------------------------------------
diff --git a/jbatch/src/main/java/org/apache/batchee/container/services/ServicesManager.java b/jbatch/src/main/java/org/apache/batchee/container/services/ServicesManager.java
index 4aefa33..bd83689 100755
--- a/jbatch/src/main/java/org/apache/batchee/container/services/ServicesManager.java
+++ b/jbatch/src/main/java/org/apache/batchee/container/services/ServicesManager.java
@@ -17,6 +17,23 @@
  */
 package org.apache.batchee.container.services;
 
+import static org.apache.batchee.container.util.ClassLoaderAwareHandler.makeLoaderAware;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
 import org.apache.batchee.container.exception.BatchContainerRuntimeException;
 import org.apache.batchee.container.exception.BatchContainerServiceException;
 import org.apache.batchee.container.services.callback.SimpleJobExecutionCallbackService;
@@ -31,6 +48,9 @@ import org.apache.batchee.container.services.persistence.MemoryPersistenceManage
 import org.apache.batchee.container.services.status.DefaultJobStatusManager;
 import org.apache.batchee.container.services.transaction.DefaultBatchTransactionService;
 import org.apache.batchee.container.util.BatchContainerConstants;
+import org.apache.batchee.jmx.BatchEE;
+import org.apache.batchee.jmx.BatchEEMBean;
+import org.apache.batchee.jmx.BatchEEMBeanImpl;
 import org.apache.batchee.spi.BatchArtifactFactory;
 import org.apache.batchee.spi.BatchService;
 import org.apache.batchee.spi.BatchThreadPoolService;
@@ -40,15 +60,6 @@ import org.apache.batchee.spi.JobXMLLoaderService;
 import org.apache.batchee.spi.PersistenceManagerService;
 import org.apache.batchee.spi.TransactionManagementService;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
-
 public class ServicesManager implements BatchContainerConstants {
     private final static Logger LOGGER = Logger.getLogger(ServicesManager.class.getName());
 
@@ -77,6 +88,7 @@ public class ServicesManager implements BatchContainerConstants {
 
     private static ServicesManagerLocator servicesManagerLocator;
 
+    private ObjectName jmxName;
     private ClassLoader loader = null;
 
     // designed to be used from app or a server
@@ -147,12 +159,69 @@ public class ServicesManager implements BatchContainerConstants {
 
                     logServices = Boolean.parseBoolean(batchRuntimeConfig.getProperty("batchee.service-manager.log", "false"));
 
+                    if (Boolean.parseBoolean(batchRuntimeConfig.getProperty("org.apache.batchee.jmx", "true"))) {
+                        try {
+                            final MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
+                            final String app = batchRuntimeConfig.getProperty("org.apache.batchee.jmx.application", "");
+                            if (app.isEmpty()) {
+                                jmxName = new ObjectName(BatchEEMBean.DEFAULT_OBJECT_NAME);
+                            } else {
+                                jmxName = new ObjectName(BatchEEMBean.DEFAULT_OBJECT_NAME + ",application=" + app);
+                            }
+
+                            if (!platformMBeanServer.isRegistered(jmxName)) {
+                                platformMBeanServer.registerMBean(
+                                        new BatchEE(
+                                                makeLoaderAware(BatchEEMBean.class, new Class<?>[]{ BatchEEMBean.class },
+                                                        BatchEEMBeanImpl.INSTANCE)),
+                                        jmxName);
+                            } else {
+                                jmxName = null;
+                                LOGGER.warning("You didn't specify org.apache.batchee.jmx.application and JMX is already registered, skipping");
+                            }
+                        } catch (final Exception e) {
+                            throw new IllegalStateException(e);
+                        }
+                    }
+
                     isInited = Boolean.TRUE;
                 }
             }
         }
     }
 
+    public void close() {
+        if (isInited) {
+            synchronized (isInitedLock) {
+                if (isInited) {
+                    service(BatchThreadPoolService.class).shutdown();
+                    synchronized (serviceRegistry) {
+                        for (final Object service : serviceRegistry.values()) {
+                            if (Closeable.class.isInstance(service)) {
+                                try {
+                                    Closeable.class.cast(service).close();
+                                } catch (IOException e) { // don't make it blocking, on j7 we can use suppressed maybe?
+                                    LOGGER.log(Level.SEVERE, e.getMessage(), e);
+                                }
+                            }
+                        }
+                    }
+
+
+                    if (jmxName != null) { // unregister jmx bean if deployed in an app
+                        final MBeanServer jmx = ManagementFactory.getPlatformMBeanServer();
+                        try {
+                            jmx.unregisterMBean(jmxName);
+                        } catch (final Exception e) {
+                            // no-op
+                        }
+                    }
+                    isInited = false;
+                }
+            }
+        }
+    }
+
     public <T extends BatchService> T service(final Class<T> clazz) throws BatchContainerServiceException {
         T service = clazz.cast(serviceRegistry.get(clazz.getName()));
         if (service == null) {

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/86c407c6/jbatch/src/main/java/org/apache/batchee/container/services/data/DefaultDataRepresentationService.java
----------------------------------------------------------------------
diff --git a/jbatch/src/main/java/org/apache/batchee/container/services/data/DefaultDataRepresentationService.java b/jbatch/src/main/java/org/apache/batchee/container/services/data/DefaultDataRepresentationService.java
index 7453059..15eb5ca 100644
--- a/jbatch/src/main/java/org/apache/batchee/container/services/data/DefaultDataRepresentationService.java
+++ b/jbatch/src/main/java/org/apache/batchee/container/services/data/DefaultDataRepresentationService.java
@@ -22,7 +22,6 @@ import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.lang.reflect.Method;
 import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
 import java.sql.Timestamp;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -46,7 +45,7 @@ public class DefaultDataRepresentationService implements DataRepresentationServi
 
     public static final String BATCHEE_DATA_PREFIX = "BatchEE_data" + BATCHEE_SPLIT_TOKEN;
 
-    private static final Charset UTF8_CHARSET = StandardCharsets.UTF_8;
+    private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");
 
     private static final Logger LOGGER = Logger.getLogger(DefaultDataRepresentationService.class.getName());
 
@@ -298,7 +297,7 @@ public class DefaultDataRepresentationService implements DataRepresentationServi
             Class<?> typeClass = getClassLoader().loadClass(typeVal);
             Method method = typeClass.getMethod(methodName, paramType);
             return method.invoke(null, valueVal);
-        } catch (ReflectiveOperationException e) {
+        } catch (Exception e) {
             throw new BatchContainerServiceException("Cannot convert data [" + valueVal + "] of type [" + typeVal + "]", e );
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/86c407c6/jbatch/src/main/java/org/apache/batchee/jmx/BatchEEMBeanImpl.java
----------------------------------------------------------------------
diff --git a/jbatch/src/main/java/org/apache/batchee/jmx/BatchEEMBeanImpl.java b/jbatch/src/main/java/org/apache/batchee/jmx/BatchEEMBeanImpl.java
index b396ee5..108ce42 100644
--- a/jbatch/src/main/java/org/apache/batchee/jmx/BatchEEMBeanImpl.java
+++ b/jbatch/src/main/java/org/apache/batchee/jmx/BatchEEMBeanImpl.java
@@ -41,8 +41,6 @@ import java.util.Set;
 public class BatchEEMBeanImpl implements BatchEEMBean {
     public static final BatchEEMBeanImpl INSTANCE = new BatchEEMBeanImpl();
 
-    private final JobOperator operator = BatchRuntime.getJobOperator();
-
     private static final String[] JOB_INSTANCES_ATTRIBUTES = { "jobName", "instanceId" };
     private static final TabularType JOB_INSTANCES_TABULAR_TYPE;
     private static final CompositeType JOB_INSTANCES_COMPOSITE_TYPE;
@@ -154,20 +152,24 @@ public class BatchEEMBeanImpl implements BatchEEMBean {
         // no-op
     }
 
+    private JobOperator operator() { // lazy since we register jmx with the servicesmanager init
+        return BatchRuntime.getJobOperator();
+    }
+
     @Override
     public String[] getJobNames() {
-        final Set<String> jobNames = operator.getJobNames();
+        final Set<String> jobNames = operator().getJobNames();
         return jobNames.toArray(new String[jobNames.size()]);
     }
 
     @Override
     public int getJobInstanceCount(final String jobName) {
-        return operator.getJobInstanceCount(jobName);
+        return operator().getJobInstanceCount(jobName);
     }
 
     @Override
     public TabularData getJobInstances(final String jobName, final int start, final int count) {
-        final List<JobInstance> instances = operator.getJobInstances(jobName, start, count);
+        final List<JobInstance> instances = operator().getJobInstances(jobName, start, count);
 
         try {
             final TabularDataSupport data = new TabularDataSupport(JOB_INSTANCES_TABULAR_TYPE);
@@ -183,7 +185,7 @@ public class BatchEEMBeanImpl implements BatchEEMBean {
     @Override
     public Long[] getRunningExecutions(final String jobName) {
         try {
-            final List<Long> runningExecutions = operator.getRunningExecutions(jobName);
+            final List<Long> runningExecutions = operator().getRunningExecutions(jobName);
             return runningExecutions.toArray(new Long[runningExecutions.size()]);
         } catch (final NoSuchJobException nsje) {
             return new Long[0];
@@ -192,7 +194,7 @@ public class BatchEEMBeanImpl implements BatchEEMBean {
 
     @Override
     public TabularData getParameters(final long executionId) {
-        final Properties parameters = operator.getParameters(executionId);
+        final Properties parameters = operator().getParameters(executionId);
         try {
             final TabularDataSupport data = new TabularDataSupport(PROPERTIES_TABULAR_TYPE);
             for (final Map.Entry<Object, Object> entry : parameters.entrySet()) {
@@ -206,7 +208,7 @@ public class BatchEEMBeanImpl implements BatchEEMBean {
 
     @Override
     public TabularData getJobInstance(final long executionId) {
-        final JobInstance instance = operator.getJobInstance(executionId);
+        final JobInstance instance = operator().getJobInstance(executionId);
         try {
             final TabularDataSupport data = new TabularDataSupport(JOB_INSTANCES_TABULAR_TYPE);
             data.put(new CompositeDataSupport(JOB_INSTANCES_COMPOSITE_TYPE, JOB_INSTANCES_ATTRIBUTES, new Object[] { instance.getJobName(), instance.getInstanceId() }));
@@ -218,27 +220,27 @@ public class BatchEEMBeanImpl implements BatchEEMBean {
 
     @Override
     public void stop(final long executionId) {
-        operator.stop(executionId);
+        operator().stop(executionId);
     }
 
     @Override
     public void abandon(final long executionId) {
-        operator.abandon(executionId);
+        operator().abandon(executionId);
     }
 
     @Override
     public long start(final String jobXMLName, final String jobParameters) {
-        return operator.start(jobXMLName, toProperties(jobParameters));
+        return operator().start(jobXMLName, toProperties(jobParameters));
     }
 
     @Override
     public long restart(final long executionId, final String restartParameters) {
-        return operator.restart(executionId, toProperties(restartParameters));
+        return operator().restart(executionId, toProperties(restartParameters));
     }
 
     @Override
     public TabularData getJobExecutions(final long id, final String name) {
-        final List<JobExecution> executions = operator.getJobExecutions(new JobInstanceImpl(id, name));
+        final List<JobExecution> executions = operator().getJobExecutions(new JobInstanceImpl(id, name));
         try {
             final TabularDataSupport data = new TabularDataSupport(JOB_EXECUTION_TABULAR_TYPE);
             for (final JobExecution n : executions) {
@@ -252,7 +254,7 @@ public class BatchEEMBeanImpl implements BatchEEMBean {
 
     @Override
     public TabularData getJobExecution(final long executionId) {
-        final JobExecution execution = operator.getJobExecution(executionId);
+        final JobExecution execution = operator().getJobExecution(executionId);
         try {
             final TabularDataSupport data = new TabularDataSupport(JOB_EXECUTION_TABULAR_TYPE);
             data.put(new CompositeDataSupport(JOB_EXECUTION_COMPOSITE_TYPE, JOB_EXECUTION_ATTRIBUTES, asArray(execution)));
@@ -264,7 +266,7 @@ public class BatchEEMBeanImpl implements BatchEEMBean {
 
     @Override
     public TabularData getStepExecutions(final long jobExecutionId) {
-        final List<StepExecution> executions = operator.getStepExecutions(jobExecutionId);
+        final List<StepExecution> executions = operator().getStepExecutions(jobExecutionId);
         try {
             final TabularDataSupport data = new TabularDataSupport(STEP_EXECUTION_TABULAR_TYPE);
             for (final StepExecution n : executions) {

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/86c407c6/jbatch/src/main/java/org/apache/batchee/servlet/CleanUpWebappListener.java
----------------------------------------------------------------------
diff --git a/jbatch/src/main/java/org/apache/batchee/servlet/CleanUpWebappListener.java b/jbatch/src/main/java/org/apache/batchee/servlet/CleanUpWebappListener.java
index 9beef4c..51a3b92 100644
--- a/jbatch/src/main/java/org/apache/batchee/servlet/CleanUpWebappListener.java
+++ b/jbatch/src/main/java/org/apache/batchee/servlet/CleanUpWebappListener.java
@@ -16,16 +16,11 @@
  */
 package org.apache.batchee.servlet;
 
-import org.apache.batchee.container.services.ServicesManager;
-import org.apache.batchee.jmx.BatchEEMBean;
-import org.apache.batchee.spi.BatchThreadPoolService;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
 import javax.servlet.annotation.WebListener;
-import java.lang.management.ManagementFactory;
+
+import org.apache.batchee.container.services.ServicesManager;
 
 @WebListener
 public class CleanUpWebappListener implements ServletContextListener {
@@ -36,20 +31,9 @@ public class CleanUpWebappListener implements ServletContextListener {
 
     @Override
     public void contextDestroyed(final ServletContextEvent sce) {
-        final BatchThreadPoolService threadPoolService = ServicesManager.find().service(BatchThreadPoolService.class);
-        if (CleanUpWebappListener.class.getClassLoader() == sce.getServletContext().getClassLoader()) {
-            threadPoolService.shutdown();
-
-            // unregister jmx bean if deployed in an app
-            final MBeanServer jmx = ManagementFactory.getPlatformMBeanServer();
-            try {
-                final ObjectName objectName = new ObjectName(BatchEEMBean.DEFAULT_OBJECT_NAME);
-                if (jmx.isRegistered(objectName)) {
-                    jmx.unregisterMBean(objectName);
-                }
-            } catch (final Exception e) {
-                // no-op
-            }
+        final ServicesManager servicesManager = ServicesManager.find();
+        if (ServicesManager.class.getClassLoader() == sce.getServletContext().getClassLoader()) {
+            servicesManager.close();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-batchee/blob/86c407c6/jbatch/src/test/java/org/apache/batchee/test/data/DefaultDataRepresentationServiceTest.java
----------------------------------------------------------------------
diff --git a/jbatch/src/test/java/org/apache/batchee/test/data/DefaultDataRepresentationServiceTest.java b/jbatch/src/test/java/org/apache/batchee/test/data/DefaultDataRepresentationServiceTest.java
index e5fba15..617f9db 100644
--- a/jbatch/src/test/java/org/apache/batchee/test/data/DefaultDataRepresentationServiceTest.java
+++ b/jbatch/src/test/java/org/apache/batchee/test/data/DefaultDataRepresentationServiceTest.java
@@ -129,7 +129,7 @@ public class DefaultDataRepresentationServiceTest {
             Class<?> clazz = Class.forName(className);
             Method now = clazz.getMethod("now");
             return now.invoke(null);
-        } catch (ReflectiveOperationException e) {
+        } catch (Exception e) {
             // all fine, we are just not running on java8
         }
         return null;