Improved: Refactor and simplify the startup sequence in OFBiz
(OFBIZ-8337)

Continuing the refactoring work on the startup sequence, this commit
specifically focuses on the ComponentContainer and how it loads
components into the system. The following changes are made:

- simplify and cleanup the ofbiz-containers.xml to have only one entry
- substantially simplify the ComponentLoaderConfig class and remove unnecessary defined state
- delete the JustLoadComponentsContainer (used to exist for the server command --testlist which no longer exists)
- fully refactor the ComponentContainer class and breakup the messy logic into chunks of private methods. The methods are also properly documented.
- remove an old reference to the testlist container which no longer exists



git-svn-id: https://svn.apache.org/repos/asf/ofbiz/trunk@1772256 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/base/config/ofbiz-containers.xml b/framework/base/config/ofbiz-containers.xml
index 405c50e..726fadc 100644
--- a/framework/base/config/ofbiz-containers.xml
+++ b/framework/base/config/ofbiz-containers.xml
@@ -22,14 +22,6 @@
         xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-containers.xsd">
 
     <!-- load the ofbiz component container (always first) -->
-    <container name="component-container" loaders="main,rmi,load-data" class="org.apache.ofbiz.base.container.ComponentContainer"/>
-
-    <container name="component-container-test" loaders="test" class="org.apache.ofbiz.base.container.ComponentContainer"/>
-
-    <container name="component-container-limited" loaders="limited" class="org.apache.ofbiz.base.container.ComponentContainer">
-        <property name="update-classpath" value="false"/>
-    </container>
-
-    <container name="component-container" loaders="testlist" class="org.apache.ofbiz.base.container.JustLoadComponentsContainer"/>
+    <container name="component-container" loaders="main,rmi,load-data,test" class="org.apache.ofbiz.base.container.ComponentContainer"/>
 
 </ofbiz-containers>
diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/component/ComponentLoaderConfig.java b/framework/base/src/main/java/org/apache/ofbiz/base/component/ComponentLoaderConfig.java
index 810d2c9..611bdad 100644
--- a/framework/base/src/main/java/org/apache/ofbiz/base/component/ComponentLoaderConfig.java
+++ b/framework/base/src/main/java/org/apache/ofbiz/base/component/ComponentLoaderConfig.java
@@ -24,7 +24,6 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
 
 import javax.xml.parsers.ParserConfigurationException;
 
@@ -37,70 +36,29 @@
 import org.xml.sax.SAXException;
 
 /**
- * ComponentLoaderConfig - Component Loader configuration
+ * ComponentLoaderConfig - Component Loader configuration utility class
+ * to handle component-load.xml files
  *
  */
-public class ComponentLoaderConfig {
+public final class ComponentLoaderConfig {
 
     public static final String module = ComponentLoaderConfig.class.getName();
     public static final String COMPONENT_LOAD_XML_FILENAME = "component-load.xml";
-    public static final int SINGLE_COMPONENT = 0;
-    public static final int COMPONENT_DIRECTORY = 1;
-    private static final AtomicReference<List<ComponentDef>> componentDefsRef = new AtomicReference<List<ComponentDef>>(null);
 
-    public static List<ComponentDef> getRootComponents(String configFile) throws ComponentException {
-        List<ComponentDef> existingInstance = componentDefsRef.get();
-        if (existingInstance == null) {
-            if (configFile == null) {
-                configFile = COMPONENT_LOAD_XML_FILENAME;
-            }
-            URL xmlUrl = UtilURL.fromResource(configFile);
-            List<ComponentDef> newInstance = getComponentsFromConfig(xmlUrl);
-            if (componentDefsRef.compareAndSet(existingInstance, newInstance)) {
-                existingInstance = newInstance;
-            } else {
-                existingInstance = componentDefsRef.get();
-            }
-        }
-        return existingInstance;
+    public enum ComponentType { SINGLE_COMPONENT, COMPONENT_DIRECTORY }
+
+    public static List<ComponentDef> getRootComponents() throws ComponentException {
+        URL xmlUrl = UtilURL.fromResource(COMPONENT_LOAD_XML_FILENAME);
+        return getComponentsFromConfig(xmlUrl);
     }
 
     public static List<ComponentDef> getComponentsFromConfig(URL configUrl) throws ComponentException {
-        if (configUrl == null) {
-            throw new IllegalArgumentException("configUrl cannot be null");
-        }
-        Document document = null;
-        try {
-            document = UtilXml.readXmlDocument(configUrl, true);
-        } catch (SAXException e) {
-            throw new ComponentException("Error reading the component config file: " + configUrl, e);
-        } catch (ParserConfigurationException e) {
-            throw new ComponentException("Error reading the component config file: " + configUrl, e);
-        } catch (IOException e) {
-            throw new ComponentException("Error reading the component config file: " + configUrl, e);
-        }
-        Element root = document.getDocumentElement();
-        List<? extends Element> toLoad = UtilXml.childElementList(root);
-        List<ComponentDef> componentsFromConfig = null;
-        if (!toLoad.isEmpty()) {
-            componentsFromConfig = new ArrayList<ComponentDef>(toLoad.size());
-            Map<String, ? extends Object> systemProps = UtilGenerics.<String, Object> checkMap(System.getProperties());
-            for (Element element : toLoad) {
-                String nodeName = element.getNodeName();
-                String name = null;
-                String location = null;
-                int type = SINGLE_COMPONENT;
-                if ("load-component".equals(nodeName)) {
-                    name = element.getAttribute("component-name");
-                    location = FlexibleStringExpander.expandString(element.getAttribute("component-location"), systemProps);
-                } else if ("load-components".equals(nodeName)) {
-                    location = FlexibleStringExpander.expandString(element.getAttribute("parent-directory"), systemProps);
-                    type = COMPONENT_DIRECTORY;
-                } else {
-                    throw new ComponentException("Invalid element '" + nodeName + "' found in component config file " + configUrl);
-                }
-                componentsFromConfig.add(new ComponentDef(name, location, type));
-            }
+        Document document = parseDocumentFromUrl(configUrl);
+        List<? extends Element> toLoad = UtilXml.childElementList(document.getDocumentElement());
+        List<ComponentDef> componentsFromConfig = new ArrayList<ComponentDef>();
+
+        for (Element element : toLoad) {
+            componentsFromConfig.add(retrieveComponentDefFromElement(element, configUrl));
         }
         return Collections.unmodifiableList(componentsFromConfig);
     }
@@ -108,12 +66,44 @@
     public static class ComponentDef {
         public String name;
         public final String location;
-        public final int type;
+        public final ComponentType type;
 
-        private ComponentDef(String name, String location, int type) {
+        private ComponentDef(String name, String location, ComponentType type) {
             this.name = name;
             this.location = location;
             this.type = type;
         }
     }
+
+    private static Document parseDocumentFromUrl(URL configUrl) throws ComponentException {
+        if (configUrl == null) {
+            throw new ComponentException("configUrl cannot be null");
+        }
+        try {
+            return UtilXml.readXmlDocument(configUrl, true);
+        } catch (SAXException | ParserConfigurationException | IOException e) {
+            throw new ComponentException("Error reading the component config file: " + configUrl, e);
+        }
+    }
+
+    private static ComponentDef retrieveComponentDefFromElement(Element element, URL configUrl) throws ComponentException {
+        Map<String, ? extends Object> systemProps = UtilGenerics.<String, Object> checkMap(System.getProperties());
+        String nodeName = element.getNodeName();
+
+        String name = null;
+        String location = null;
+        ComponentType type = null;
+
+        if ("load-component".equals(nodeName)) {
+            name = element.getAttribute("component-name");
+            location = FlexibleStringExpander.expandString(element.getAttribute("component-location"), systemProps);
+            type = ComponentType.SINGLE_COMPONENT;
+        } else if ("load-components".equals(nodeName)) {
+            location = FlexibleStringExpander.expandString(element.getAttribute("parent-directory"), systemProps);
+            type = ComponentType.COMPONENT_DIRECTORY;
+        } else {
+            throw new ComponentException("Invalid element '" + nodeName + "' found in component-load file " + configUrl);
+        }
+        return new ComponentDef(name, location, type);
+    }
 }
diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/container/ComponentContainer.java b/framework/base/src/main/java/org/apache/ofbiz/base/container/ComponentContainer.java
index be38e60..3172dd4 100644
--- a/framework/base/src/main/java/org/apache/ofbiz/base/container/ComponentContainer.java
+++ b/framework/base/src/main/java/org/apache/ofbiz/base/container/ComponentContainer.java
@@ -31,24 +31,25 @@
 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.Start;
 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;
 
 /**
  * ComponentContainer - StartupContainer implementation for Components
- * <p/>
- * Example ofbiz-container.xml configuration:
- * <pre>
- *   <container name="component-container" class="org.apache.ofbiz.base.component.ComponentContainer"/>
- * </pre>
+ *
+ * The purpose of this container is to load the classpath for all components
+ * defined in OFBiz. This container must run before any other containers to
+ * allow components to access any necessary resources. Furthermore, the
+ * ComponentContainer also builds up the <code>ComponentConfigCache</code>
+ * to keep track of all loaded components
+ *
  */
 public class ComponentContainer implements Container {
 
     public static final String module = ComponentContainer.class.getName();
 
-    protected String configFileLocation = null;
     private String name;
     private final AtomicBoolean loaded = new AtomicBoolean(false);
 
@@ -58,23 +59,16 @@
             throw new ContainerException("Components already loaded, cannot start");
         }
         this.name = name;
-        this.configFileLocation = configFile;
 
-        // get the config for this container
-        ContainerConfig.Configuration cc = ContainerConfig.getConfiguration(name, configFileLocation);
-
-        // check for an override loader config
-        String loaderConfig = null;
-        if (cc.getProperty("loader-config") != null) {
-            loaderConfig = cc.getProperty("loader-config").value;
-        }
-
-        // load the components
+        // load the components from framework/base/config/component-load.xml (root components)
         try {
-            loadComponents(loaderConfig);
-        } catch (ComponentException e) {
+            for (ComponentLoaderConfig.ComponentDef def: ComponentLoaderConfig.getRootComponents()) {
+                loadComponentFromConfig(Start.getInstance().getConfig().ofbizHome, def);
+            }
+        } catch (IOException | ComponentException e) {
             throw new ContainerException(e);
         }
+        Debug.logInfo("All components loaded", module);
     }
 
     /**
@@ -84,166 +78,186 @@
         return loaded.get();
     }
 
-    public void loadComponents(String loaderConfig) throws ComponentException {
-        // get the components to load
-        List<ComponentLoaderConfig.ComponentDef> components = ComponentLoaderConfig.getRootComponents(loaderConfig);
-        String parentPath;
+    /**
+     * Checks if <code>ComponentDef.type</code> is a directory or a single component.
+     * If it is a directory, load the directory, otherwise load a single component
+     *
+     * @param parentPath: the parent path of what is being loaded
+     * @param def: the component or directory loader definition
+     * @throws IOException
+     */
+    private void loadComponentFromConfig(String parentPath, ComponentLoaderConfig.ComponentDef def) throws IOException {
+        String location = def.location.startsWith("/") ? def.location : parentPath + "/" + def.location;
+
+        if (def.type.equals(ComponentLoaderConfig.ComponentType.COMPONENT_DIRECTORY)) {
+            loadComponentDirectory(location);
+        } else if (def.type.equals(ComponentLoaderConfig.ComponentType.SINGLE_COMPONENT)) {
+            ComponentConfig config = retrieveComponentConfig(def.name, location);
+            if (config != null) {
+                loadComponent(config);
+            }
+        }
+    }
+
+    /**
+     * Checks to see if the directory contains a load file (component-load.xml) and
+     * then delegates loading to the appropriate method
+     *
+     * @param directoryName: the name of component directory to load
+     * @throws IOException
+     */
+    private void loadComponentDirectory(String directoryName) throws IOException {
+        Debug.logInfo("Auto-Loading component directory : [" + directoryName + "]", module);
+
+        File directoryPath = FileUtil.getFile(directoryName);
+        if (directoryPath.exists() && directoryPath.isDirectory()) {
+            File componentLoadFile = new File(directoryPath, ComponentLoaderConfig.COMPONENT_LOAD_XML_FILENAME);
+            if (componentLoadFile != null && componentLoadFile.exists()) {
+                loadComponentsInDirectoryUsingLoadFile(directoryPath, componentLoadFile);
+            } else {
+                loadComponentsInDirectory(directoryPath);
+            }
+        } else {
+            Debug.logError("Auto-Load Component directory not found : " + directoryName, module);
+        }
+
+    }
+
+    /**
+     * load components residing in a directory only if they exist in the component
+     * load file (component-load.xml) and they are sorted in order from top to bottom
+     * in the load file
+     *
+     * @param directoryPath: the absolute path of the directory
+     * @param componentLoadFile: the name of the load file (i.e. component-load.xml)
+     * @throws IOException
+     */
+    private void loadComponentsInDirectoryUsingLoadFile(File directoryPath, File componentLoadFile) throws IOException {
+        URL configUrl = null;
         try {
-            parentPath = FileUtil.getFile(System.getProperty("ofbiz.home")).getCanonicalFile().toString().replaceAll("\\\\", "/");
-            // load each component
-            if (components != null) {
-                for (ComponentLoaderConfig.ComponentDef def: components) {
-                    loadComponentFromConfig(parentPath, def);
+            configUrl = componentLoadFile.toURI().toURL();
+            List<ComponentLoaderConfig.ComponentDef> componentsToLoad = ComponentLoaderConfig.getComponentsFromConfig(configUrl);
+            if (componentsToLoad != null) {
+                for (ComponentLoaderConfig.ComponentDef def: componentsToLoad) {
+                    loadComponentFromConfig(directoryPath.toString(), def);
                 }
             }
         } catch (MalformedURLException e) {
-            throw new ComponentException(e.getMessage(), e);
-        } catch (IOException e) {
-            throw new ComponentException(e.getMessage(), e);
-        }
-        Debug.logInfo("All components loaded", module);
-    }
-
-    private void loadComponentFromConfig(String parentPath, ComponentLoaderConfig.ComponentDef def) throws IOException {
-        String location;
-        if (def.location.startsWith("/")) {
-            location = def.location;
-        } else {
-            location = parentPath + "/" + def.location;
-        }
-        if (def.type == ComponentLoaderConfig.SINGLE_COMPONENT) {
-            ComponentConfig config = null;
-            try {
-                config = ComponentConfig.getComponentConfig(def.name, location);
-                if (UtilValidate.isEmpty(def.name)) {
-                    def.name = config.getGlobalName();
-                }
-            } catch (ComponentException e) {
-                Debug.logError("Cannot load component : " + def.name + " @ " + def.location + " : " + e.getMessage(), module);
-            }
-            if (config == null) {
-                Debug.logError("Cannot load component : " + def.name + " @ " + def.location, module);
-            } else {
-                this.loadComponent(config);
-            }
-        } else if (def.type == ComponentLoaderConfig.COMPONENT_DIRECTORY) {
-            this.loadComponentDirectory(location);
+            Debug.logError(e, "Unable to locate URL for component loading file: " + componentLoadFile.getAbsolutePath(), module);
+        } catch (ComponentException e) {
+            Debug.logError(e, "Unable to load components from URL: " + configUrl.toExternalForm(), module);
         }
     }
 
-    private void loadComponentDirectory(String directoryName) throws IOException {
-        Debug.logInfo("Auto-Loading component directory : [" + directoryName + "]", module);
-        File parentPath = FileUtil.getFile(directoryName);
-        if (!parentPath.exists() || !parentPath.isDirectory()) {
-            Debug.logError("Auto-Load Component directory not found : " + directoryName, module);
-        } else {
-            File componentLoadConfig = new File(parentPath, ComponentLoaderConfig.COMPONENT_LOAD_XML_FILENAME);
-            if (componentLoadConfig != null && componentLoadConfig.exists()) {
-                URL configUrl = null;
-                try {
-                    configUrl = componentLoadConfig.toURI().toURL();
-                    List<ComponentLoaderConfig.ComponentDef> componentsToLoad = ComponentLoaderConfig.getComponentsFromConfig(configUrl);
-                    if (componentsToLoad != null) {
-                        for (ComponentLoaderConfig.ComponentDef def: componentsToLoad) {
-                            this.loadComponentFromConfig(parentPath.toString(), def);
-                        }
-                    }
-                } catch (MalformedURLException e) {
-                    Debug.logError(e, "Unable to locate URL for component loading file: " + componentLoadConfig.getAbsolutePath(), module);
-                } catch (ComponentException e) {
-                    Debug.logError(e, "Unable to load components from URL: " + configUrl.toExternalForm(), module);
-                }
-            } else {
-                String[] fileNames = parentPath.list();
-                Arrays.sort(fileNames);
-                for (String sub: fileNames) {
-                    try {
-                        File componentPath = FileUtil.getFile(parentPath.getCanonicalPath() + File.separator + sub);
-                        if (componentPath.isDirectory() && !sub.equals("CVS") && !sub.equals(".svn")) {
-                            // make sure we have a component configuration file
-                            String componentLocation = componentPath.getCanonicalPath();
-                            File configFile = FileUtil.getFile(componentLocation.concat(File.separator).concat(ComponentConfig.OFBIZ_COMPONENT_XML_FILENAME));
-                            if (configFile.exists()) {
-                                ComponentConfig config = null;
-                                try {
-                                    // pass null for the name, will default to the internal component name
-                                    config = ComponentConfig.getComponentConfig(null, componentLocation);
-                                } catch (ComponentException e) {
-                                    Debug.logError(e, "Cannot load component : " + componentPath.getName() + " @ " + componentLocation + " : " + e.getMessage(), module);
-                                }
-                                if (config == null) {
-                                    Debug.logError("Cannot load component : " + componentPath.getName() + " @ " + componentLocation, module);
-                                } else {
-                                    loadComponent(config);
-                                }
-                            }
-                        }
-                    } catch (IOException ioe) {
-                        Debug.logError(ioe, module);
-                    }
+    /**
+     * Load all components in a directory because it does not contain 
+     * a load-components.xml file. The components are sorted alphabetically
+     * for loading purposes
+     *
+     * @param directoryPath: the absolute path of the directory
+     * @throws IOException
+     */
+    private void loadComponentsInDirectory(File directoryPath) throws IOException {
+        String[] sortedComponentNames = directoryPath.list();
+        Arrays.sort(sortedComponentNames);
+
+        for (String componentName: sortedComponentNames) {
+            File componentPath = FileUtil.getFile(directoryPath.getCanonicalPath() + File.separator + componentName);
+            String componentLocation = componentPath.getCanonicalPath();
+            File configFile = FileUtil.getFile(componentLocation.concat(File.separator).concat(ComponentConfig.OFBIZ_COMPONENT_XML_FILENAME));
+
+            if (componentPath.isDirectory() && !componentName.startsWith(".") && configFile.exists()) {
+                ComponentConfig config = retrieveComponentConfig(null, componentLocation);
+                if (config != null) { 
+                    loadComponent(config);
                 }
             }
         }
     }
 
+    /**
+     * Fetch the <code>ComponentConfig</code> for a certain component
+     *
+     * @param name: component name
+     * @param location: directory location of the component
+     * @return The component configuration
+     */
+    private ComponentConfig retrieveComponentConfig(String name, String location) {
+        ComponentConfig config = null;
+        try {
+            config = ComponentConfig.getComponentConfig(name, location);
+        } catch (ComponentException e) {
+            Debug.logError("Cannot load component : " + name + " @ " + location + " : " + e.getMessage(), module);
+        }
+        if (config == null) {
+            Debug.logError("Cannot load component : " + name + " @ " + location, module);
+        }
+        return config;
+    }
+
+    /**
+     * Load a single component by adding all its classpath entries to
+     * the classloader
+     *
+     * @param config: the component configuration
+     * @throws IOException
+     */
     private void loadComponent(ComponentConfig config) throws IOException {
-        // make sure the component is enabled
         if (!config.enabled()) {
             Debug.logInfo("Not loading component [" + config.getComponentName() + "] because it is disabled", module);
             return;
         }
-        List<ComponentConfig.ClasspathInfo> classpathInfos = config.getClasspathInfos();
-        String configRoot = config.getRootLocation();
-        configRoot = configRoot.replace('\\', '/');
-        // set the root to have a trailing slash
-        if (!configRoot.endsWith("/")) {
-            configRoot = configRoot + "/";
+
+        NativeLibClassLoader classloader = (NativeLibClassLoader) Thread.currentThread().getContextClassLoader();
+        Classpath classPath = buildClasspathFromComponentConfig(config);
+
+        for (URL url : classPath.getUrls()) {
+            classloader.addURL(url);
         }
-        if (classpathInfos != null) {
-            Classpath classPath = new Classpath();
-            // TODO: If any components change the class loader, then this will need to be changed.
-            NativeLibClassLoader classloader = (NativeLibClassLoader) Thread.currentThread().getContextClassLoader();
-            for (ComponentConfig.ClasspathInfo cp: classpathInfos) {
-                String location = cp.location.replace('\\', '/');
-                // set the location to not have a leading slash
-                if (location.startsWith("/")) {
-                    location = location.substring(1);
-                }
-                if (!"jar".equals(cp.type) && !"dir".equals(cp.type)) {
-                    Debug.logError("Classpath type '" + cp.type + "' is not supported; '" + location + "' not loaded", module);
-                    continue;
-                }
-                String dirLoc = location;
-                if (dirLoc.endsWith("/*")) {
-                    // strip off the slash splat
-                    dirLoc = location.substring(0, location.length() - 2);
-                }
-                File path = FileUtil.getFile(configRoot + dirLoc);
-                if (path.exists()) {
-                    if (path.isDirectory()) {
-                        if ("dir".equals(cp.type)) {
-                            classPath.addComponent(configRoot + location);
-                        }
-                        classPath.addFilesFromPath(path);
-                    } else {
-                        // add a single file
-                        classPath.addComponent(configRoot + location);
-                    }
-                } else {
-                    Debug.logWarning("Location '" + configRoot + dirLoc + "' does not exist", module);
-                }
-            }
-            for (URL url : classPath.getUrls()) {
-                classloader.addURL(url);
-            }
-            for (File folder : classPath.getNativeFolders()) {
-                classloader.addNativeClassPath(folder);
-            }
+        for (File folder : classPath.getNativeFolders()) {
+            classloader.addNativeClassPath(folder);
         }
-         Debug.logInfo("Loaded component : [" + config.getComponentName() + "]", module);
+
+        Debug.logInfo("Loaded component : [" + config.getComponentName() + "]", module);
     }
 
     /**
+     * Construct a <code>Classpath</code> object for a certain component based
+     * on its configuration defined in <code>ComponentConfig</code>
+     *
+     * @param config: the component configuration
+     * @return the constructed classpath
+     * @throws IOException
+     */
+    private Classpath buildClasspathFromComponentConfig(ComponentConfig config) throws IOException {
+        Classpath classPath = new Classpath();
+        String configRoot = config.getRootLocation().replace('\\', '/');
+        configRoot = configRoot.endsWith("/") ? configRoot : configRoot + "/";
+        List<ComponentConfig.ClasspathInfo> classpathInfos = config.getClasspathInfos();
+
+        for (ComponentConfig.ClasspathInfo cp: classpathInfos) {
+            String location = cp.location.replace('\\', '/');
+            if (!"jar".equals(cp.type) && !"dir".equals(cp.type)) {
+                Debug.logError("Classpath type '" + cp.type + "' is not supported; '" + location + "' not loaded", module);
+                continue;
+            }
+
+            location = location.startsWith("/") ? location.substring(1) : location;
+            String dirLoc = location.endsWith("/*") ? location.substring(0, location.length() - 2) : location; 
+            File path = FileUtil.getFile(configRoot + dirLoc);
+
+            if (path.exists()) {
+                classPath.addComponent(configRoot + location);
+                if (path.isDirectory() && "dir".equals(cp.type)) {
+                    classPath.addFilesFromPath(path);
+                }
+            } else {
+                Debug.logWarning("Location '" + configRoot + dirLoc + "' does not exist", module);
+            }
+        }
+        return classPath;
+    }
+    /**
      * @see org.apache.ofbiz.base.container.Container#stop()
      */
     public void stop() throws ContainerException {
diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/container/JustLoadComponentsContainer.java b/framework/base/src/main/java/org/apache/ofbiz/base/container/JustLoadComponentsContainer.java
deleted file mode 100644
index d9c35e3..0000000
--- a/framework/base/src/main/java/org/apache/ofbiz/base/container/JustLoadComponentsContainer.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.apache.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.
- */
-public class JustLoadComponentsContainer implements Container {
-
-    public static final String module = JustLoadComponentsContainer.class.getName();
-
-    private String name;
-
-    @Override
-    public void init(List<StartupCommand> ofbizCommands, String name, String configFile) {
-        this.name = name;
-        try {
-            ComponentContainer cc = new ComponentContainer();
-            cc.loadComponents(null);
-        } catch (AlreadyLoadedException e) {
-            Debug.logError(e, module);
-        } catch (ComponentException e) {
-            Debug.logError(e, module);
-        }
-    }
-
-    public boolean start() throws ContainerException {
-        return true;
-    }
-
-    public void stop() throws ContainerException {
-    }
-
-    public String getName() {
-        return name;
-    }
-}
diff --git a/framework/testtools/ofbiz-component.xml b/framework/testtools/ofbiz-component.xml
index 24c1d7a..e1e0dfd 100644
--- a/framework/testtools/ofbiz-component.xml
+++ b/framework/testtools/ofbiz-component.xml
@@ -31,6 +31,4 @@
     <service-resource type="model" loader="main" location="servicedef/services.xml"/>
 
     <container name="testtools-container" loaders="test" class="org.apache.ofbiz.testtools.TestRunContainer"/>
-    <container name="testtools-container" loaders="testlist" class="org.apache.ofbiz.testtools.TestListContainer"/>
-
 </ofbiz-component>
\ No newline at end of file