You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2011/03/22 17:22:54 UTC
svn commit: r1084238 - in /ofbiz/trunk/framework:
base/src/org/ofbiz/base/container/ContainerLoader.java
webapp/src/org/ofbiz/webapp/control/ContextFilter.java
Author: adrianc
Date: Tue Mar 22 16:22:54 2011
New Revision: 1084238
URL: http://svn.apache.org/viewvc?rev=1084238&view=rev
Log:
Some work on ContainerLoader.java - Fixes some thread-safe issues and try to have better control over loading/starting/stopping containers.
I'm not sure what the Geronimo code was supposed to do. It appeared to load all of the containers just so it could create/start the rmi-dispatcher container. So, I created a static method that allows client code to get a specific container. If this change causes problems with Geronimo just let me know and I will fix it.
Modified:
ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ContainerLoader.java
ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java
Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ContainerLoader.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ContainerLoader.java?rev=1084238&r1=1084237&r2=1084238&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ContainerLoader.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/container/ContainerLoader.java Tue Mar 22 16:22:54 2011
@@ -25,6 +25,8 @@ import java.util.Collection;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.ofbiz.base.start.Start;
import org.ofbiz.base.start.StartupException;
@@ -33,40 +35,48 @@ import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilValidate;
/**
- * ContainerLoader - StartupLoader for the container
+ * An object that loads containers (background processes).
+ *
+ * <p>Normally, instances of this class are created by OFBiz startup code, and
+ * client code should not create instances of this class. Client code is
+ * responsible for making sure containers are shut down properly. </p>
*
*/
public class ContainerLoader implements StartupLoader {
public static final String module = ContainerLoader.class.getName();
- public static final String CONTAINER_CONFIG = "ofbiz-containers.xml";
- private static boolean loaded = false;
- public static Container rmiLoadedContainer = null; // used in Geronimo/WASCE to allow to deregister
+ private static Map<String, Container> containerMap = new ConcurrentHashMap<String, Container>();
- public static synchronized Container loadContainers(String config, String[] args) throws StartupException {
- if (!loaded) {
- ContainerLoader loader = new ContainerLoader();
- Start.Config cfg = new Start.Config();
- cfg.containerConfig = config == null ? "limited-containers.xml" : config;
- loader.load(cfg, args);
- if (rmiLoadedContainer != null) { // used in Geronimo/WASCE to allow to deregister
- return rmiLoadedContainer;
- }
- }
- return null;
+ /**
+ * Returns a <code>Container</code> that has the specified name. Returns
+ * <code>null</code> if the specified container was not loaded. If more than one
+ * instance of the container was loaded, then the last instance that was loaded is
+ * returned. The returned <code>Container</code> will be initialized, but there is no
+ * guarantee that it will be in the running state.
+ *
+ * @param containerName
+ * The name of the container.
+ * @return A <code>Container</code> that has the specified name.
+ */
+ public static Container getContainer(String containerName) {
+ return containerMap.get(containerName);
}
- protected String configFile = null;
- protected List<Container> loadedContainers = new LinkedList<Container>();
+ private String configFile = null;
+ private final List<Container> loadedContainers = new LinkedList<Container>();
+ private boolean unloading = false;
+ private boolean loaded = false;
/**
* @see org.ofbiz.base.start.StartupLoader#load(Start.Config, String[])
*/
- public void load(Start.Config config, String args[]) throws StartupException {
+ public synchronized void load(Start.Config config, String args[]) throws StartupException {
+ if (this.loaded || this.unloading) {
+ return;
+ }
Debug.logInfo("[Startup] Loading containers...", module);
- loaded = true;
-
- // get the master container configuration file
+ this.loadedContainers.clear();
+ // get this loader's configuration file
this.configFile = config.containerConfig;
Collection<ContainerConfig.Container> containers = null;
try {
@@ -78,9 +88,14 @@ public class ContainerLoader implements
throw new StartupException(e);
}
for (ContainerConfig.Container containerCfg : containers) {
+ if (this.unloading) {
+ return;
+ }
Container tmpContainer = loadContainer(containerCfg, args);
- loadedContainers.add(tmpContainer);
+ this.loadedContainers.add(tmpContainer);
+ containerMap.put(containerCfg.name, tmpContainer);
+ // TODO: Put container-specific code in the container.
// This is only used in case of OFBiz running in Geronimo or WASCE. It allows to use the RMIDispatcher
if (containerCfg.name.equals("rmi-dispatcher") && configFile.equals("limited-containers.xml")) {
try {
@@ -92,7 +107,6 @@ public class ContainerLoader implements
System.setSecurityManager(new java.rmi.RMISecurityManager());
}
tmpContainer.start();
- rmiLoadedContainer = tmpContainer; // used in Geronimo/WASCE to allow to deregister
}
} catch (ContainerException e) {
throw new StartupException("Cannot start() " + tmpContainer.getClass().getName(), e);
@@ -101,23 +115,32 @@ public class ContainerLoader implements
}
}
}
+ if (this.unloading) {
+ return;
+ }
// 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()) {
+ 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) {
- loadedContainers.add(loadContainer(containerCfg, args));
+ if (this.unloading) {
+ return;
+ }
+ Container tmpContainer = loadContainer(containerCfg, args);
+ this.loadedContainers.add(tmpContainer);
+ containerMap.put(containerCfg.name, tmpContainer);
}
}
} catch (Exception e) {
Debug.logError(e, "Could not load hot-deploy-containers.xml", module);
throw new StartupException(e);
}
+ loaded = true;
}
private Container loadContainer(ContainerConfig.Container containerCfg, String[] args) throws StartupException {
@@ -193,11 +216,16 @@ public class ContainerLoader implements
/**
* @see org.ofbiz.base.start.StartupLoader#start()
*/
- public void start() throws StartupException {
+ public synchronized void start() throws StartupException {
+ if (!this.loaded || this.unloading) {
+ throw new IllegalStateException("start() called on unloaded containers");
+ }
Debug.logInfo("[Startup] Starting containers...", module);
-
// start each container object
- for (Container container: loadedContainers) {
+ for (Container container: this.loadedContainers) {
+ if (this.unloading) {
+ return;
+ }
try {
container.start();
} catch (ContainerException e) {
@@ -212,17 +240,22 @@ public class ContainerLoader implements
* @see org.ofbiz.base.start.StartupLoader#unload()
*/
public void unload() throws StartupException {
- Debug.logInfo("Shutting down containers", module);
- if (Debug.verboseOn())
- printThreadDump();
-
- // shutting down in reverse order
- for (int i = loadedContainers.size(); i > 0; i--) {
- Container container = loadedContainers.get(i-1);
- try {
- container.stop();
- } catch (ContainerException e) {
- Debug.logError(e, module);
+ 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);
+ try {
+ container.stop();
+ } catch (ContainerException e) {
+ Debug.logError(e, module);
+ }
+ }
}
}
}
Modified: ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java?rev=1084238&r1=1084237&r2=1084238&view=diff
==============================================================================
--- ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java (original)
+++ ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/control/ContextFilter.java Tue Mar 22 16:22:54 2011
@@ -490,14 +490,7 @@ public class ContextFilter implements Fi
}
protected Container getContainers() throws ServletException {
- Container rmiLoadedContainer = null;
- try {
- rmiLoadedContainer = ContainerLoader.loadContainers(CONTAINER_CONFIG, null); // used in Geronimo/WASCE to allow to unregister
- } catch (StartupException e) {
- Debug.logError(e, module);
- throw new ServletException("Unable to load containers; cannot start ContextFilter");
- }
- return rmiLoadedContainer;
+ return ContainerLoader.getContainer("rmi-dispatcher");
}
// used in Geronimo/WASCE to allow to deregister