You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ta...@apache.org on 2016/10/16 09:07:09 UTC

svn commit: r1765127 [1/2] - in /ofbiz/trunk: framework/base/src/main/java/org/apache/ofbiz/base/component/ framework/base/src/main/java/org/apache/ofbiz/base/container/ framework/base/src/main/java/org/apache/ofbiz/base/lang/ framework/base/src/main/j...

Author: taher
Date: Sun Oct 16 09:07:08 2016
New Revision: 1765127

URL: http://svn.apache.org/viewvc?rev=1765127&view=rev
Log:
Improved: Refactor and simplify the startup sequence in OFBiz
(OFBIZ-8337)

This is a major refactoring exercise to simplify the startup sequence in
OFBiz. There are no functional changes, however, both the logic and the
API signatures of the core classes in OFBiz are changed to help simplify
the startup sequence. The changes insofar are summarized as:

- Rename ContainerConfig.Container to ContainerConfig.Configuration, the old
  nameing was very confusing as it confuses it with actual containers
- Change the signature of ContainerLoader and Container to accept
  List<StartupCommand> instead of String[]. And also migrate the adapter for
  converting these args into a standalone class called
  StartupCommandsToArgsAdapter
- Remove the LockedBy annotation as it is not used
- Substantially simplify the ContainerLoader load and unload logic and delete
  the start logic (merge it with load). The interface StartupLoader was updated
  accordingly
- Remove old logic to load containers in hot-deploy components
- Remove printThreadDump output from ContainerLoader which used to exist for
  debugging purposes and is no longer necessary
- Cleanup the AdminServer startup logic
- Change the StartupControlPanel logic to use only one StartupLoader instead
  of a list. The only implementation is ContainerLoader
- Remove the synchronized blocks in StartupControlPanel due to having only one
  loader
- Update the startup .properties files to reflect the changes in the startup
  logic
- Update the TestRunContainer to use List<StartupCommand> in its logic

We expect more commits (specifically to the containers) to complete this
refactoring initiative


Added:
    ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/StartupCommandToArgsAdapter.java   (with props)
Removed:
    ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/lang/LockedBy.java
Modified:
    ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/component/ComponentConfig.java
    ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ComponentContainer.java
    ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/Container.java
    ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ContainerConfig.java
    ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ContainerLoader.java
    ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/JustLoadComponentsContainer.java
    ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/NamingServiceContainer.java
    ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/metrics/MetricsFactory.java
    ofbiz/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java
    ofbiz/trunk/framework/entity/src/main/java/org/apache/ofbiz/entity/DelegatorContainer.java
    ofbiz/trunk/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataLoadContainer.java
    ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/ServiceContainer.java
    ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/mail/JavaMailContainer.java
    ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/rmi/RmiServiceContainer.java
    ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/AdminClient.java
    ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/AdminServer.java
    ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java
    ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupCommand.java
    ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupCommandUtil.java
    ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupControlPanel.java
    ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupLoader.java
    ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/load-data.properties
    ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/rmi.properties
    ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/start.properties
    ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/test.properties
    ofbiz/trunk/framework/testtools/src/main/java/org/apache/ofbiz/testtools/TestRunContainer.java
    ofbiz/trunk/framework/webtools/src/main/java/org/apache/ofbiz/webtools/artifactinfo/RunTestEvents.java
    ofbiz/trunk/specialpurpose/birt/src/main/java/org/apache/ofbiz/birt/container/BirtContainer.java

Modified: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/component/ComponentConfig.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/component/ComponentConfig.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/component/ComponentConfig.java (original)
+++ ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/component/ComponentConfig.java Sun Oct 16 09:07:08 2016
@@ -33,7 +33,7 @@ import java.util.Map;
 import java.util.TreeMap;
 
 import org.apache.ofbiz.base.container.ContainerConfig;
-import org.apache.ofbiz.base.container.ContainerConfig.Container;
+import org.apache.ofbiz.base.container.ContainerConfig.Configuration;
 import org.apache.ofbiz.base.container.ContainerException;
 import org.apache.ofbiz.base.location.FlexibleLocation;
 import org.apache.ofbiz.base.util.Assert;
@@ -85,18 +85,18 @@ public final class ComponentConfig {
         return componentConfigCache.values();
     }
 
-    public static List<ContainerConfig.Container> getAllContainers() {
-        return getAllContainers(null);
+    public static List<ContainerConfig.Configuration> getAllConfigurations() {
+        return getAllConfigurations(null);
     }
 
-    public static List<ContainerConfig.Container> getAllContainers(String componentName) {
-        List<ContainerConfig.Container> containers = new ArrayList<ContainerConfig.Container>();
+    public static List<ContainerConfig.Configuration> getAllConfigurations(String componentName) {
+        List<ContainerConfig.Configuration> configurations = new ArrayList<ContainerConfig.Configuration>();
         for (ComponentConfig cc : getAllComponents()) {
             if (componentName == null || componentName.equals(cc.getComponentName())) {
-                containers.addAll(cc.getContainers());
+                configurations.addAll(cc.getConfigurations());
             }
         }
-        return containers;
+        return configurations;
     }
 
     public static List<EntityResourceInfo> getAllEntityResourceInfos(String type) {
@@ -346,7 +346,7 @@ public final class ComponentConfig {
     private final List<TestSuiteInfo> testSuiteInfos;
     private final List<KeystoreInfo> keystoreInfos;
     private final List<WebappInfo> webappInfos;
-    private final List<ContainerConfig.Container> containers;
+    private final List<ContainerConfig.Configuration> configurations;
 
     private ComponentConfig(String globalName, String rootLocation) throws ComponentException {
         if (!rootLocation.endsWith("/")) {
@@ -463,16 +463,16 @@ public final class ComponentConfig {
         } else {
             this.webappInfos = Collections.emptyList();
         }
-        // containers
+        // configurations
         try {
-            Collection<Container> containers = ContainerConfig.getContainers(xmlUrl);
-            if (!containers.isEmpty()) {
-                this.containers = Collections.unmodifiableList(new ArrayList<ContainerConfig.Container>(containers));
+            Collection<Configuration> configurations = ContainerConfig.getConfigurations(xmlUrl);
+            if (!configurations.isEmpty()) {
+                this.configurations = Collections.unmodifiableList(new ArrayList<ContainerConfig.Configuration>(configurations));
             } else {
-                this.containers = Collections.emptyList();
+                this.configurations = Collections.emptyList();
             }
         } catch (ContainerException ce) {
-            throw new ComponentException("Error reading containers for component: " + this.globalName, ce);
+            throw new ComponentException("Error reading container configurations for component: " + this.globalName, ce);
         }
         if (Debug.verboseOn())
             Debug.logVerbose("Read component config : [" + rootLocation + "]", module);
@@ -490,8 +490,8 @@ public final class ComponentConfig {
         return this.componentName;
     }
 
-    public List<ContainerConfig.Container> getContainers() {
-        return this.containers;
+    public List<ContainerConfig.Configuration> getConfigurations() {
+        return this.configurations;
     }
 
     public List<EntityResourceInfo> getEntityResourceInfos() {

Modified: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ComponentContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ComponentContainer.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ComponentContainer.java (original)
+++ ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ComponentContainer.java Sun Oct 16 09:07:08 2016
@@ -31,6 +31,7 @@ import org.apache.ofbiz.base.component.C
 import org.apache.ofbiz.base.component.ComponentLoaderConfig;
 import org.apache.ofbiz.base.start.Classpath;
 import org.apache.ofbiz.base.start.NativeLibClassLoader;
+import org.apache.ofbiz.base.start.StartupCommand;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.FileUtil;
 import org.apache.ofbiz.base.util.UtilValidate;
@@ -52,7 +53,7 @@ public class ComponentContainer implemen
     private final AtomicBoolean loaded = new AtomicBoolean(false);
 
     @Override
-    public void init(String[] args, String name, String configFile) throws ContainerException {
+    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) throws ContainerException {
         if (!loaded.compareAndSet(false, true)) {
             throw new ContainerException("Components already loaded, cannot start");
         }
@@ -60,7 +61,7 @@ public class ComponentContainer implemen
         this.configFileLocation = configFile;
 
         // get the config for this container
-        ContainerConfig.Container cc = ContainerConfig.getContainer(name, configFileLocation);
+        ContainerConfig.Configuration cc = ContainerConfig.getConfiguration(name, configFileLocation);
 
         // check for an override loader config
         String loaderConfig = null;

Modified: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/Container.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/Container.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/Container.java (original)
+++ ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/Container.java Sun Oct 16 09:07:08 2016
@@ -18,6 +18,10 @@
  *******************************************************************************/
 package org.apache.ofbiz.base.container;
 
+import java.util.List;
+
+import org.apache.ofbiz.base.start.StartupCommand;
+
 /**
  * An OFBiz container. A container can be thought of as a background process.
  * 
@@ -39,14 +43,14 @@ public interface Container {
     /** Initialize the container. This method must not block - implementations
      * should initialize internal structures and then return.
      *
-     * @param args Command-line arguments.
+     * @param ofbizCommands Command-line arguments.
      * @param name Unique name of the container's instance.
      * @param configFile Location of the configuration file used to load this container.
      * @throws ContainerException If an error was encountered. Throwing this exception
      * will halt container loading, so it should be thrown only when other containers
      * might depend on this one.
      */
-    public void init(String[] args, String name, String configFile) throws ContainerException;
+    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) throws ContainerException;
 
     /**
      * Start the container process. This method must not block - implementations

Modified: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ContainerConfig.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ContainerConfig.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ContainerConfig.java (original)
+++ ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ContainerConfig.java Sun Oct 16 09:07:08 2016
@@ -29,7 +29,6 @@ import java.util.Map;
 
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.apache.ofbiz.base.lang.LockedBy;
 import org.apache.ofbiz.base.util.StringUtil;
 import org.apache.ofbiz.base.util.UtilURL;
 import org.apache.ofbiz.base.util.UtilValidate;
@@ -44,24 +43,25 @@ import org.xml.sax.SAXException;
  */
 public class ContainerConfig {
 
+    private ContainerConfig() {}
+
     public static final String module = ContainerConfig.class.getName();
 
-    @LockedBy("ContainerConfig.class")
-    private static Map<String, Container> containers = new LinkedHashMap<String, Container>();
+    private static Map<String, Configuration> configurations = new LinkedHashMap<String, Configuration>();
 
-    public static Container getContainer(String containerName, String configFile) throws ContainerException {
-        Container container = containers.get(containerName);
-        if (container == null) {
-            getContainers(configFile);
-            container = containers.get(containerName);
+    public static Configuration getConfiguration(String containerName, String configFile) throws ContainerException {
+        Configuration configuration = configurations.get(containerName);
+        if (configuration == null) {
+            getConfigurations(configFile);
+            configuration = configurations.get(containerName);
         }
-        if (container == null) {
+        if (configuration == null) {
             throw new ContainerException("No container found with the name : " + containerName);
         }
-        return container;
+        return configuration;
     }
 
-    public static Collection<Container> getContainers(String configFile) throws ContainerException {
+    public static Collection<Configuration> getConfigurations(String configFile) throws ContainerException {
         if (UtilValidate.isEmpty(configFile)) {
             throw new ContainerException("configFile argument cannot be null or empty");
         }
@@ -69,24 +69,24 @@ public class ContainerConfig {
         if (xmlUrl == null) {
             throw new ContainerException("Could not find container config file " + configFile);
         }
-        return getContainers(xmlUrl);
+        return getConfigurations(xmlUrl);
     }
 
-    public static Collection<Container> getContainers(URL xmlUrl) throws ContainerException {
+    public static Collection<Configuration> getConfigurations(URL xmlUrl) throws ContainerException {
         if (xmlUrl == null) {
             throw new ContainerException("xmlUrl argument cannot be null");
         }
-        Collection<Container> result = getContainerPropsFromXml(xmlUrl);
+        Collection<Configuration> result = getConfigurationPropsFromXml(xmlUrl);
         synchronized (ContainerConfig.class) {
-            for (Container container : result) {
-                containers.put(container.name, container);
+            for (Configuration container : result) {
+                configurations.put(container.name, container);
             }
         }
         return result;
     }
 
-    public static String getPropertyValue(ContainerConfig.Container parentProp, String name, String defaultValue) {
-        ContainerConfig.Container.Property prop = parentProp.getProperty(name);
+    public static String getPropertyValue(ContainerConfig.Configuration parentProp, String name, String defaultValue) {
+        ContainerConfig.Configuration.Property prop = parentProp.getProperty(name);
         if (prop == null || UtilValidate.isEmpty(prop.value)) {
             return defaultValue;
         } else {
@@ -94,8 +94,8 @@ public class ContainerConfig {
         }
     }
 
-    public static int getPropertyValue(ContainerConfig.Container parentProp, String name, int defaultValue) {
-        ContainerConfig.Container.Property prop = parentProp.getProperty(name);
+    public static int getPropertyValue(ContainerConfig.Configuration parentProp, String name, int defaultValue) {
+        ContainerConfig.Configuration.Property prop = parentProp.getProperty(name);
         if (prop == null || UtilValidate.isEmpty(prop.value)) {
             return defaultValue;
         } else {
@@ -109,8 +109,8 @@ public class ContainerConfig {
         }
     }
 
-    public static boolean getPropertyValue(ContainerConfig.Container parentProp, String name, boolean defaultValue) {
-        ContainerConfig.Container.Property prop = parentProp.getProperty(name);
+    public static boolean getPropertyValue(ContainerConfig.Configuration parentProp, String name, boolean defaultValue) {
+        ContainerConfig.Configuration.Property prop = parentProp.getProperty(name);
         if (prop == null || UtilValidate.isEmpty(prop.value)) {
             return defaultValue;
         } else {
@@ -118,8 +118,8 @@ public class ContainerConfig {
         }
     }
 
-    public static String getPropertyValue(ContainerConfig.Container.Property parentProp, String name, String defaultValue) {
-        ContainerConfig.Container.Property prop = parentProp.getProperty(name);
+    public static String getPropertyValue(ContainerConfig.Configuration.Property parentProp, String name, String defaultValue) {
+        ContainerConfig.Configuration.Property prop = parentProp.getProperty(name);
         if (prop == null || UtilValidate.isEmpty(prop.value)) {
             return defaultValue;
         } else {
@@ -127,8 +127,8 @@ public class ContainerConfig {
         }
     }
 
-    public static int getPropertyValue(ContainerConfig.Container.Property parentProp, String name, int defaultValue) {
-        ContainerConfig.Container.Property prop = parentProp.getProperty(name);
+    public static int getPropertyValue(ContainerConfig.Configuration.Property parentProp, String name, int defaultValue) {
+        ContainerConfig.Configuration.Property prop = parentProp.getProperty(name);
         if (prop == null || UtilValidate.isEmpty(prop.value)) {
             return defaultValue;
         } else {
@@ -142,8 +142,8 @@ public class ContainerConfig {
         }
     }
 
-    public static boolean getPropertyValue(ContainerConfig.Container.Property parentProp, String name, boolean defaultValue) {
-        ContainerConfig.Container.Property prop = parentProp.getProperty(name);
+    public static boolean getPropertyValue(ContainerConfig.Configuration.Property parentProp, String name, boolean defaultValue) {
+        ContainerConfig.Configuration.Property prop = parentProp.getProperty(name);
         if (prop == null || UtilValidate.isEmpty(prop.value)) {
             return defaultValue;
         } else {
@@ -151,9 +151,7 @@ public class ContainerConfig {
         }
     }
 
-    private ContainerConfig() {}
-
-    private static Collection<Container> getContainerPropsFromXml(URL xmlUrl) throws ContainerException {
+    private static Collection<Configuration> getConfigurationPropsFromXml(URL xmlUrl) throws ContainerException {
         Document containerDocument = null;
         try {
             containerDocument = UtilXml.readXmlDocument(xmlUrl, true);
@@ -165,20 +163,20 @@ public class ContainerConfig {
             throw new ContainerException("Error reading the container config file: " + xmlUrl, e);
         }
         Element root = containerDocument.getDocumentElement();
-        List<Container> result = new ArrayList<Container>();
+        List<Configuration> result = new ArrayList<Configuration>();
         for (Element curElement: UtilXml.childElementList(root, "container")) {
-            result.add(new Container(curElement));
+            result.add(new Configuration(curElement));
         }
         return result;
     }
 
-    public static class Container {
+    public static class Configuration {
         public final String name;
         public final String className;
         public final List<String> loaders;
         public final Map<String, Property> properties;
 
-        public Container(Element element) {
+        public Configuration(Element element) {
             this.name = element.getAttribute("name");
             this.className = element.getAttribute("class");
             this.loaders = StringUtil.split(element.getAttribute("loaders"), ",");

Modified: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ContainerLoader.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ContainerLoader.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ContainerLoader.java (original)
+++ ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/ContainerLoader.java Sun Oct 16 09:07:08 2016
@@ -18,23 +18,23 @@
  *******************************************************************************/
 package org.apache.ofbiz.base.container;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.URL;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Enumeration;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
+import java.util.stream.Collectors;
 
 import org.apache.ofbiz.base.component.ComponentConfig;
 import org.apache.ofbiz.base.start.Config;
+import org.apache.ofbiz.base.start.StartupCommand;
 import org.apache.ofbiz.base.start.StartupException;
 import org.apache.ofbiz.base.start.StartupLoader;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.StringUtil;
 import org.apache.ofbiz.base.util.UtilValidate;
 
+import edu.emory.mathcs.backport.java.util.Collections;
+
 /**
  * An object that loads containers (background processes).
  * 
@@ -47,115 +47,70 @@ public class ContainerLoader implements
 
     public static final String module = ContainerLoader.class.getName();
 
-    private String configFile = null;
     private final List<Container> loadedContainers = new LinkedList<Container>();
-    private boolean unloading = false;
-    private boolean loaded = false;
 
     /**
      * @see org.apache.ofbiz.base.start.StartupLoader#load(Config, String[])
      */
     @Override
-    public synchronized void load(Config config, String args[]) throws StartupException {
-        if (this.loaded || this.unloading) {
-            return;
-        }
-        this.loadedContainers.clear();
-        // get this loader's configuration file
-        this.configFile = config.containerConfig;
-
-        List<String> loaders = null;
-        for (Map loaderMap: config.loaders) {
-            if (module.equals(loaderMap.get("class"))) {
-                loaders = StringUtil.split((String)loaderMap.get("profiles"), ",");
-            }
-        }
+    public synchronized void load(Config config, List<StartupCommand> ofbizCommands) throws StartupException {
+
+        // loaders defined in startup (e.g. main, test, load-data, etc ...)
+        List<String> loaders = StringUtil.split((String) config.loader.get("profiles"), ",");
+
+        // load containers defined in ofbiz-containers.xml
+        Debug.logInfo("[Startup] Loading containers...", module);
+        List<ContainerConfig.Configuration> ofbizContainerConfigs = filterContainersHavingMatchingLoaders(
+                loaders, retrieveOfbizContainers(config.containerConfig));
+        loadedContainers.addAll(loadContainersFromConfigurations(ofbizContainerConfigs, config, ofbizCommands));
+
+        // load containers defined in components
+        Debug.logInfo("[Startup] Loading component containers...", module);
+        List<ContainerConfig.Configuration> componentContainerConfigs = filterContainersHavingMatchingLoaders(
+                loaders, ComponentConfig.getAllConfigurations());
+        loadedContainers.addAll(loadContainersFromConfigurations(componentContainerConfigs, config, ofbizCommands));
 
-        Debug.logInfo("[Startup] Loading containers from " + configFile + " for loaders " + loaders, module);
-        Collection<ContainerConfig.Container> containers = null;
+        // Start all containers loaded from above steps
+        startLoadedContainers();
+    }
+
+    private Collection<ContainerConfig.Configuration> retrieveOfbizContainers(String configFile) throws StartupException {
         try {
-            containers = ContainerConfig.getContainers(configFile);
+            return ContainerConfig.getConfigurations(configFile);
         } catch (ContainerException e) {
             throw new StartupException(e);
-        }
-        for (ContainerConfig.Container containerCfg : containers) {
-            if (this.unloading) {
-                return;
-            }
-            boolean matchingLoaderFound = false;
-            if (UtilValidate.isEmpty(containerCfg.loaders) && UtilValidate.isEmpty(loaders)) {
-                matchingLoaderFound = true;
-            } else {
-                for (String loader: loaders) {
-                    if (UtilValidate.isEmpty(containerCfg.loaders) || containerCfg.loaders.contains(loader)) {
-                        matchingLoaderFound = true;
-                        break;
-                    }
-                }
-            }
-            if (matchingLoaderFound) {
-                Debug.logInfo("Loading container: " + containerCfg.name, module);
-                Container tmpContainer = loadContainer(containerCfg, args);
-                this.loadedContainers.add(tmpContainer);
-                Debug.logInfo("Loaded container: " + containerCfg.name, module);
-            }
-        }
-        if (this.unloading) {
-            return;
-        }
+        }        
+    }
 
-        List<ContainerConfig.Container> containersDefinedInComponents = ComponentConfig.getAllContainers();
-        for (ContainerConfig.Container containerCfg: containersDefinedInComponents) {
-            boolean matchingLoaderFound = false;
-            if (UtilValidate.isEmpty(containerCfg.loaders) && UtilValidate.isEmpty(loaders)) {
-                matchingLoaderFound = true;
-            } else {
-                for (String loader: loaders) {
-                    if (UtilValidate.isEmpty(containerCfg.loaders) || containerCfg.loaders.contains(loader)) {
-                        matchingLoaderFound = true;
-                        break;
-                    }
-                }
-            }
-            if (matchingLoaderFound) {
-                Debug.logInfo("Loading component's container: " + containerCfg.name, module);
-                Container tmpContainer = loadContainer(containerCfg, args);
-                this.loadedContainers.add(tmpContainer);
-                Debug.logInfo("Loaded component's container: " + containerCfg.name, module);
-            }
-        }
-        // Get hot-deploy container configuration files
-        ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        Enumeration<URL> resources;
-        try {
-            resources = loader.getResources("hot-deploy-containers.xml");
-            while (resources.hasMoreElements() && !this.unloading) {
-                URL xmlUrl = resources.nextElement();
-                Debug.logInfo("Loading hot-deploy containers from " + xmlUrl, module);
-                Collection<ContainerConfig.Container> hotDeployContainers = ContainerConfig.getContainers(xmlUrl);
-                for (ContainerConfig.Container containerCfg : hotDeployContainers) {
-                    if (this.unloading) {
-                        return;
-                    }
-                    Container tmpContainer = loadContainer(containerCfg, args);
-                    this.loadedContainers.add(tmpContainer);
-                }
-            }
-        } catch (Exception e) {
-            Debug.logError(e, "Could not load hot-deploy-containers.xml", module);
-            throw new StartupException(e);
+    private List<ContainerConfig.Configuration> filterContainersHavingMatchingLoaders(List<String> loaders,
+            Collection<ContainerConfig.Configuration> containerConfigs) throws StartupException {
+        return containerConfigs.stream()
+                .filter(containerCfg ->
+                    UtilValidate.isEmpty(containerCfg.loaders) &&
+                    UtilValidate.isEmpty(loaders) ||
+                    containerCfg.loaders.stream().anyMatch(loader -> loaders.contains(loader)))
+                .collect(Collectors.toList());
+    }
+
+    private List<Container> loadContainersFromConfigurations(List<ContainerConfig.Configuration> containerConfigs,
+            Config config, List<StartupCommand> ofbizCommands) throws StartupException {
+
+        List<Container> loadContainers = new ArrayList<Container>();
+        for (ContainerConfig.Configuration containerCfg : containerConfigs) {
+            Debug.logInfo("Loading container: " + containerCfg.name, module);
+            Container tmpContainer = loadContainer(config.containerConfig, containerCfg, ofbizCommands);
+            loadContainers.add(tmpContainer);
+            Debug.logInfo("Loaded container: " + containerCfg.name, module);
         }
-        loaded = true;
+        return loadContainers;
     }
 
-    private Container loadContainer(ContainerConfig.Container containerCfg, String[] args) throws StartupException {
+    private Container loadContainer(String configFile, 
+            ContainerConfig.Configuration containerCfg,
+            List<StartupCommand> ofbizCommands) throws StartupException {
         // load the container class
         ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        if (loader == null) {
-            Debug.logWarning("Unable to get context classloader; using system", module);
-            loader = ClassLoader.getSystemClassLoader();
-        }
-        Class<?> containerClass = null;
+        Class<?> containerClass;
         try {
             containerClass = loader.loadClass(containerCfg.className);
         } catch (ClassNotFoundException e) {
@@ -166,79 +121,34 @@ public class ContainerLoader implements
         }
 
         // create a new instance of the container object
-        Container containerObj = null;
+        Container containerObj;
         try {
             containerObj = (Container) containerClass.newInstance();
-        } catch (InstantiationException e) {
-            throw new StartupException("Cannot create " + containerCfg.name, e);
-        } catch (IllegalAccessException e) {
-            throw new StartupException("Cannot create " + containerCfg.name, e);
-        } catch (ClassCastException e) {
+        } catch (InstantiationException | IllegalAccessException e) {
             throw new StartupException("Cannot create " + containerCfg.name, e);
         }
-
         if (containerObj == null) {
             throw new StartupException("Unable to create instance of component container");
         }
 
         // initialize the container object
         try {
-            containerObj.init(args, containerCfg.name, configFile);
+            containerObj.init(ofbizCommands, containerCfg.name, configFile);
         } catch (ContainerException e) {
             throw new StartupException("Cannot init() " + containerCfg.name, e);
-        } catch (java.lang.AbstractMethodError e) {
-            throw new StartupException("Cannot init() " + containerCfg.name, e);
         }
 
         return containerObj;
     }
 
-    private void printThreadDump() {
-        Thread currentThread = Thread.currentThread();
-        ThreadGroup group = currentThread.getThreadGroup();
-        while (group.getParent() != null) {
-            group = group.getParent();
-        }
-        Thread threadArr[] = new Thread[1000];
-        group.enumerate(threadArr);
-
-        StringWriter writer = new StringWriter();
-        PrintWriter out = new PrintWriter(writer);
-        out.println("Thread dump:");
-        for (Thread t: threadArr) {
-            if (t != null) {
-                ThreadGroup g = t.getThreadGroup();
-                out.println("Thread: " + t.getName() + " [" + t.getId() + "] @ " + (g != null ? g.getName() : "[none]") + " : " + t.getPriority() + " [" + t.getState().name() + "]");
-                out.println("--- Alive: " + t.isAlive() + " Daemon: " + t.isDaemon());
-                for (StackTraceElement stack: t.getStackTrace()) {
-                    out.println("### " + stack.toString());
-                }
-            }
-        }
-        Debug.logInfo(writer.toString(), module);
-    }
-
-    /**
-     * @see org.apache.ofbiz.base.start.StartupLoader#start()
-     */
-    @Override
-    public synchronized void start() throws StartupException {
-        if (!this.loaded || this.unloading) {
-            throw new IllegalStateException("start() called on unloaded containers");
-        }
+    private void startLoadedContainers() throws StartupException {
         Debug.logInfo("[Startup] Starting containers...", module);
-        // start each container object
-        for (Container container: this.loadedContainers) {
-            if (this.unloading) {
-                return;
-            }
+        for (Container container: loadedContainers) {
             Debug.logInfo("Starting container " + container.getName(), module);
             try {
                 container.start();
             } catch (ContainerException e) {
                 throw new StartupException("Cannot start() " + container.getClass().getName(), e);
-            } catch (java.lang.AbstractMethodError e) {
-                throw new StartupException("Cannot start() " + container.getClass().getName(), e);
             }
             Debug.logInfo("Started container " + container.getName(), module);
         }
@@ -248,26 +158,20 @@ public class ContainerLoader implements
      * @see org.apache.ofbiz.base.start.StartupLoader#unload()
      */
     @Override
-    public void unload() throws StartupException {
-        if (!this.unloading) {
-            this.unloading = true;
-            synchronized (this) {
-                Debug.logInfo("Shutting down containers", module);
-                if (Debug.verboseOn()) {
-                    printThreadDump();
-                }
-                // shutting down in reverse order
-                for (int i = this.loadedContainers.size(); i > 0; i--) {
-                    Container container = this.loadedContainers.get(i-1);
-                    Debug.logInfo("Stopping container " + container.getName(), module);
-                    try {
-                        container.stop();
-                    } catch (ContainerException e) {
-                        Debug.logError(e, module);
-                    }
-                    Debug.logInfo("Stopped container " + container.getName(), module);
-                }
+    public synchronized void unload() throws StartupException {
+        Debug.logInfo("Shutting down containers", module);
+
+        List<Container> reversedContainerList = new ArrayList<Container>(loadedContainers);
+        Collections.reverse(reversedContainerList);
+
+        for(Container loadedContainer : reversedContainerList) {
+            Debug.logInfo("Stopping container " + loadedContainer.getName(), module);
+            try {
+                loadedContainer.stop();
+            } catch (ContainerException e) {
+                Debug.logError(e, module);
             }
+            Debug.logInfo("Stopped container " + loadedContainer.getName(), module);
         }
     }
 }

Modified: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/JustLoadComponentsContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/JustLoadComponentsContainer.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/JustLoadComponentsContainer.java (original)
+++ ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/JustLoadComponentsContainer.java Sun Oct 16 09:07:08 2016
@@ -18,10 +18,14 @@
  *******************************************************************************/
 package org.apache.ofbiz.base.container;
 
+import java.util.List;
+
 import org.apache.ofbiz.base.component.AlreadyLoadedException;
 import org.apache.ofbiz.base.component.ComponentException;
+import org.apache.ofbiz.base.start.StartupCommand;
 import org.apache.ofbiz.base.util.Debug;
 
+
 /**
  * A Container implementation to run the tests configured through this testtools stuff.
  */
@@ -32,7 +36,7 @@ public class JustLoadComponentsContainer
     private String name;
 
     @Override
-    public void init(String[] args, String name, String configFile) {
+    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) {
         this.name = name;
         try {
             ComponentContainer cc = new ComponentContainer();

Modified: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/NamingServiceContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/NamingServiceContainer.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/NamingServiceContainer.java (original)
+++ ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/NamingServiceContainer.java Sun Oct 16 09:07:08 2016
@@ -24,8 +24,10 @@ import java.rmi.RemoteException;
 import java.rmi.registry.LocateRegistry;
 import java.rmi.registry.Registry;
 import java.rmi.server.UnicastRemoteObject;
+import java.util.List;
 
 import org.apache.ofbiz.base.start.Start;
+import org.apache.ofbiz.base.start.StartupCommand;
 import org.apache.ofbiz.base.util.RMIExtendedSocketFactory;
 
 /**
@@ -47,15 +49,15 @@ public class NamingServiceContainer impl
 
     private String name;
 
-    public void init(String[] args, String name, String configFile) throws ContainerException {
+    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) throws ContainerException {
         this.name =name;
         this.configFileLocation = configFile;
 
-        ContainerConfig.Container cfg = ContainerConfig.getContainer(name, configFileLocation);
+        ContainerConfig.Configuration cfg = ContainerConfig.getConfiguration(name, configFileLocation);
 
         // get the naming (JNDI) port
         
-        ContainerConfig.Container.Property port = cfg.getProperty("port");
+        ContainerConfig.Configuration.Property port = cfg.getProperty("port");
         if (port.value != null) {
             try {
                 this.namingPort = Integer.parseInt(port.value) + Start.getInstance().getConfig().portOffset;
@@ -65,7 +67,7 @@ public class NamingServiceContainer impl
         }
 
         // get the naming (JNDI) server
-        ContainerConfig.Container.Property host = cfg.getProperty("host");
+        ContainerConfig.Configuration.Property host = cfg.getProperty("host");
         if (host != null && host.value != null) {
             this.namingHost =  host.value ;
         }

Added: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/StartupCommandToArgsAdapter.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/StartupCommandToArgsAdapter.java?rev=1765127&view=auto
==============================================================================
--- ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/StartupCommandToArgsAdapter.java (added)
+++ ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/StartupCommandToArgsAdapter.java Sun Oct 16 09:07:08 2016
@@ -0,0 +1,47 @@
+package org.apache.ofbiz.base.container;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.ofbiz.base.start.StartupCommand;
+import org.apache.ofbiz.base.start.StartupCommandUtil;
+
+/**
+ * Temporary class. This class is responsible for converting
+ * StartupCommand instances to String[]. This is a workaround until all
+ * containers have fully changed their signatures to adopt the StartupCommand
+ * object 
+ */
+public class StartupCommandToArgsAdapter {
+    /**
+     * Generates the loaderArgs with arguments as expected by the
+     * containers that will receive them. 
+     * 
+     * TODO A better solution is to change the signature of all 
+     * containers to receive a <tt>List</tt> of <tt>StartupCommand</tt>s
+     * instead and delete the methods adaptStartupCommandsToLoaderArgs
+     * and retrieveCommandArguments along with the loaderArgs list.
+     */
+    public static String[] adaptStartupCommandsToLoaderArgs(List<StartupCommand> ofbizCommands) {
+        List<String> loaderArgs = new ArrayList<String>();
+        final String LOAD_DATA = StartupCommandUtil.StartupOption.LOAD_DATA.getName();
+        final String TEST = StartupCommandUtil.StartupOption.TEST.getName();
+        
+        if(ofbizCommands.stream().anyMatch(command -> command.getName().equals(LOAD_DATA))) {
+            retrieveCommandArguments(ofbizCommands, LOAD_DATA).entrySet().stream().forEach(entry -> 
+            loaderArgs.add("-" + entry.getKey() + "=" + entry.getValue()));
+        } else if(ofbizCommands.stream().anyMatch(command -> command.getName().equals(TEST))) {
+            retrieveCommandArguments(ofbizCommands, TEST).entrySet().stream().forEach(entry -> 
+            loaderArgs.add("-" + entry.getKey() + "=" + entry.getValue()));
+        }
+        return loaderArgs.toArray(new String[loaderArgs.size()]);
+    }
+
+    private static Map<String,String> retrieveCommandArguments(List<StartupCommand> ofbizCommands, String commandName) {
+        return ofbizCommands.stream()
+                .filter(option-> option.getName().equals(commandName))
+                .collect(Collectors.toList()).get(0).getProperties();
+    }
+}

Propchange: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/StartupCommandToArgsAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/StartupCommandToArgsAdapter.java
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/container/StartupCommandToArgsAdapter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/metrics/MetricsFactory.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/metrics/MetricsFactory.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/metrics/MetricsFactory.java (original)
+++ ofbiz/trunk/framework/base/src/main/java/org/apache/ofbiz/base/metrics/MetricsFactory.java Sun Oct 16 09:07:08 2016
@@ -31,7 +31,6 @@ package org.apache.ofbiz.base.metrics;
 import java.util.Collection;
 import java.util.TreeSet;
 
-import org.apache.ofbiz.base.lang.LockedBy;
 import org.apache.ofbiz.base.lang.ThreadSafe;
 import org.apache.ofbiz.base.util.Assert;
 import org.apache.ofbiz.base.util.UtilProperties;
@@ -138,17 +137,11 @@ public final class MetricsFactory {
     }
 
     private static final class MetricsImpl implements Metrics, Comparable<Metrics> {
-        @LockedBy("this")
         private int count = 0;
-        @LockedBy("this")
         private long lastTime = System.currentTimeMillis();
-        @LockedBy("this")
         private double serviceRate = 0.0;
-        @LockedBy("this")
         private long totalServiceTime = 0;
-        @LockedBy("this")
         private long totalEvents = 0;
-        @LockedBy("this")
         private long cumulativeEvents = 0;
         private final String name;
         private final int estimationSize;

Modified: ofbiz/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java (original)
+++ ofbiz/trunk/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java Sun Oct 16 09:07:08 2016
@@ -68,10 +68,11 @@ import org.apache.ofbiz.base.component.C
 import org.apache.ofbiz.base.concurrent.ExecutionPool;
 import org.apache.ofbiz.base.container.Container;
 import org.apache.ofbiz.base.container.ContainerConfig;
-import org.apache.ofbiz.base.container.ContainerConfig.Container.Property;
+import org.apache.ofbiz.base.container.ContainerConfig.Configuration.Property;
 import org.apache.ofbiz.base.container.ContainerException;
 import org.apache.ofbiz.base.location.FlexibleLocation;
 import org.apache.ofbiz.base.start.Start;
+import org.apache.ofbiz.base.start.StartupCommand;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.SSLUtil;
 import org.apache.ofbiz.base.util.UtilValidate;
@@ -145,7 +146,7 @@ public class CatalinaContainer implement
     }
 
     private Tomcat tomcat = null;
-    protected Map<String, ContainerConfig.Container.Property> clusterConfig = new HashMap<String, ContainerConfig.Container.Property>();
+    protected Map<String, ContainerConfig.Configuration.Property> clusterConfig = new HashMap<String, ContainerConfig.Configuration.Property>();
 
     protected boolean contextReloadable = false;
     protected boolean crossContext = false;
@@ -156,10 +157,10 @@ public class CatalinaContainer implement
     private String name;
 
     @Override
-    public void init(String[] args, String name, String configFile) throws ContainerException {
+    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) throws ContainerException {
         this.name = name;
         // get the container config
-        ContainerConfig.Container cc = ContainerConfig.getContainer(name, configFile);
+        ContainerConfig.Configuration cc = ContainerConfig.getConfiguration(name, configFile);
         if (cc == null) {
             throw new ContainerException("No catalina-container configuration found in container config!");
         }
@@ -196,7 +197,7 @@ public class CatalinaContainer implement
         }
 
         // create the engine
-        List<ContainerConfig.Container.Property> engineProps = cc.getPropertiesWithValue("engine");
+        List<ContainerConfig.Configuration.Property> engineProps = cc.getPropertiesWithValue("engine");
         if (UtilValidate.isEmpty(engineProps)) {
             throw new ContainerException("Cannot load CatalinaContainer; no engines defined.");
         }
@@ -206,11 +207,11 @@ public class CatalinaContainer implement
         createEngine(engineProps.get(0));
 
         // create the connectors
-        List<ContainerConfig.Container.Property> connectorProps = cc.getPropertiesWithValue("connector");
+        List<ContainerConfig.Configuration.Property> connectorProps = cc.getPropertiesWithValue("connector");
         if (UtilValidate.isEmpty(connectorProps)) {
             throw new ContainerException("Cannot load CatalinaContainer; no connectors defined!");
         }
-        for (ContainerConfig.Container.Property connectorProp: connectorProps) {
+        for (ContainerConfig.Configuration.Property connectorProp: connectorProps) {
             createConnector(connectorProp);
         }
     }
@@ -234,12 +235,12 @@ public class CatalinaContainer implement
         return true;
     }
 
-    private Engine createEngine(ContainerConfig.Container.Property engineConfig) throws ContainerException {
+    private Engine createEngine(ContainerConfig.Configuration.Property engineConfig) throws ContainerException {
         if (tomcat == null) {
             throw new ContainerException("Cannot create Engine without Tomcat instance!");
         }
 
-        ContainerConfig.Container.Property defaultHostProp = engineConfig.getProperty("default-host");
+        ContainerConfig.Configuration.Property defaultHostProp = engineConfig.getProperty("default-host");
         if (defaultHostProp == null) {
             throw new ContainerException("default-host element of server property is required for catalina!");
         }
@@ -262,13 +263,13 @@ public class CatalinaContainer implement
         configureHost(host);
 
         // configure clustering
-        List<ContainerConfig.Container.Property> clusterProps = engineConfig.getPropertiesWithValue("cluster");
+        List<ContainerConfig.Configuration.Property> clusterProps = engineConfig.getPropertiesWithValue("cluster");
         if (clusterProps != null && clusterProps.size() > 1) {
             throw new ContainerException("Only one cluster configuration allowed per engine");
         }
 
         if (UtilValidate.isNotEmpty(clusterProps)) {
-            ContainerConfig.Container.Property clusterProp = clusterProps.get(0);
+            ContainerConfig.Configuration.Property clusterProp = clusterProps.get(0);
             createCluster(clusterProp, host);
             clusterConfig.put(engineName, clusterProp);
         }
@@ -341,7 +342,7 @@ public class CatalinaContainer implement
         ((StandardHost)host).setWorkDir(new File(System.getProperty(Globals.CATALINA_HOME_PROP), "work" + File.separator + host.getName()).getAbsolutePath());
     }
 
-    protected Cluster createCluster(ContainerConfig.Container.Property clusterProps, Host host) throws ContainerException {
+    protected Cluster createCluster(ContainerConfig.Configuration.Property clusterProps, Host host) throws ContainerException {
         String defaultValveFilter = ".*\\.gif;.*\\.js;.*\\.jpg;.*\\.htm;.*\\.html;.*\\.txt;.*\\.png;.*\\.css;.*\\.ico;.*\\.htc;";
 
         ReplicationValve clusterValve = new ReplicationValve();
@@ -429,7 +430,7 @@ public class CatalinaContainer implement
         return cluster;
     }
 
-    protected Connector createConnector(ContainerConfig.Container.Property connectorProp) throws ContainerException {
+    protected Connector createConnector(ContainerConfig.Configuration.Property connectorProp) throws ContainerException {
         if (tomcat == null) {
             throw new ContainerException("Cannot create Connector without Tomcat instance!");
         }
@@ -442,7 +443,7 @@ public class CatalinaContainer implement
             connector = new Connector(protocol);
             connector.setPort(port);
             // then set all the other parameters
-            for (ContainerConfig.Container.Property prop: connectorProp.properties.values()) {
+            for (ContainerConfig.Configuration.Property prop: connectorProp.properties.values()) {
                 if ("protocol".equals(prop.name) || "port".equals(prop.name)) {
                     // protocol and port are already set
                     continue;

Modified: ofbiz/trunk/framework/entity/src/main/java/org/apache/ofbiz/entity/DelegatorContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/main/java/org/apache/ofbiz/entity/DelegatorContainer.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/main/java/org/apache/ofbiz/entity/DelegatorContainer.java (original)
+++ ofbiz/trunk/framework/entity/src/main/java/org/apache/ofbiz/entity/DelegatorContainer.java Sun Oct 16 09:07:08 2016
@@ -27,6 +27,7 @@ import org.apache.ofbiz.base.concurrent.
 import org.apache.ofbiz.base.container.Container;
 import org.apache.ofbiz.base.container.ContainerConfig;
 import org.apache.ofbiz.base.container.ContainerException;
+import org.apache.ofbiz.base.start.StartupCommand;
 import org.apache.ofbiz.base.util.UtilValidate;
 import org.apache.ofbiz.base.util.StringUtil;
 
@@ -35,10 +36,10 @@ public class DelegatorContainer implemen
     private List<String> preloadedDelegatorNames;
 
     @Override
-    public void init(String[] args, String name, String configFile) throws ContainerException {
+    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) throws ContainerException {
         this.name = name;
 
-        ContainerConfig.Container cc = ContainerConfig.getContainer(name, configFile);
+        ContainerConfig.Configuration cc = ContainerConfig.getConfiguration(name, configFile);
 
         preloadedDelegatorNames = StringUtil.split(ContainerConfig.getPropertyValue(cc, "preloaded-delegators", "default"), ", ");
     }

Modified: ofbiz/trunk/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataLoadContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataLoadContainer.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataLoadContainer.java (original)
+++ ofbiz/trunk/framework/entityext/src/main/java/org/apache/ofbiz/entityext/data/EntityDataLoadContainer.java Sun Oct 16 09:07:08 2016
@@ -32,6 +32,8 @@ import org.apache.ofbiz.base.component.C
 import org.apache.ofbiz.base.container.Container;
 import org.apache.ofbiz.base.container.ContainerConfig;
 import org.apache.ofbiz.base.container.ContainerException;
+import org.apache.ofbiz.base.container.StartupCommandToArgsAdapter;
+import org.apache.ofbiz.base.start.StartupCommand;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.StringUtil;
 import org.apache.ofbiz.base.util.UtilURL;
@@ -83,7 +85,10 @@ public class EntityDataLoadContainer imp
     }
 
     @Override
-    public void init(String[] args, String name, String configFile) throws ContainerException {
+    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) throws ContainerException {
+        // TODO: remove this hack and provide clean implementation
+        String[] args = StartupCommandToArgsAdapter.adaptStartupCommandsToLoaderArgs(ofbizCommands);
+
         this.name = name;
         this.configFile = configFile;
         // disable job scheduler, JMS listener and startup services
@@ -212,8 +217,8 @@ public class EntityDataLoadContainer imp
                 Debug.logWarning("Multitenant is disabled. Please enable multitenant. (e.g. general.properties --> multitenant=Y)", module);
                 return true;
             }
-            ContainerConfig.Container cfg = ContainerConfig.getContainer(name, configFile);
-            ContainerConfig.Container.Property delegatorNameProp = cfg.getProperty("delegator-name");
+            ContainerConfig.Configuration cfg = ContainerConfig.getConfiguration(name, configFile);
+            ContainerConfig.Configuration.Property delegatorNameProp = cfg.getProperty("delegator-name");
             String delegatorName = null;
             if (delegatorNameProp == null || UtilValidate.isEmpty(delegatorNameProp.value)) {
                 throw new ContainerException("Invalid delegator-name defined in container configuration");
@@ -243,9 +248,9 @@ public class EntityDataLoadContainer imp
         return true;
     }
     private void loadContainer() throws ContainerException{
-        ContainerConfig.Container cfg = ContainerConfig.getContainer(name, configFile);
-        ContainerConfig.Container.Property delegatorNameProp = cfg.getProperty("delegator-name");
-        ContainerConfig.Container.Property entityGroupNameProp = cfg.getProperty("entity-group-name");
+        ContainerConfig.Configuration cfg = ContainerConfig.getConfiguration(name, configFile);
+        ContainerConfig.Configuration.Property delegatorNameProp = cfg.getProperty("delegator-name");
+        ContainerConfig.Configuration.Property entityGroupNameProp = cfg.getProperty("entity-group-name");
 
         String delegatorName = null;
         String entityGroupName = null;

Modified: ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/ServiceContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/ServiceContainer.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/ServiceContainer.java (original)
+++ ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/ServiceContainer.java Sun Oct 16 09:07:08 2016
@@ -19,12 +19,14 @@
 package org.apache.ofbiz.service;
 
 import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.ofbiz.base.container.Container;
 import org.apache.ofbiz.base.container.ContainerConfig;
 import org.apache.ofbiz.base.container.ContainerException;
+import org.apache.ofbiz.base.start.StartupCommand;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.UtilValidate;
 import org.apache.ofbiz.entity.Delegator;
@@ -41,11 +43,11 @@ public class ServiceContainer implements
     private String name;
 
     @Override
-    public void init(String[] args, String name, String configFile) throws ContainerException {
+    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) throws ContainerException {
         this.name = name;
         // initialize the LocalDispatcherFactory
-        ContainerConfig.Container cfg = ContainerConfig.getContainer(name, configFile);
-        ContainerConfig.Container.Property dispatcherFactoryProperty = cfg.getProperty("dispatcher-factory");
+        ContainerConfig.Configuration cfg = ContainerConfig.getConfiguration(name, configFile);
+        ContainerConfig.Configuration.Property dispatcherFactoryProperty = cfg.getProperty("dispatcher-factory");
         if (dispatcherFactoryProperty == null || UtilValidate.isEmpty(dispatcherFactoryProperty.value)) {
             throw new ContainerException("Unable to initialize container " + name + ": dispatcher-factory property is not set");
         }

Modified: ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/mail/JavaMailContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/mail/JavaMailContainer.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/mail/JavaMailContainer.java (original)
+++ ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/mail/JavaMailContainer.java Sun Oct 16 09:07:08 2016
@@ -43,6 +43,7 @@ import javax.mail.search.FlagTerm;
 import org.apache.ofbiz.base.container.Container;
 import org.apache.ofbiz.base.container.ContainerConfig;
 import org.apache.ofbiz.base.container.ContainerException;
+import org.apache.ofbiz.base.start.StartupCommand;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.UtilMisc;
 import org.apache.ofbiz.base.util.UtilValidate;
@@ -80,7 +81,7 @@ public class JavaMailContainer implement
      *
      */
     @Override
-    public void init(String[] args, String name, String configFile) throws ContainerException {
+    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) throws ContainerException {
         this.name = name;
         this.configFile = configFile;
         this.stores = new LinkedHashMap<Store, Session>();
@@ -96,7 +97,7 @@ public class JavaMailContainer implement
      */
     @Override
     public boolean start() throws ContainerException {
-        ContainerConfig.Container cfg = ContainerConfig.getContainer(name, configFile);
+        ContainerConfig.Configuration cfg = ContainerConfig.getConfiguration(name, configFile);
         String dispatcherName = ContainerConfig.getPropertyValue(cfg, "dispatcher-name", "JavaMailDispatcher");
         String delegatorName = ContainerConfig.getPropertyValue(cfg, "delegator-name", "default");
         this.deleteMail = "true".equals(ContainerConfig.getPropertyValue(cfg, "delete-mail", "false"));
@@ -119,8 +120,8 @@ public class JavaMailContainer implement
         ServiceMcaUtil.readConfig();
 
         // load the listeners
-        List<ContainerConfig.Container.Property> configs = cfg.getPropertiesWithValue("store-listener");
-        for (ContainerConfig.Container.Property prop: configs) {
+        List<ContainerConfig.Configuration.Property> configs = cfg.getPropertiesWithValue("store-listener");
+        for (ContainerConfig.Configuration.Property prop: configs) {
             Session session = this.makeSession(prop);
             Store store = this.getStore(session);
             if (store != null) {
@@ -158,11 +159,11 @@ public class JavaMailContainer implement
     }
 
     // java-mail methods
-    protected Session makeSession(ContainerConfig.Container.Property client) {
+    protected Session makeSession(ContainerConfig.Configuration.Property client) {
         Properties props = new Properties();
-        Map<String, ContainerConfig.Container.Property> clientProps = client.properties;
+        Map<String, ContainerConfig.Configuration.Property> clientProps = client.properties;
         if (clientProps != null) {
-            for (ContainerConfig.Container.Property p: clientProps.values()) {
+            for (ContainerConfig.Configuration.Property p: clientProps.values()) {
                 props.setProperty(p.name.toLowerCase(), p.value);
             }
         }

Modified: ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/rmi/RmiServiceContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/rmi/RmiServiceContainer.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/rmi/RmiServiceContainer.java (original)
+++ ofbiz/trunk/framework/service/src/main/java/org/apache/ofbiz/service/rmi/RmiServiceContainer.java Sun Oct 16 09:07:08 2016
@@ -22,6 +22,7 @@ import java.rmi.Naming;
 import java.rmi.RemoteException;
 import java.rmi.server.RMIClientSocketFactory;
 import java.rmi.server.RMIServerSocketFactory;
+import java.util.List;
 
 import javax.naming.InitialContext;
 import javax.naming.NamingException;
@@ -30,6 +31,7 @@ import org.apache.ofbiz.base.container.C
 import org.apache.ofbiz.base.container.ContainerConfig;
 import org.apache.ofbiz.base.container.ContainerException;
 import org.apache.ofbiz.base.start.Start;
+import org.apache.ofbiz.base.start.StartupCommand;
 import org.apache.ofbiz.base.util.UtilValidate;
 import org.apache.ofbiz.entity.Delegator;
 import org.apache.ofbiz.entity.DelegatorFactory;
@@ -50,21 +52,21 @@ public class RmiServiceContainer impleme
     // Container methods
 
     @Override
-    public void init(String[] args, String name, String configFile) {
+    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) {
         this.containerName = name;
         this.configFile = configFile;
     }
 
     public boolean start() throws ContainerException {
         // get the container config
-        ContainerConfig.Container cfg = ContainerConfig.getContainer(containerName, configFile);
-        ContainerConfig.Container.Property initialCtxProp = cfg.getProperty("use-initial-context");
-        ContainerConfig.Container.Property lookupHostProp = cfg.getProperty("bound-host");
-        ContainerConfig.Container.Property lookupPortProp = cfg.getProperty("bound-port");
-        ContainerConfig.Container.Property lookupNameProp = cfg.getProperty("bound-name");
-        ContainerConfig.Container.Property delegatorProp = cfg.getProperty("delegator-name");
-        ContainerConfig.Container.Property clientProp = cfg.getProperty("client-factory");
-        ContainerConfig.Container.Property serverProp = cfg.getProperty("server-factory");
+        ContainerConfig.Configuration cfg = ContainerConfig.getConfiguration(containerName, configFile);
+        ContainerConfig.Configuration.Property initialCtxProp = cfg.getProperty("use-initial-context");
+        ContainerConfig.Configuration.Property lookupHostProp = cfg.getProperty("bound-host");
+        ContainerConfig.Configuration.Property lookupPortProp = cfg.getProperty("bound-port");
+        ContainerConfig.Configuration.Property lookupNameProp = cfg.getProperty("bound-name");
+        ContainerConfig.Configuration.Property delegatorProp = cfg.getProperty("delegator-name");
+        ContainerConfig.Configuration.Property clientProp = cfg.getProperty("client-factory");
+        ContainerConfig.Configuration.Property serverProp = cfg.getProperty("server-factory");
 
         // check the required lookup-name property
         if (lookupNameProp == null || UtilValidate.isEmpty(lookupNameProp.value)) {

Modified: ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/AdminClient.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/AdminClient.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/AdminClient.java (original)
+++ ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/AdminClient.java Sun Oct 16 09:07:08 2016
@@ -73,20 +73,15 @@ class AdminClient {
 
     private static String sendSocketCommand(OfbizSocketCommand socketCommand, Config config) throws IOException {
         String response = "OFBiz is Down";
-        try {
-            Socket socket = new Socket(config.adminAddress, config.adminPort);
+        try (Socket socket = new Socket(config.adminAddress, config.adminPort);
+                PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
+                BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
+
             // send the command
-            PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
             writer.println(config.adminKey + ":" + socketCommand);
             writer.flush();
             // read the reply
-            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
             response = reader.readLine();
-            reader.close();
-            // close the socket
-            writer.close();
-            socket.close();
-
         } catch (ConnectException e) {
             System.out.println("Could not connect to " + config.adminAddress + ":" + config.adminPort);
         }

Modified: ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/AdminServer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/AdminServer.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/AdminServer.java (original)
+++ ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/AdminServer.java Sun Oct 16 09:07:08 2016
@@ -24,7 +24,6 @@ import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.net.ServerSocket;
 import java.net.Socket;
-import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.ofbiz.base.start.Start.ServerState;
@@ -44,11 +43,11 @@ final class AdminServer extends Thread {
     }
 
     private ServerSocket serverSocket = null;
-    private List<StartupLoader> loaders = null;
+    private StartupLoader loader = null;
     private AtomicReference<ServerState> serverState = null;
     private Config config = null;
 
-    AdminServer(List<StartupLoader> loaders, AtomicReference<ServerState> serverState, Config config) throws StartupException {
+    AdminServer(StartupLoader loader, AtomicReference<ServerState> serverState, Config config) throws StartupException {
         super("OFBiz-AdminServer");
         try {
             this.serverSocket = new ServerSocket(config.adminPort, 1, config.adminAddress);
@@ -56,7 +55,7 @@ final class AdminServer extends Thread {
             throw new StartupException("Couldn't create server socket(" + config.adminAddress + ":" + config.adminPort + ")", e);
         }
         setDaemon(false);
-        this.loaders = loaders;
+        this.loader = loader;
         this.serverState = serverState;
         this.config = config;
     }
@@ -65,49 +64,38 @@ final class AdminServer extends Thread {
     public void run() {
         System.out.println("Admin socket configured on - " + config.adminAddress + ":" + config.adminPort);
         while (!Thread.interrupted()) {
-            try {
-                Socket clientSocket = serverSocket.accept();
-                System.out.println("Received connection from - " + clientSocket.getInetAddress() + " : "
+            try (Socket clientSocket = serverSocket.accept()){
+
+                System.out.println("Received connection from - " 
+                        + clientSocket.getInetAddress() + " : "
                         + clientSocket.getPort());
-                processClientRequest(clientSocket, loaders, serverState);
-                clientSocket.close();
+
+                processClientRequest(clientSocket, loader, serverState);
+
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }
 
-    private void processClientRequest(Socket client, List<StartupLoader> loaders, AtomicReference<ServerState> serverState) throws IOException {
-        BufferedReader reader = null;
-        PrintWriter writer = null;
-        try {
-            reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
-            writer = new PrintWriter(client.getOutputStream(), true);
+    private void processClientRequest(Socket client, StartupLoader loader, AtomicReference<ServerState> serverState) throws IOException {
 
-            executeClientRequest(reader, writer, loaders, serverState);
-        } finally {
-            if (reader != null) {
-                reader.close();
-            }
-            if (writer != null) {
-                writer.flush();
-                writer.close();
-            }
-        }
-    }
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
+                PrintWriter writer = new PrintWriter(client.getOutputStream(), true)) {
 
-    private void executeClientRequest(BufferedReader reader, PrintWriter writer,
-            List<StartupLoader> loaders, AtomicReference<ServerState> serverState) throws IOException {
+            // read client request and prepare response
+            String clientRequest = reader.readLine();
+            OfbizSocketCommand clientCommand = determineClientCommand(clientRequest);
+            String serverResponse = prepareResponseToClient(clientCommand, serverState);
 
-        String clientRequest = reader.readLine();
-        OfbizSocketCommand clientCommand = determineClientCommand(clientRequest);
-        String serverResponse = prepareResponseToClient(clientCommand, serverState);
-        
-        writer.println(serverResponse);
-
-        if(clientCommand.equals(OfbizSocketCommand.SHUTDOWN)) {
-            writer.flush();
-            StartupControlPanel.stop(loaders, serverState, this);
+            // send response back to client
+            writer.println(serverResponse);
+
+            // if the client request is shutdown, execute shutdown sequence
+            if(clientCommand.equals(OfbizSocketCommand.SHUTDOWN)) {
+                writer.flush();
+                StartupControlPanel.stop(loader, serverState, this);
+            }
         }
     }
 

Modified: ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java (original)
+++ ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/Config.java Sun Oct 16 09:07:08 2016
@@ -25,8 +25,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -48,7 +46,7 @@ public final class Config {
     public final int portOffset;
     public final int adminPort;
     public final String containerConfig;
-    public final List<Map<String, String>> loaders;
+    public final Map<String, String> loader;
     public final String logDir;
     public final boolean shutdownAfterLoad;
     public final boolean useShutdownHook;
@@ -72,7 +70,7 @@ public final class Config {
         portOffset = getPortOffsetValue(ofbizCommands);
         adminPort = getAdminPort(props, portOffset);
         containerConfig = getAbsolutePath(props, "ofbiz.container.config", "framework/base/config/ofbiz-containers.xml", ofbizHome);
-        loaders = getLoaders(props);
+        loader = getLoader(props);
         logDir = getAbsolutePath(props, "ofbiz.log.dir", "runtime/logs", ofbizHome);
         shutdownAfterLoad = isShutdownAfterLoad(props);
         useShutdownHook = isUseShutdownHook(props);
@@ -234,25 +232,11 @@ public final class Config {
         return calculatedAdminPort;
     }
 
-    private List<Map<String, String>> getLoaders(Properties props) {
-        ArrayList<Map<String, String>> loadersTmp = new ArrayList<Map<String, String>>();
-        int currentPosition = 1;
-        Map<String, String> loader = null;
-        while (true) {
-            loader = new HashMap<String, String>();
-            String loaderClass = props.getProperty("ofbiz.start.loader" + currentPosition);
-
-            if (loaderClass == null || loaderClass.length() == 0) {
-                break;
-            } else {
-                loader.put("class", loaderClass);
-                loader.put("profiles", props.getProperty("ofbiz.start.loader" + currentPosition + ".loaders"));
-                loadersTmp.add(Collections.unmodifiableMap(loader));
-                currentPosition++;
-            }
-        }
-        loadersTmp.trimToSize();
-        return Collections.unmodifiableList(loadersTmp);
+    private Map<String, String> getLoader(Properties props) {
+        Map<String, String> loader = new HashMap<String, String>();
+        loader.put("class", props.getProperty("ofbiz.start.loader"));
+        loader.put("profiles", props.getProperty("ofbiz.start.loader.loaders"));
+        return loader;
     }
 
     private String getOfbizHome(Properties props) {

Modified: ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupCommand.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupCommand.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupCommand.java (original)
+++ ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupCommand.java Sun Oct 16 09:07:08 2016
@@ -18,6 +18,7 @@
  *******************************************************************************/
 package org.apache.ofbiz.base.start;
 
+import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -29,7 +30,7 @@ import java.util.Map;
  * For example: <code>java -jar build/libs/ofbiz.jar --status</code> where status is a command.
  * </p>
  */
-final class StartupCommand {
+public final class StartupCommand {
     private String name;
     private Map<String,String> properties;
 
@@ -59,6 +60,13 @@ final class StartupCommand {
             this.properties = properties;
             return this;
         }
+        public Builder addProperty(String key, String value) {
+            if(properties == null) {
+                properties = new HashMap<String,String>();
+            }
+            properties.put(key, value);
+            return this;
+        }
 
         public StartupCommand build() {
             return new StartupCommand(this);

Modified: ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupCommandUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupCommandUtil.java?rev=1765127&r1=1765126&r2=1765127&view=diff
==============================================================================
--- ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupCommandUtil.java (original)
+++ ofbiz/trunk/framework/start/src/main/java/org/apache/ofbiz/base/start/StartupCommandUtil.java Sun Oct 16 09:07:08 2016
@@ -20,7 +20,6 @@ package org.apache.ofbiz.base.start;
 
 import java.io.PrintStream;
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -46,7 +45,7 @@ import org.apache.commons.cli.ParseExcep
  * in addition to utility methods for parsing and handling these options
  * </p> 
  */
-final class StartupCommandUtil {
+public final class StartupCommandUtil {
 
     /* 
      * Make sure of defining the same set of values in:
@@ -180,36 +179,6 @@ final class StartupCommandUtil {
                 );
     }
 
-    /**
-     * Generates the loaderArgs with arguments as expected by the
-     * containers that will receive them. 
-     * 
-     * TODO A better solution is to change the signature of all 
-     * containers to receive a <tt>List</tt> of <tt>StartupCommand</tt>s
-     * instead and delete the methods adaptStartupCommandsToLoaderArgs
-     * and retrieveCommandArguments along with the loaderArgs list.
-     */
-    static List<String> adaptStartupCommandsToLoaderArgs(List<StartupCommand> ofbizCommands) {
-        List<String> loaderArgs = new ArrayList<String>();
-        final String LOAD_DATA = StartupCommandUtil.StartupOption.LOAD_DATA.getName();
-        final String TEST = StartupCommandUtil.StartupOption.TEST.getName();
-        
-        if(ofbizCommands.stream().anyMatch(command -> command.getName().equals(LOAD_DATA))) {
-            retrieveCommandArguments(ofbizCommands, LOAD_DATA).entrySet().stream().forEach(entry -> 
-            loaderArgs.add("-" + entry.getKey() + "=" + entry.getValue()));
-        } else if(ofbizCommands.stream().anyMatch(command -> command.getName().equals(TEST))) {
-            retrieveCommandArguments(ofbizCommands, TEST).entrySet().stream().forEach(entry -> 
-            loaderArgs.add("-" + entry.getKey() + "=" + entry.getValue()));
-        }
-        return loaderArgs;
-    }
-
-    private static Map<String,String> retrieveCommandArguments(List<StartupCommand> ofbizCommands, String commandName) {
-        return ofbizCommands.stream()
-                .filter(option-> option.getName().equals(commandName))
-                .collect(Collectors.toList()).get(0).getProperties();
-    }
-
     private static final Options getOfbizStartupOptions() {
         OptionGroup ofbizCommandOptions = new OptionGroup();
         ofbizCommandOptions.addOption(HELP);