[jbpm-commits] JBoss JBPM SVN: r4759 - in jbpm3/branches/jbpm-3.2.5.SP/modules/core/src: main/java/org/jbpm/configuration and 6 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Thu May 7 09:21:23 EDT 2009
Author: alex.guizar at jboss.com
Date: 2009-05-07 09:21:23 -0400 (Thu, 07 May 2009)
New Revision: 4759
Added:
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/SharedProcessClassLoaderFactory.java
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/instantiation/ConfigurableClassLoadersTest.java
Removed:
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/instantiation/ConfigurableClassloadersTest.java
Modified:
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/DefaultProcessClassLoaderFactory.java
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoaderFactory.java
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/util/XmlUtil.java
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/resources/org/jbpm/default.jbpm.cfg.xml
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/JbpmConfigurationTest.java
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/JbpmContextTest.java
jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/jpdl/par/ProcessClassLoaderTest.java
Log:
[JBPM-2202] merge r4689 from trunk;
take parent class loader into account when looking up a cached process class loader
Modified: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -24,10 +24,11 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
-import java.util.Stack;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -48,30 +49,31 @@
/**
* configuration of one jBPM instance.
- *
* <p>
- * During process execution, jBPM might need to use some services. A JbpmConfiguration contains the knowledge on how to
- * create those services.
+ * During process execution, jBPM might need to use some services. A JbpmConfiguration contains the
+ * knowledge on how to create those services.
* </p>
- *
* <p>
- * A JbpmConfiguration is a thread safe object and serves as a factory for {@link org.jbpm.JbpmContext}s, which means
- * one JbpmConfiguration can be used to create {@link org.jbpm.JbpmContext}s for all threads. The single
- * JbpmConfiguration can be maintained in a static member or in the JNDI tree if that is available.
+ * A JbpmConfiguration is a thread safe object and serves as a factory for
+ * {@link org.jbpm.JbpmContext}s, which means one JbpmConfiguration can be used to create
+ * {@link org.jbpm.JbpmContext}s for all threads. The single JbpmConfiguration can be maintained in
+ * a static member or in the JNDI tree if that is available.
* </p>
- *
* <p>
* A JbpmConfiguration can be obtained in following ways:
+ * </p>
* <ul>
* <li>from a resource (by default <code>jbpm.cfg.xml</code> is used):
*
* <pre>
+ *
* JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
* </pre>
*
* or
*
* <pre>
+ *
* String myXmlResource = "...";
* JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance(myXmlResource);
* </pre>
@@ -88,8 +90,8 @@
* </pre>
*
* </li>
- * <li>By specifying a custom implementation of an object factory. This can be used to specify a JbpmConfiguration in
- * other bean-style notations such as used by JBoss Microcontainer or Spring.
+ * <li>By specifying a custom implementation of an object factory. This can be used to specify a
+ * JbpmConfiguration in other bean-style notations such as used by JBoss Microcontainer or Spring.
*
* <pre>
* ObjectFactory of = new <i>MyCustomObjectFactory</i>();
@@ -99,10 +101,9 @@
*
* </li>
* </ul>
- * </p>
- *
* <p>
- * JbpmConfigurations can be configured using a spring-like XML notation (in relax ng compact notation):
+ * JbpmConfigurations can be configured using a spring-like XML notation (in relax ng compact
+ * notation):
* </p>
*
* <pre>
@@ -234,123 +235,97 @@
* </pre>
*
* </p>
- *
* <p>
* Other configuration properties
+ * </p>
* <table>
* <tr>
* <td>jbpm.files.dir</td>
- * <td></td>
+ * <td/>
* </tr>
* <tr>
* <td>jbpm.types</td>
- * <td></td>
+ * <td/>
* </tr>
* </table>
- * </p>
*/
-public class JbpmConfiguration implements Serializable
-{
+public class JbpmConfiguration implements Serializable {
private static final long serialVersionUID = 1L;
static ObjectFactory defaultObjectFactory;
- static Map instances = new HashMap();
- static ThreadLocal jbpmConfigurationsStacks = new ThreadLocal();
+ static final Map instances = new HashMap();
+ static final ThreadLocal jbpmConfigurationStacks = new StackThreadLocal();
- private ObjectFactory objectFactory;
- private ThreadLocal jbpmContextStacks = new ThreadLocal();
+ private final ObjectFactory objectFactory;
+ private final ThreadLocal jbpmContextStacks = new StackThreadLocal();
private JobExecutor jobExecutor;
+ private boolean isClosed;
- public JbpmConfiguration(ObjectFactory objectFactory)
- {
+ static class StackThreadLocal extends ThreadLocal {
+
+ protected Object initialValue() {
+ return new ArrayList();
+ }
+ }
+
+ public JbpmConfiguration(ObjectFactory objectFactory) {
this.objectFactory = objectFactory;
}
- public static JbpmConfiguration getInstance()
- {
+ public static JbpmConfiguration getInstance() {
return getInstance(null);
}
- public static JbpmConfiguration getInstance(String resource)
- {
- JbpmConfiguration instance = null;
- synchronized (instances)
- {
- if (resource == null)
- {
- resource = "jbpm.cfg.xml";
- }
+ public static JbpmConfiguration getInstance(String resource) {
+ if (resource == null) {
+ resource = "jbpm.cfg.xml";
+ }
- instance = (JbpmConfiguration)instances.get(resource);
- if (instance == null)
- {
-
- if (defaultObjectFactory != null)
- {
- log.debug("creating jbpm configuration from given default object factory '" + defaultObjectFactory + "'");
+ JbpmConfiguration instance;
+ synchronized (instances) {
+ // look for configuration in cache
+ instance = (JbpmConfiguration) instances.get(resource);
+ if (instance == null) {
+ // configuration does not exist or was evicted, construct it
+ if (defaultObjectFactory != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("creating configuration from default object factory: " + defaultObjectFactory);
+ }
instance = new JbpmConfiguration(defaultObjectFactory);
-
}
- else
- {
-
- try
- {
- log.info("using jbpm configuration resource '" + resource + "'");
- InputStream jbpmCfgXmlStream = ClassLoaderUtil.getJbpmConfigurationStream(resource);
-
- // if a custom resource is to be used, but is not found in the
- // classpath
- // log a warning (otherwise, users who want to load custom stuff
- // will be confused if the resource is not found and not loaded,
- // without
- // any notice)
- if (jbpmCfgXmlStream == null && !"jbpm.cfg.xml".equals(resource))
- {
- log.warn("jbpm configuration resource '" + resource + "' is not available");
- }
-
- ObjectFactory objectFactory = parseObjectFactory(jbpmCfgXmlStream);
- instance = createJbpmConfiguration(objectFactory);
-
+ else {
+ log.info("using configuration resource: " + resource);
+ InputStream jbpmCfgXmlStream = ClassLoaderUtil.getStream(resource, false);
+ /*
+ * if a custom resource is specified, but not found in the classpath, log a warning;
+ * otherwise, users who want to load custom stuff will not receive any feedback when their
+ * resource cannot be found
+ */
+ if (jbpmCfgXmlStream == null && !"jbpm.cfg.xml".equals(resource)) {
+ log.warn("configuration resource '" + resource + "' could not be found");
}
- catch (RuntimeException e)
- {
- throw new JbpmException("couldn't parse jbpm configuration from resource '" + resource + "'", e);
- }
+ ObjectFactory objectFactory = parseObjectFactory(jbpmCfgXmlStream);
+ instance = createJbpmConfiguration(objectFactory);
}
-
+ // put configuration in cache
instances.put(resource, instance);
}
}
-
return instance;
}
- public static boolean hasInstance(String resource)
- {
- boolean hasInstance = false;
- if (resource == null)
- {
- resource = "jbpm.cfg.xml";
- }
- if ((instances != null) && (instances.containsKey(resource)))
- {
- hasInstance = true;
- }
- return hasInstance;
+ public static boolean hasInstance(String resource) {
+ return instances.containsKey(resource != null ? resource : "jbpm.cfg.xml");
}
- protected static ObjectFactory parseObjectFactory(InputStream inputStream)
- {
+ protected static ObjectFactory parseObjectFactory(InputStream inputStream) {
log.debug("loading defaults in jbpm configuration");
ObjectFactoryParser objectFactoryParser = new ObjectFactoryParser();
ObjectFactoryImpl objectFactoryImpl = new ObjectFactoryImpl();
objectFactoryParser.parseElementsFromResource("org/jbpm/default.jbpm.cfg.xml", objectFactoryImpl);
- if (inputStream != null)
- {
+ if (inputStream != null) {
log.debug("loading specific configuration...");
objectFactoryParser.parseElementsStream(inputStream, objectFactoryImpl);
}
@@ -358,34 +333,26 @@
return objectFactoryImpl;
}
- /**
- * create an ObjectFacotory from an XML string.
- */
- public static JbpmConfiguration parseXmlString(String xml)
- {
+ public static JbpmConfiguration parseXmlString(String xml) {
log.debug("creating jbpm configuration from xml string");
InputStream inputStream = null;
- if (xml != null)
- {
+ if (xml != null) {
inputStream = new ByteArrayInputStream(xml.getBytes());
}
ObjectFactory objectFactory = parseObjectFactory(inputStream);
return createJbpmConfiguration(objectFactory);
}
- protected static JbpmConfiguration createJbpmConfiguration(ObjectFactory objectFactory)
- {
+ protected static JbpmConfiguration createJbpmConfiguration(ObjectFactory objectFactory) {
JbpmConfiguration jbpmConfiguration = new JbpmConfiguration(objectFactory);
- // now we make the bean jbpm.configuration always availble
- if (objectFactory instanceof ObjectFactoryImpl)
- {
- ObjectFactoryImpl objectFactoryImpl = (ObjectFactoryImpl)objectFactory;
+ // make the bean jbpm.configuration always available
+ if (objectFactory instanceof ObjectFactoryImpl) {
+ ObjectFactoryImpl objectFactoryImpl = (ObjectFactoryImpl) objectFactory;
ObjectInfo jbpmConfigurationInfo = new ValueInfo("jbpmConfiguration", jbpmConfiguration);
objectFactoryImpl.addObjectInfo(jbpmConfigurationInfo);
- if (getHideStaleObjectExceptions(objectFactory))
- {
+ if (getHideStaleObjectExceptions(objectFactory)) {
StaleObjectLogConfigurer.hideStaleObjectExceptions();
}
}
@@ -393,77 +360,68 @@
return jbpmConfiguration;
}
- private static boolean getHideStaleObjectExceptions(ObjectFactory objectFactory)
- {
- if (!objectFactory.hasObject("jbpm.hide.stale.object.exceptions"))
- {
- return true;
- }
+ private static boolean getHideStaleObjectExceptions(ObjectFactory objectFactory) {
+ if (!objectFactory.hasObject("jbpm.hide.stale.object.exceptions")) return true;
+
Object object = objectFactory.createObject("jbpm.hide.stale.object.exceptions");
- return object instanceof Boolean ? ((Boolean)object).booleanValue() : true;
+ return object instanceof Boolean ? ((Boolean) object).booleanValue() : true;
}
- public static JbpmConfiguration parseInputStream(InputStream inputStream)
- {
- ObjectFactory objectFactory = parseObjectFactory(inputStream);
+ public static JbpmConfiguration parseInputStream(InputStream inputStream) {
log.debug("creating jbpm configuration from input stream");
+ ObjectFactory objectFactory = parseObjectFactory(inputStream);
return createJbpmConfiguration(objectFactory);
}
- public static JbpmConfiguration parseResource(String resource)
- {
+ public static JbpmConfiguration parseResource(String resource) {
+ if (log.isDebugEnabled()) {
+ log.debug("creating jbpm configuration from resource: " + resource);
+ }
InputStream inputStream = null;
- log.debug("creating jbpm configuration from resource '" + resource + "'");
- if (resource != null)
- {
- inputStream = ClassLoaderUtil.getJbpmConfigurationStream(resource);
+ if (resource != null) {
+ inputStream = ClassLoaderUtil.getStream(resource, false);
}
ObjectFactory objectFactory = parseObjectFactory(inputStream);
return createJbpmConfiguration(objectFactory);
}
- public JbpmContext createJbpmContext()
- {
+ public JbpmContext createJbpmContext() {
return createJbpmContext(JbpmContext.DEFAULT_JBPM_CONTEXT_NAME);
}
- public JbpmContext createJbpmContext(String name)
- {
- JbpmContext jbpmContext = (JbpmContext)objectFactory.createObject(name);
+ public JbpmContext createJbpmContext(String name) {
+ ensureOpen();
+
+ JbpmContext jbpmContext = (JbpmContext) objectFactory.createObject(name);
jbpmContext.jbpmConfiguration = this;
jbpmContextCreated(jbpmContext);
return jbpmContext;
}
- public ServiceFactory getServiceFactory(String serviceName)
- {
+ private void ensureOpen() {
+ if (isClosed) throw new JbpmException("configuration closed");
+ }
+
+ public ServiceFactory getServiceFactory(String serviceName) {
return getServiceFactory(serviceName, JbpmContext.DEFAULT_JBPM_CONTEXT_NAME);
}
- public ServiceFactory getServiceFactory(String serviceName, String jbpmContextName)
- {
- ServiceFactory serviceFactory = null;
+ public ServiceFactory getServiceFactory(String serviceName, String jbpmContextName) {
JbpmContext jbpmContext = createJbpmContext(jbpmContextName);
- try
- {
- serviceFactory = jbpmContext.getServices().getServiceFactory(serviceName);
+ try {
+ return jbpmContext.getServices().getServiceFactory(serviceName);
}
- finally
- {
+ finally {
jbpmContext.close();
}
- return serviceFactory;
}
- public static ClassLoader getProcessClassLoader(ProcessDefinition processDefinition)
- {
- ProcessClassLoaderFactory factory = null;
- if (Configs.hasObject("jbpm.processClassLoader"))
- {
- factory = (ProcessClassLoaderFactory)Configs.getObject("jbpm.processClassLoader");
+ public static ClassLoader getProcessClassLoader(ProcessDefinition processDefinition) {
+ ProcessClassLoaderFactory factory;
+ if (Configs.hasObject("process.class.loader.factory")) {
+ factory = (ProcessClassLoaderFactory) Configs.getObject("process.class.loader.factory");
}
- else
- {
+ else {
factory = new DefaultProcessClassLoaderFactory();
}
return factory.getProcessClassLoader(processDefinition);
@@ -472,270 +430,232 @@
/**
* gives the jbpm domain model access to configuration information via the current JbpmContext.
*/
- public abstract static class Configs
- {
+ public static class Configs {
- public static ObjectFactory getObjectFactory()
- {
+ private Configs() {
+ // hide default constructor to prevent instantiation
+ }
+
+ public static ObjectFactory getObjectFactory() {
ObjectFactory objectFactory = null;
JbpmContext jbpmContext = JbpmContext.getCurrentJbpmContext();
- if (jbpmContext != null)
- {
+ if (jbpmContext != null) {
objectFactory = jbpmContext.objectFactory;
}
- else
- {
+ else {
objectFactory = getInstance().objectFactory;
}
return objectFactory;
}
- public static void setDefaultObjectFactory(ObjectFactory objectFactory)
- {
+ public static void setDefaultObjectFactory(ObjectFactory objectFactory) {
defaultObjectFactory = objectFactory;
}
- public static boolean hasObject(String name)
- {
+ public static boolean hasObject(String name) {
ObjectFactory objectFactory = getObjectFactory();
return objectFactory.hasObject(name);
}
- public static synchronized Object getObject(String name)
- {
+ public static synchronized Object getObject(String name) {
ObjectFactory objectFactory = getObjectFactory();
return objectFactory.createObject(name);
}
- public static String getString(String name)
- {
- return (String)getObject(name);
+ public static String getString(String name) {
+ return (String) getObject(name);
}
- public static long getLong(String name)
- {
- return ((Long)getObject(name)).longValue();
+ public static long getLong(String name) {
+ return ((Long) getObject(name)).longValue();
}
- public static int getInt(String name)
- {
- return ((Integer)getObject(name)).intValue();
+ public static int getInt(String name) {
+ return ((Integer) getObject(name)).intValue();
}
- public static boolean getBoolean(String name)
- {
- return ((Boolean)getObject(name)).booleanValue();
+ public static boolean getBoolean(String name) {
+ return ((Boolean) getObject(name)).booleanValue();
}
}
- public void cleanSchema()
- {
+ public void cleanSchema() {
cleanSchema(JbpmContext.DEFAULT_JBPM_CONTEXT_NAME);
}
- public void cleanSchema(String jbpmContextName)
- {
- JbpmContext jbpmContext = createJbpmContext(jbpmContextName);
- try
- {
- Services services = jbpmContext.getServices();
- DbPersistenceServiceFactory persistenceServiceFactory = (DbPersistenceServiceFactory)services.getServiceFactory(Services.SERVICENAME_PERSISTENCE);
- persistenceServiceFactory.cleanSchema();
- }
- finally
- {
- jbpmContext.close();
- }
+ public void cleanSchema(String jbpmContextName) {
+ getPersistenceServiceFactory(jbpmContextName).cleanSchema();
}
- public void createSchema()
- {
+ public void createSchema() {
createSchema(JbpmContext.DEFAULT_JBPM_CONTEXT_NAME);
}
- public void createSchema(String jbpmContextName)
- {
- JbpmContext jbpmContext = createJbpmContext(jbpmContextName);
- try
- {
- Services services = jbpmContext.getServices();
- DbPersistenceServiceFactory persistenceServiceFactory = (DbPersistenceServiceFactory)services.getServiceFactory(Services.SERVICENAME_PERSISTENCE);
- persistenceServiceFactory.createSchema();
- }
- finally
- {
- jbpmContext.close();
- }
+ public void createSchema(String jbpmContextName) {
+ getPersistenceServiceFactory(jbpmContextName).createSchema();
}
- public void dropSchema()
- {
+ public void dropSchema() {
dropSchema(JbpmContext.DEFAULT_JBPM_CONTEXT_NAME);
}
- public void dropSchema(String jbpmContextName)
- {
- log.warn("Dropping schema: " + jbpmContextName);
- JbpmContext jbpmContext = createJbpmContext(jbpmContextName);
- try
- {
- Services services = jbpmContext.getServices();
- DbPersistenceServiceFactory persistenceServiceFactory = (DbPersistenceServiceFactory)services.getServiceFactory(Services.SERVICENAME_PERSISTENCE);
- persistenceServiceFactory.dropSchema();
- }
- finally
- {
- jbpmContext.close();
- }
+ public void dropSchema(String jbpmContextName) {
+ getPersistenceServiceFactory(jbpmContextName).dropSchema();
}
- public void close()
- {
- close(JbpmContext.DEFAULT_JBPM_CONTEXT_NAME);
+ private DbPersistenceServiceFactory getPersistenceServiceFactory(String jbpmContextName) {
+ return (DbPersistenceServiceFactory) getServiceFactory(Services.SERVICENAME_PERSISTENCE, jbpmContextName);
}
- public void close(String jbpmContextName)
- {
- JbpmContext jbpmContext = createJbpmContext(jbpmContextName);
- try
- {
+ public boolean isClosed() {
+ return isClosed;
+ }
- synchronized (instances)
- {
- Iterator iter = instances.values().iterator();
- while (iter.hasNext())
- {
- if (this == iter.next())
- {
- iter.remove();
- break;
- }
- }
- }
+ public void close() {
+ close(JbpmContext.DEFAULT_JBPM_CONTEXT_NAME);
+ }
- if (jobExecutor != null)
- {
- jobExecutor.stop();
- }
+ public void close(String jbpmContextName) {
+ // prevent configuration from being closed more than once
+ if (isClosed) return;
+ // stop job executor
+ if (jobExecutor != null) {
+ jobExecutor.stop();
+ jobExecutor = null;
+ }
+
+ // close service factories
+ JbpmContext jbpmContext = createJbpmContext(jbpmContextName);
+ try {
Map serviceFactories = jbpmContext.getServices().getServiceFactories();
- if (serviceFactories != null)
- {
- Iterator iter = serviceFactories.values().iterator();
- while (iter.hasNext())
- {
- ServiceFactory serviceFactory = (ServiceFactory)iter.next();
+ if (serviceFactories != null) {
+ for (Iterator i = serviceFactories.values().iterator(); i.hasNext();) {
+ ServiceFactory serviceFactory = (ServiceFactory) i.next();
serviceFactory.close();
}
}
}
- finally
- {
+ finally {
jbpmContext.close();
}
+
+ // closing service factories requires open configuration
+ isClosed = true;
+
+ // release context stack
+ jbpmContextStacks.set(null);
+
+ // remove from configuration cache
+ synchronized (instances) {
+ for (Iterator i = instances.values().iterator(); i.hasNext();) {
+ if (this == i.next()) {
+ i.remove();
+ break;
+ }
+ }
+ }
}
- static JbpmConfiguration getCurrentJbpmConfiguration()
- {
+ static JbpmConfiguration getCurrentJbpmConfiguration() {
JbpmConfiguration currentJbpmConfiguration = null;
- Stack stack = getJbpmConfigurationStack();
- if (!stack.isEmpty())
- {
- currentJbpmConfiguration = (JbpmConfiguration)stack.peek();
+ List stack = getJbpmConfigurationStack();
+ if (!stack.isEmpty()) {
+ currentJbpmConfiguration = (JbpmConfiguration) stack.get(stack.size() - 1);
}
return currentJbpmConfiguration;
}
- static synchronized Stack getJbpmConfigurationStack()
- {
- Stack stack = (Stack)jbpmConfigurationsStacks.get();
- if (stack == null)
- {
- stack = new Stack();
- jbpmConfigurationsStacks.set(stack);
+ static List getJbpmConfigurationStack() {
+ return (List) jbpmConfigurationStacks.get();
+ }
+
+ static void clearJbpmConfigurationStack() {
+ List configStack = getJbpmConfigurationStack();
+ if (configStack != null) {
+ Object[] configs = configStack.toArray();
+ for (int f = 0; f < configs.length; f++) {
+ JbpmConfiguration config = (JbpmConfiguration) configs[f];
+ List contextStack = config.getJbpmContextStack();
+ if (contextStack != null) {
+ Object[] contexts = contextStack.toArray();
+ for (int t = 0; t < contexts.length; t++) {
+ JbpmContext context = (JbpmContext) contexts[t];
+ context.close();
+ }
+ }
+ contextStack.clear();
+ }
+ configStack.clear();
}
- return stack;
}
- synchronized void pushJbpmConfiguration()
- {
- getJbpmConfigurationStack().push(this);
+ synchronized void pushJbpmConfiguration() {
+ getJbpmConfigurationStack().add(this);
}
- synchronized void popJbpmConfiguration()
- {
+ synchronized void popJbpmConfiguration() {
getJbpmConfigurationStack().remove(this);
}
- public JbpmContext getCurrentJbpmContext()
- {
+ public JbpmContext getCurrentJbpmContext() {
+ ensureOpen();
+
JbpmContext currentJbpmContext = null;
- Stack stack = getJbpmContextStack();
- if (!stack.isEmpty())
- {
- currentJbpmContext = (JbpmContext)stack.peek();
+ List stack = getJbpmContextStack();
+ if (!stack.isEmpty()) {
+ currentJbpmContext = (JbpmContext) stack.get(stack.size() - 1);
}
return currentJbpmContext;
}
- Stack getJbpmContextStack()
- {
- Stack stack = (Stack)jbpmContextStacks.get();
- if (stack == null)
- {
- stack = new Stack();
- jbpmContextStacks.set(stack);
- }
- return stack;
+ List getJbpmContextStack() {
+ return (List) jbpmContextStacks.get();
}
- void pushJbpmContext(JbpmContext jbpmContext)
- {
- getJbpmContextStack().push(jbpmContext);
+ void pushJbpmContext(JbpmContext jbpmContext) {
+ getJbpmContextStack().add(jbpmContext);
}
- void popJbpmContext(JbpmContext jbpmContext)
- {
- Stack stack = getJbpmContextStack();
- if (stack.isEmpty())
- {
- throw new JbpmException("closed JbpmContext more then once... check your try-finally's around JbpmContexts blocks");
+ void popJbpmContext(JbpmContext jbpmContext) {
+ List stack = getJbpmContextStack();
+ int size = stack.size();
+ if (size == 0) {
+ log.warn("closed JbpmContext more than once... "
+ + "check your try-finally clauses around JbpmContext blocks");
}
- JbpmContext popped = (JbpmContext)stack.pop();
- if (jbpmContext != popped)
- {
- throw new JbpmException("closed JbpmContext in different order then they were created... check your try-finally's around JbpmContexts blocks");
+ else if (jbpmContext != stack.remove(size - 1)) {
+ stack.remove(jbpmContext); // prevent context from remaining in the stack
+ log.warn("closed JbpmContext in some order that differs from creation... "
+ + "check your try-finally clauses around JbpmContext blocks");
}
}
- void jbpmContextCreated(JbpmContext jbpmContext)
- {
+ void jbpmContextCreated(JbpmContext jbpmContext) {
pushJbpmConfiguration();
pushJbpmContext(jbpmContext);
}
- void jbpmContextClosed(JbpmContext jbpmContext)
- {
- popJbpmConfiguration();
+ void jbpmContextClosed(JbpmContext jbpmContext) {
popJbpmContext(jbpmContext);
+ popJbpmConfiguration();
}
- public void startJobExecutor()
- {
+ public void startJobExecutor() {
getJobExecutor().start();
}
- public synchronized JobExecutor getJobExecutor()
- {
- if (jobExecutor == null)
- {
- try
- {
- jobExecutor = (JobExecutor)this.objectFactory.createObject("jbpm.job.executor");
+ public synchronized JobExecutor getJobExecutor() {
+ ensureOpen();
+
+ if (jobExecutor == null) {
+ Object object = objectFactory.createObject("jbpm.job.executor");
+ if (object instanceof JobExecutor) {
+ jobExecutor = (JobExecutor) object;
}
- catch (ClassCastException e)
- {
- throw new JbpmException("jbpm configuration object under key 'jbpm.job.executor' is not a " + JobExecutor.class.getName(), e);
+ else if (object != null) {
+ throw new JbpmException("configuration object 'jbpm.job.executor' is not an "
+ + JobExecutor.class.getName());
}
}
return jobExecutor;
Modified: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -37,6 +37,7 @@
private static final long serialVersionUID = 1L;
+ ClassLoader classLoader = null; // lazy load it later! See below..
List objectInfos = null;
Map namedObjectInfos = null;
Map singletons = new HashMap();
@@ -160,7 +161,14 @@
// "lazy load" classloader, shouldn't be loaded too early
// because if jbpm.cfg.xml is not yet parsed, the correct class loader
// may not be initialized yet.
- return ClassLoaderUtil.loadClass(className);
+ if (classLoader==null) {
+ classLoader = ClassLoaderUtil.getClassLoader();
+ }
+ try {
+ return classLoader.loadClass(className);
+ } catch (ClassNotFoundException e) {
+ throw new JbpmException("couldn't load class '"+className+"'", e);
+ }
}
Object getRegistryKey(ObjectInfo objectInfo) {
Modified: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/DefaultProcessClassLoaderFactory.java
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/DefaultProcessClassLoaderFactory.java 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/DefaultProcessClassLoaderFactory.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -1,7 +1,5 @@
package org.jbpm.instantiation;
-import java.io.Serializable;
-
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.util.ClassLoaderUtil;
@@ -10,12 +8,12 @@
*
* @author bernd.ruecker at camunda.com
*/
-public class DefaultProcessClassLoaderFactory implements ProcessClassLoaderFactory, Serializable {
-
+public class DefaultProcessClassLoaderFactory implements ProcessClassLoaderFactory {
+
private static final long serialVersionUID = 1L;
public ClassLoader getProcessClassLoader(ProcessDefinition processDefinition) {
// default behavior like before https://jira.jboss.org/jira/browse/JBPM-1148
return new ProcessClassLoader(ClassLoaderUtil.getClassLoader(), processDefinition);
- }
+ }
}
Modified: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoader.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -29,106 +29,127 @@
import java.net.URLConnection;
import java.net.URLStreamHandler;
+import org.jbpm.JbpmContext;
import org.jbpm.JbpmException;
import org.jbpm.file.def.FileDefinition;
import org.jbpm.graph.def.ProcessDefinition;
public class ProcessClassLoader extends ClassLoader {
-
- private ProcessDefinition processDefinition = null;
- public ProcessClassLoader( ClassLoader parent, ProcessDefinition processDefinition ) {
+ private ProcessDefinition processDefinition;
+ private long processDefinitionId;
+
+ public ProcessClassLoader(ClassLoader parent, ProcessDefinition processDefinition) {
super(parent);
- this.processDefinition = processDefinition;
+ // check whether the given process definition is transient
+ long id = processDefinition.getId();
+ if (id != 0) {
+ // persistent, keep id only
+ processDefinitionId = id;
+ }
+ else {
+ // transient, keep full object
+ this.processDefinition = processDefinition;
+ }
}
+ protected ProcessDefinition getProcessDefinition() {
+ return processDefinition != null ? processDefinition : JbpmContext.getCurrentJbpmContext()
+ .getGraphSession()
+ .loadProcessDefinition(processDefinitionId);
+ }
+
public URL findResource(String name) {
- URL url = null;
+ ProcessDefinition processDefinition = getProcessDefinition();
FileDefinition fileDefinition = processDefinition.getFileDefinition();
- if (fileDefinition!=null) {
- // if the name of the resources starts with a /
- if (name.startsWith("/")) {
- // then we start searching from the root of the process archive
+ if (fileDefinition != null) {
+ // we know that the leading slashes are removed in the names of the
+ // file definitions, therefore we skip the leading slashes
+ int off = 0;
+ for (int len = name.length(); off < len && name.charAt(off) == '/'; off++)
+ /* just increase offset */;
- // we know that the leading slashes are removed in the names of the
- // file definitions, therefor we skip the leading slashes
- while (name.startsWith("/")) {
- name = name.substring(1);
- }
- } else {
- // otherwise, (if the resource is relative), we look in the classes
+ // if the name of the resources is absolute (starts with one or more slashes)
+ if (off > 0) {
+ // then start searching from the root of the process archive
+ name = name.substring(off);
+ }
+ else {
+ // otherwise (if the resource is relative), look in the classes
// directory in the process archive
- name = "classes/"+name;
+ name = "classes/" + name;
}
byte[] bytes = null;
if (fileDefinition.hasFile(name)) {
bytes = fileDefinition.getBytes(name);
}
- if (bytes!=null) {
+ if (bytes != null) {
try {
- url = new URL(null, "processresource://"+processDefinition.getName()+"/classes/"+name, new BytesUrlStreamHandler(bytes));
- } catch (MalformedURLException e) {
+ return new URL(null, "processresource://"
+ + processDefinition.getName()
+ + "/classes/"
+ + name, new BytesUrlStreamHandler(bytes));
+ }
+ catch (MalformedURLException e) {
throw new JbpmException("couldn't create url", e);
}
}
}
- return url;
+ return null;
}
-
+
public static class BytesUrlStreamHandler extends URLStreamHandler {
+
byte[] bytes;
+
public BytesUrlStreamHandler(byte[] bytes) {
this.bytes = bytes;
}
+
protected URLConnection openConnection(URL u) throws IOException {
return new BytesUrlConnection(bytes, u);
}
}
public static class BytesUrlConnection extends URLConnection {
+
byte[] bytes = null;
+
public BytesUrlConnection(byte[] bytes, URL u) {
super(u);
this.bytes = bytes;
}
+
public void connect() throws IOException {
}
+
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(bytes);
}
}
- public Class findClass(String name) throws ClassNotFoundException {
- Class clazz = null;
+ public Class findClass(String className) throws ClassNotFoundException {
+ FileDefinition fileDefinition = getProcessDefinition().getFileDefinition();
+ if (fileDefinition != null) {
+ String fileName = "classes/" + className.replace('.', '/') + ".class";
+ byte[] classBytes = fileDefinition.getBytes(fileName);
- FileDefinition fileDefinition = processDefinition.getFileDefinition();
- if (fileDefinition!=null) {
- String fileName = "classes/" + name.replace( '.', '/' ) + ".class";
- byte[] classBytes;
- try {
- classBytes = fileDefinition.getBytes(fileName);
- clazz = defineClass(name, classBytes, 0, classBytes.length);
- } catch (JbpmException e) {
- clazz = null;
- }
-
- // Add the package information
- // see https://jira.jboss.org/jira/browse/JBPM-1404
- final int packageIndex = name.lastIndexOf('.');
- if (packageIndex != -1) {
- final String packageName = name.substring(0, packageIndex);
- final Package classPackage = getPackage(packageName);
- if (classPackage == null) {
- definePackage(packageName, null, null, null, null, null, null, null);
+ if (classBytes != null) {
+ // define the package before defining the class
+ // see https://jira.jboss.org/jira/browse/JBPM-1404
+ int packageIndex = className.lastIndexOf('.');
+
+ if (packageIndex != -1) {
+ String packageName = className.substring(0, packageIndex);
+
+ if (getPackage(packageName) == null) {
+ definePackage(packageName, null, null, null, processDefinition.getName(), Integer.toString(processDefinition.getVersion()), null, null);
+ }
}
+ return defineClass(className, classBytes, 0, classBytes.length);
}
}
-
- if (clazz==null) {
- throw new ClassNotFoundException("class '"+name+"' could not be found by the process classloader");
- }
-
- return clazz;
+ throw new ClassNotFoundException(className);
}
}
Modified: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoaderFactory.java
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoaderFactory.java 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/ProcessClassLoaderFactory.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -1,21 +1,31 @@
package org.jbpm.instantiation;
+import java.io.Serializable;
+
+import org.jbpm.JbpmConfiguration;
import org.jbpm.graph.def.ProcessDefinition;
/**
- * Factory to retrieve the Process{@link ClassLoader} which is then used
- * to load delegation classes used by the process.
+ * <p>
+ * Factory to retrieve the Process {@link ClassLoader} which is then used to load delegation classes
+ * used by the process.
+ * </p>
+ * <p>
+ * Default is the build in {@link ProcessClassLoader}, which tries to load the classes from the jBPM
+ * database first.
+ * </p>
+ * <p>
+ * Can be configured by setting the property <code>jbpm.process.class.loader</code> in the
+ * configuration file to the class name of the custom class loader.
+ * </p>
+ * <p>
+ * Implementations should be serializable, as the {@link JbpmConfiguration} that references them is.
+ * </p>
*
- * Default is the build in {@link ProcessClassLoader}, which
- * tries to load the classes from the jbpm database first.
- *
- * Can be configured by setting the property <b>'jbpm.processClassLoader'</b>
- * in the jbpm.cfg.xml to the class name of the custom class loader.
- *
* @author bernd.ruecker at camunda.com
*/
-public interface ProcessClassLoaderFactory {
+public interface ProcessClassLoaderFactory extends Serializable {
public ClassLoader getProcessClassLoader(ProcessDefinition processDefinition);
-
+
}
\ No newline at end of file
Copied: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/SharedProcessClassLoaderFactory.java (from rev 4689, jbpm3/trunk/modules/core/src/main/java/org/jbpm/instantiation/SharedProcessClassLoaderFactory.java)
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/SharedProcessClassLoaderFactory.java (rev 0)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/instantiation/SharedProcessClassLoaderFactory.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -0,0 +1,98 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.instantiation;
+
+import java.lang.ref.SoftReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.util.ClassLoaderUtil;
+
+/**
+ * Refined process class loader factory that maintains a cache of the class loaders it returns. The
+ * cache does not prevent class loaders from being discarded by the garbage collector.
+ *
+ * @author Alejandro Guizar
+ */
+public class SharedProcessClassLoaderFactory implements ProcessClassLoaderFactory {
+
+ private transient Map classLoaderRefs = new HashMap();
+
+ private static final long serialVersionUID = 1L;
+
+ public ClassLoader getProcessClassLoader(ProcessDefinition processDefinition) {
+ // determine the key to lookup a cached class loader
+ // observe that the given process definition may be transient
+ long id = processDefinition.getId();
+ if (id == 0L) id = processDefinition.hashCode();
+ Long key = new Long(id);
+ // consider that the context class loader changes among applications
+ ClassLoader parentClassLoader = ClassLoaderUtil.getClassLoader();
+ assert parentClassLoader != null : "parent class loader is null";
+
+ synchronized (classLoaderRefs) {
+ // lookup the class loader reference
+ ClassLoader processClassLoader = getProcessClassLoader(key, parentClassLoader);
+ // the reference may not exist or may have been cleared already
+ if (processClassLoader == null) {
+ // (re-)create the class loader and the reference
+ processClassLoader = new ProcessClassLoader(parentClassLoader, processDefinition);
+ // cache the reference
+ putProcessClassLoader(key, processClassLoader);
+ }
+ return processClassLoader;
+ }
+ }
+
+ private ClassLoader getProcessClassLoader(Long processDefinitionKey, ClassLoader parentClassLoader) {
+ List referenceList = (List) classLoaderRefs.get(processDefinitionKey);
+ if (referenceList != null) {
+ for (Iterator i = referenceList.iterator(); i.hasNext();) {
+ SoftReference reference = (SoftReference) i.next();
+ ClassLoader processClassLoader = (ClassLoader) reference.get();
+ // reference may have been cleared already
+ if (processClassLoader == null) {
+ // remove cleared reference
+ i.remove();
+ }
+ // process class loader may have a different parent
+ else if (processClassLoader.getParent() == parentClassLoader) {
+ return processClassLoader;
+ }
+ }
+ }
+ return null;
+ }
+
+ private void putProcessClassLoader(Long processDefinitionKey, ClassLoader processClassLoader) {
+ List referenceList = (List) classLoaderRefs.get(processDefinitionKey);
+ if (referenceList == null) {
+ referenceList = new ArrayList();
+ classLoaderRefs.put(processDefinitionKey, referenceList);
+ }
+ referenceList.add(new SoftReference(processClassLoader));
+ }
+}
Modified: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -29,126 +29,132 @@
import org.jbpm.JbpmException;
/**
- * provides centralized classloader lookup.
+ * provides centralized classloader lookup.
*/
-public class ClassLoaderUtil
-{
+public class ClassLoaderUtil {
- private ClassLoaderUtil()
- {
+ private ClassLoaderUtil() {
// hide default constructor to prevent instantiation
}
- public static Class loadClass(String className)
- {
- try
- {
+ /**
+ * Bad usage of ClassLoader.loadClass() under JDK 6.
+ *
+ * @deprecated Use {@linkplain #classForName(String) classForName()} instead
+ * @see <a href="https://jira.jboss.org/jira/browse/JBPM-1976">JBPM-1976</a>
+ */
+ public static Class loadClass(String className) {
+ try {
return getClassLoader().loadClass(className);
}
- catch (ClassNotFoundException e)
- {
+ catch (ClassNotFoundException e) {
throw new JbpmException("class not found '" + className + "'", e);
}
}
- /*
- * returns the {@link ClassLoader} which is used in jbpm. Can be configured in jbpm.cfg.xml by the property <b>'jbpm.classloader'</b> <td> <li>'jbpm': (default value)
- * uses the {@link ClassLoaderUtil}.class.getClassLoader() {@link ClassLoader}. This was the only behavior available before <a
- * href="https://jira.jboss.org/jira/browse/JBPM-1148">JBPM-1148</a>.</li> <li>'context': uses the Thread.currentThread().getContextClassLoader().</li> <li>'custom':
- * means that a ClassLoader class has to be provided in the property <b>'jbpm.classloader.classname'</b></li> </td>
+ public static Class classForName(String className) {
+ try {
+ return Class.forName(className, true, getClassLoader());
+ }
+ catch (ClassNotFoundException e) {
+ throw new JbpmException("class not found '" + className + "'", e);
+ }
+ }
+
+ public static Class classForName(String className, boolean useConfiguredLoader) {
+ if (useConfiguredLoader) return classForName(className);
+
+ // try context class loader first, so that applications can override provided classes
+ try {
+ return Class.forName(className, true, Thread.currentThread().getContextClassLoader());
+ }
+ catch (ClassNotFoundException e) {
+ // try the class loader of the current class
+ try {
+ return Class.forName(className);
+ }
+ catch (ClassNotFoundException e2) {
+ // give up
+ throw new JbpmException("class not found '" + className + "'", e);
+ }
+ }
+ }
+
+ /**
+ * Returns the {@link ClassLoader} employed by jBPM to load classes referenced in the
+ * configuration. The class loader can be changed in <code>jbpm.cfg.xml</code> by setting the
+ * string property <code>jbpm.class.loader</code>. The possible values are:
+ * <ul>
+ * <li><code>jbpm</code> (default) indicates the class loader of the jBPM classes. Before <a
+ * href="https://jira.jboss.org/jira/browse/JBPM-1148">JBPM-1148</a> no other behavior was
+ * available</li>
+ * <li><code>context</code> indicates the {@linkplain Thread#getContextClassLoader() context class
+ * loader}</li>
+ * <li>any other value is interpreted as a reference to a class loader bean described in the
+ * configuration</li>
+ * </ul>
*/
- public static ClassLoader getClassLoader()
- {
- if (JbpmConfiguration.Configs.hasObject("jbpm.classLoader"))
- {
- String jbpmClassloader = JbpmConfiguration.Configs.getString("jbpm.classLoader");
+ public static ClassLoader getClassLoader() {
+ if (JbpmConfiguration.Configs.hasObject("jbpm.class.loader")) {
+ String jbpmClassLoader = JbpmConfiguration.Configs.getString("jbpm.class.loader");
- if (jbpmClassloader.equals("jbpm"))
- {
+ if (jbpmClassLoader.equals("jbpm")) {
+ // use class loader that loaded the jbpm classes
return ClassLoaderUtil.class.getClassLoader();
}
- else if (jbpmClassloader.equals("context"))
- {
+
+ if (jbpmClassLoader.equals("context")) {
+ // use the context class loader
return Thread.currentThread().getContextClassLoader();
}
- else if (jbpmClassloader.equals("custom"))
- {
- String jbpmClassloaderClassname = null;
- try
- {
- if (!JbpmConfiguration.Configs.hasObject("jbpm.customClassLoader.className"))
- {
- throw new JbpmException("'jbpm.classloader' property set to 'custom' but 'jbpm.customClassLoader.className' is empty!");
- }
- jbpmClassloaderClassname = JbpmConfiguration.Configs.getString("jbpm.customClassLoader.className");
- if (jbpmClassloaderClassname == null)
- {
- throw new JbpmException("'jbpm.classloader' property set to 'custom' but 'jbpm.customClassLoader.className' is empty!");
- }
- Class clazz = ClassLoaderUtil.class.getClassLoader().loadClass(jbpmClassloaderClassname);
- if (clazz == null)
- clazz = Thread.currentThread().getContextClassLoader().loadClass(jbpmClassloaderClassname);
-
- return (ClassLoader)clazz.newInstance();
- }
- catch (InstantiationException e)
- {
- throw new JbpmException("Error instantiating custom classloader " + jbpmClassloaderClassname, e);
- }
- catch (IllegalAccessException e)
- {
- throw new JbpmException("Error accessing custom classloader " + jbpmClassloaderClassname, e);
- }
- catch (ClassNotFoundException e)
- {
- throw new JbpmException("Custom classloader " + jbpmClassloaderClassname + " not found ", e);
- }
+ // interpret value as a reference to a class loader bean
+ Object bean = JbpmConfiguration.Configs.getObject(jbpmClassLoader);
+ if (!(bean instanceof ClassLoader)) {
+ throw new JbpmException("bean '" + jbpmClassLoader + "' is not a class loader");
}
- else
- {
- throw new JbpmException("'jbpm.classloader' property set to '" + jbpmClassloader + "' but only the values 'jbpm'/'context'/'custom' are supported!");
- }
+ return (ClassLoader) bean;
}
- else
- {
- // default behavior like before https://jira.jboss.org/jira/browse/JBPM-1148
+ else {
+ // behave like before JBPM-1148
return ClassLoaderUtil.class.getClassLoader();
}
}
- public static InputStream getStream(String resource)
- {
+ public static InputStream getStream(String resource) {
return getClassLoader().getResourceAsStream(resource);
}
- /*
- * Load jbpm configuration related resources as stream (normally jbpm.cfg.xml). This method first tries to load the resource from the {@link ClassLoaderUtil} class
- * loader, if not found it tries the context class loader. If this doesn't return any ressource the call is delegated to the class loader configured by calling
- * getClassLoader(). This is a special method because the class loader which has to be used for loading the jbpm.cfg.xml cannot be configured in the jbpm.cfg.xml
- * itself.
+ /**
+ * Load jbpm configuration related resources as stream (normally jbpm.cfg.xml). This method first
+ * tries to load the resource from the {@link ClassLoaderUtil} class loader, if not found it tries
+ * the context class loader. If this doesn't return any ressource the call is delegated to the
+ * class loader configured by calling getClassLoader(). This is a special method because the class
+ * loader which has to be used for loading the jbpm.cfg.xml cannot be configured in the
+ * jbpm.cfg.xml itself.
*/
- public static InputStream getJbpmConfigurationStream(String resource)
- {
- InputStream jbpmCfgStream = ClassLoaderUtil.class.getClassLoader().getResourceAsStream(resource);
- if (jbpmCfgStream == null)
- {
- jbpmCfgStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
+ public static InputStream getStream(String resource, boolean useConfiguredLoader) {
+ if (useConfiguredLoader) return getStream(resource);
+
+ // try context class loader first, so that applications can override provided classes
+ InputStream stream = Thread.currentThread()
+ .getContextClassLoader()
+ .getResourceAsStream(resource);
+ if (stream == null) {
+ // try the class loader of the current class
+ stream = ClassLoaderUtil.class.getClassLoader().getResourceAsStream(resource);
}
- return jbpmCfgStream;
+ return stream;
}
- public static Properties getProperties(String resource)
- {
+ public static Properties getProperties(String resource) {
Properties properties = new Properties();
- try
- {
+ try {
InputStream inStream = getStream(resource);
properties.load(inStream);
inStream.close();
}
- catch (IOException e)
- {
+ catch (IOException e) {
throw new JbpmException("couldn't load properties file '" + resource + "'", e);
}
return properties;
Modified: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/util/XmlUtil.java
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/util/XmlUtil.java 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/java/org/jbpm/util/XmlUtil.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -59,20 +59,20 @@
}
/**
- * @param isJbpmConfiguration specifies if the resource should be loaded
- * with the "limited" bootstrap class loader for jbpm config.
+ * @param isJbpmConfiguration specifies if the resource should be loaded with the "limited"
+ * bootstrap class loader for jbpm config.
*/
- public static Document parseXmlResource(String resource, boolean isJbpmConfiguration) {
+ public static Document parseXmlResource(String resource, boolean isJbpmConfiguration) {
// decide which class loading mechanism to use for loading the jbpm
// configuration (see https://jira.jboss.org/jira/browse/JBPM-1148)
InputStream inputStream = null;
if (isJbpmConfiguration)
- inputStream = ClassLoaderUtil.getJbpmConfigurationStream(resource);
+ inputStream = ClassLoaderUtil.getStream(resource, false);
else
inputStream = ClassLoaderUtil.getStream(resource);
-
+
if (inputStream == null)
- throw new IllegalArgumentException("Cannot load resource: " + resource);
+ throw new IllegalArgumentException("Cannot load resource: " + resource);
InputSource inputSource = new InputSource(inputStream);
return parseXmlInputSource(inputSource);
}
@@ -80,8 +80,9 @@
public static Document parseXmlInputStream(InputStream inputStream) {
Document document = null;
try {
- document = getDocumentBuilder().parse(inputStream);
- } catch (Exception e) {
+ document = getDocumentBuilder().parse(inputStream);
+ }
+ catch (Exception e) {
throw new XmlException("couldn't parse xml", e);
}
return document;
@@ -90,14 +91,16 @@
public static Document parseXmlInputSource(InputSource inputSource) {
Document document = null;
try {
- document = getDocumentBuilder().parse(inputSource);
- } catch (Exception e) {
+ document = getDocumentBuilder().parse(inputSource);
+ }
+ catch (Exception e) {
throw new XmlException("couldn't parse xml", e);
}
return document;
}
- public static DocumentBuilder getDocumentBuilder() throws FactoryConfigurationError, ParserConfigurationException {
+ public static DocumentBuilder getDocumentBuilder() throws FactoryConfigurationError,
+ ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
return factory.newDocumentBuilder();
}
@@ -109,9 +112,9 @@
public static List elements(Element element, String tagName) {
NodeList nodeList = element.getElementsByTagName(tagName);
List elements = new ArrayList(nodeList.getLength());
- for (int i=0; i<nodeList.getLength(); i++) {
+ for (int i = 0; i < nodeList.getLength(); i++) {
Node child = nodeList.item(i);
- if(child.getParentNode()==element) {
+ if (child.getParentNode() == element) {
elements.add(child);
}
}
@@ -121,7 +124,7 @@
public static Element element(Element element, String name) {
Element childElement = null;
NodeList nodeList = element.getElementsByTagName(name);
- if (nodeList.getLength()>0) {
+ if (nodeList.getLength() > 0) {
childElement = (Element) nodeList.item(0);
}
return childElement;
@@ -134,43 +137,41 @@
public static List elements(Element element) {
List elements = new ArrayList();
NodeList nodeList = element.getChildNodes();
- for (int i=0; i<nodeList.getLength(); i++) {
+ for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
- if ( (node instanceof Element)
- && (element==node.getParentNode())
- ){
+ if ((node instanceof Element) && (element == node.getParentNode())) {
elements.add(node);
}
}
return elements;
}
-
public static Element element(Element element) {
Element onlyChild = null;
List elements = elements(element);
- if (! elements.isEmpty()) {
+ if (!elements.isEmpty()) {
onlyChild = (Element) elements.get(0);
}
return onlyChild;
}
public static String toString(Element element) {
- if (element==null) return "null";
+ if (element == null) return "null";
Source source = new DOMSource(element);
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
Result result = new StreamResult(printWriter);
-
+
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(source, result);
- } catch (Exception e) {
- throw new XmlException("couldn't write element '"+element.getTagName()+"' to string", e);
}
-
+ catch (Exception e) {
+ throw new XmlException("couldn't write element '" + element.getTagName() + "' to string", e);
+ }
+
printWriter.close();
return stringWriter.toString();
@@ -179,7 +180,7 @@
public static String getContentText(Element element) {
StringBuffer buffer = new StringBuffer();
NodeList nodeList = element.getChildNodes();
- for (int i=0; i<nodeList.getLength(); i++) {
+ for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node instanceof CharacterData) {
CharacterData characterData = (CharacterData) node;
Modified: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/resources/org/jbpm/default.jbpm.cfg.xml
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/resources/org/jbpm/default.jbpm.cfg.xml 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/main/resources/org/jbpm/default.jbpm.cfg.xml 2009-05-07 13:21:23 UTC (rev 4759)
@@ -33,11 +33,8 @@
<string name="resource.mail.templates" value="jbpm.mail.templates.xml" />
<!-- class loading -->
- <!--
- <string name="jbpm.classLoader" value="jbpm" />
- <string name="jbpm.customClassLoader.className" value="org.example.ClassLoader" />
- <bean name="jbpm.processClassLoader" class="org.jbpm.instantiation.DefaultProcessClassLoaderFactory" singleton="true" />
- -->
+ <string name="jbpm.class.loader" value="context" />
+ <bean name="process.class.loader.factory" class="org.jbpm.instantiation.SharedProcessClassLoaderFactory" singleton="true" />
<!-- make sure the block size matches the length in ByteArray.hbm.xml -->
<int name="jbpm.byte.block.size" value="1024" singleton="true" />
Modified: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/JbpmConfigurationTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/JbpmConfigurationTest.java 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/JbpmConfigurationTest.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -21,36 +21,22 @@
*/
package org.jbpm;
-import java.util.HashMap;
-
+import org.hibernate.SessionFactory;
import org.jbpm.configuration.ConfigurationException;
import org.jbpm.configuration.ObjectFactory;
import org.jbpm.configuration.ObjectFactoryImpl;
import org.jbpm.configuration.ObjectFactoryParser;
-import org.jbpm.persistence.db.DbPersistenceServiceFactory;
-import org.jbpm.svc.Services;
import org.jbpm.util.XmlException;
public class JbpmConfigurationTest extends AbstractJbpmTestCase {
- protected void setUp() throws Exception
- {
+ protected void setUp() throws Exception {
super.setUp();
- JbpmConfiguration.instances = new HashMap();
+ JbpmConfiguration.clearJbpmConfigurationStack();
JbpmConfiguration.defaultObjectFactory = null;
- JbpmConfiguration.jbpmConfigurationsStacks = new ThreadLocal();
- JbpmContext.currentContextsStack = new ThreadLocal();
+ JbpmConfiguration.instances.clear();
}
-
- protected void tearDown() throws Exception
- {
- JbpmConfiguration.instances = new HashMap();
- JbpmConfiguration.defaultObjectFactory = null;
- JbpmConfiguration.jbpmConfigurationsStacks = new ThreadLocal();
- JbpmContext.currentContextsStack = new ThreadLocal();
- super.tearDown();
- }
-
+
public void testSingleton() {
JbpmConfiguration.defaultObjectFactory = new ObjectFactoryImpl(null, null);
JbpmConfiguration instance = JbpmConfiguration.getInstance();
@@ -61,35 +47,32 @@
}
public void testDefaultContextCreation() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='"+JbpmContext.DEFAULT_JBPM_CONTEXT_NAME+"' />" +
- "</jbpm-configuration>"
- );
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='"
+ + JbpmContext.DEFAULT_JBPM_CONTEXT_NAME
+ + "' />"
+ + "</jbpm-configuration>");
assertNotNull(jbpmConfiguration);
assertNotNull(jbpmConfiguration.createJbpmContext());
}
public void testNonExistingContext() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration />"
- );
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration />");
assertNotNull(jbpmConfiguration);
try {
jbpmConfiguration.createJbpmContext("non-existing-context");
fail("expected exception");
- } catch (ConfigurationException e) {
+ }
+ catch (ConfigurationException e) {
//OK
}
}
public void testParseXmlStringConfiguration() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='a' />" +
- " <jbpm-context name='b' />" +
- "</jbpm-configuration>"
- );
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='a' />"
+ + " <jbpm-context name='b' />"
+ + "</jbpm-configuration>");
assertNotNull(jbpmConfiguration);
JbpmContext a = jbpmConfiguration.createJbpmContext("a");
assertNotNull(a);
@@ -99,11 +82,9 @@
}
public void testNonSingletonContextCreation() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='a' />" +
- "</jbpm-configuration>"
- );
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='a' />"
+ + "</jbpm-configuration>");
assertNotNull(jbpmConfiguration);
JbpmContext a = jbpmConfiguration.createJbpmContext("a");
assertNotNull(a);
@@ -116,7 +97,8 @@
try {
JbpmConfiguration.parseXmlString("< problematic // <</> <x>M/L");
fail("expected exception");
- } catch (XmlException e) {
+ }
+ catch (XmlException e) {
// OK
}
}
@@ -132,18 +114,16 @@
// 'jbpm.cfg.xml' or the static method JbpmConfiguration.Configs.setDefaultObjectFactory
// to specify the configuration information.
- JbpmConfiguration.Configs.setDefaultObjectFactory(
- ObjectFactoryParser.parseXmlString(
- "<jbpm-configuration>" +
- " <string name='myproperty'>myvalue</string>" +
- "</jbpm-configuration>"
- )
- );
+ JbpmConfiguration.Configs.setDefaultObjectFactory(ObjectFactoryParser.parseXmlString("<jbpm-configuration>"
+ + " <string name='myproperty'>myvalue</string>"
+ + "</jbpm-configuration>"));
assertEquals("myvalue", JbpmConfiguration.Configs.getString("myproperty"));
}
public static class CustomObjectFactory implements ObjectFactory {
+
private static final long serialVersionUID = 1L;
+
public Object createObject(String name) {
Object o = null;
if ("myproperty".equals(name)) {
@@ -151,48 +131,42 @@
}
return o;
}
+
public boolean hasObject(String name) {
return "myproperty".equals(name);
}
}
public void testDomainModelConfigsWithCustomObjectFactory() {
- JbpmConfiguration.Configs.setDefaultObjectFactory(
- new CustomObjectFactory()
- );
+ JbpmConfiguration.Configs.setDefaultObjectFactory(new CustomObjectFactory());
assertEquals("mycustomfactoriedvalue", JbpmConfiguration.Configs.getString("myproperty"));
}
public void testDomainModelConfigsWithJbpmContext() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='default.jbpm.context' />" +
- " <string name='myproperty'>myvalueinacontext</string>" +
- "</jbpm-configuration>"
- );
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='default.jbpm.context' />"
+ + " <string name='myproperty'>myvalueinacontext</string>"
+ + "</jbpm-configuration>");
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
assertEquals("myvalueinacontext", JbpmConfiguration.Configs.getString("myproperty"));
- } finally {
+ }
+ finally {
jbpmContext.close();
}
}
public void testDomainModelConfigsWithNestedJbpmContext() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='default.jbpm.context' />" +
- " <string name='myproperty'>myvalueinacontext</string>" +
- "</jbpm-configuration>"
- );
- JbpmConfiguration nestedJbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='default.jbpm.context' />" +
- " <string name='myproperty'>myvalueinanestedcontext</string>" +
- "</jbpm-configuration>"
- );
-
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='default.jbpm.context' />"
+ + " <string name='myproperty'>myvalueinacontext</string>"
+ + "</jbpm-configuration>");
+ JbpmConfiguration nestedJbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='default.jbpm.context' />"
+ + " <string name='myproperty'>myvalueinanestedcontext</string>"
+ + "</jbpm-configuration>");
+
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
try {
assertEquals("myvalueinacontext", JbpmConfiguration.Configs.getString("myproperty"));
@@ -200,12 +174,14 @@
JbpmContext nestedJbpmContext = nestedJbpmConfiguration.createJbpmContext();
try {
assertEquals("myvalueinanestedcontext", JbpmConfiguration.Configs.getString("myproperty"));
- } finally {
+ }
+ finally {
nestedJbpmContext.close();
}
-
+
assertEquals("myvalueinacontext", JbpmConfiguration.Configs.getString("myproperty"));
- } finally {
+ }
+ finally {
jbpmContext.close();
}
}
@@ -213,15 +189,15 @@
public void testJbpmConfigurationClose() {
JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
+ SessionFactory sessionFactory;
try {
- jbpmContext.getSession();
- } finally {
+ sessionFactory = jbpmContext.getSessionFactory();
+ }
+ finally {
jbpmContext.close();
}
-
jbpmConfiguration.close();
-
- DbPersistenceServiceFactory dbPersistenceServiceFactory = (DbPersistenceServiceFactory) jbpmConfiguration.getServiceFactory(Services.SERVICENAME_PERSISTENCE);
- assertTrue(dbPersistenceServiceFactory.getSessionFactory().isClosed());
+
+ assertTrue("expected " + sessionFactory + " to be closed", sessionFactory.isClosed());
}
}
Modified: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/JbpmContextTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/JbpmContextTest.java 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/JbpmContextTest.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -21,8 +21,6 @@
*/
package org.jbpm;
-import java.util.HashMap;
-
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.logging.LoggingService;
import org.jbpm.logging.log.MessageLog;
@@ -33,29 +31,17 @@
import org.jbpm.svc.save.SaveOperation;
public class JbpmContextTest extends AbstractJbpmTestCase {
-
- protected void setUp() throws Exception
- {
+
+ protected void setUp() throws Exception {
super.setUp();
- JbpmConfiguration.instances = new HashMap();
+ JbpmConfiguration.instances.clear();
JbpmConfiguration.defaultObjectFactory = null;
- JbpmContext.currentContextsStack = new ThreadLocal();
}
- protected void tearDown() throws Exception
- {
- JbpmConfiguration.instances = new HashMap();
- JbpmConfiguration.defaultObjectFactory = null;
- JbpmContext.currentContextsStack = new ThreadLocal();
- super.tearDown();
- }
-
public void testServices() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='a' />" +
- "</jbpm-configuration>"
- );
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='a' />"
+ + "</jbpm-configuration>");
assertNotNull(jbpmConfiguration);
Services s = jbpmConfiguration.createJbpmContext("a").getServices();
assertNotNull(s);
@@ -65,11 +51,9 @@
}
public void testJbpmContext() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='a' />" +
- "</jbpm-configuration>"
- );
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='a' />"
+ + "</jbpm-configuration>");
JbpmContext one = jbpmConfiguration.createJbpmContext("a");
assertNotNull(one);
JbpmContext two = jbpmConfiguration.createJbpmContext("a");
@@ -78,58 +62,57 @@
}
public static class TestServiceFactory implements ServiceFactory {
+
private static final long serialVersionUID = 1L;
+
public Service openService() {
return new TestService();
}
+
public void close() {
}
}
public static class TestService implements Service {
+
private static final long serialVersionUID = 1L;
+
public void close() {
}
}
public void testCustomService() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='a'>" +
- " <service name='test' factory='org.jbpm.JbpmContextTest$TestServiceFactory' />" +
- " </jbpm-context>" +
- "</jbpm-configuration>"
- );
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='a'>"
+ + " <service name='test' factory='org.jbpm.JbpmContextTest$TestServiceFactory' />"
+ + " </jbpm-context>"
+ + "</jbpm-configuration>");
Object service = jbpmConfiguration.createJbpmContext("a").getServices().getService("test");
assertNotNull(service);
assertEquals(TestService.class, service.getClass());
}
-
+
public void testServiceInFactoryElement() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='a'>" +
- " <service name='test'>" +
- " <factory>" +
- " <bean class='org.jbpm.JbpmContextTest$TestServiceFactory' />" +
- " </factory>" +
- " </service>" +
- " </jbpm-context>" +
- "</jbpm-configuration>"
- );
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='a'>"
+ + " <service name='test'>"
+ + " <factory>"
+ + " <bean class='org.jbpm.JbpmContextTest$TestServiceFactory' />"
+ + " </factory>"
+ + " </service>"
+ + " </jbpm-context>"
+ + "</jbpm-configuration>");
Object service = jbpmConfiguration.createJbpmContext("a").getServices().getService("test");
assertNotNull(service);
assertEquals(TestService.class, service.getClass());
}
-
+
public void testServiceCaching() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='a'>" +
- " <service name='test' factory='org.jbpm.JbpmContextTest$TestServiceFactory' />" +
- " </jbpm-context>" +
- "</jbpm-configuration>"
- );
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='a'>"
+ + " <service name='test' factory='org.jbpm.JbpmContextTest$TestServiceFactory' />"
+ + " </jbpm-context>"
+ + "</jbpm-configuration>");
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext("a");
TestService serviceOne = (TestService) jbpmContext.getServices().getService("test");
assertNotNull(serviceOne);
@@ -139,22 +122,28 @@
jbpmContext = jbpmConfiguration.createJbpmContext("a");
assertNotSame(serviceOne, jbpmContext.getServices().getService("test"));
}
-
+
public static class CustomLoggingServiceFactory implements ServiceFactory {
+
private static final long serialVersionUID = 1L;
+
public Service openService() {
return new CustomLoggingService();
}
+
public void close() {
}
}
public static class CustomLoggingService implements LoggingService {
+
private static final long serialVersionUID = 1L;
ProcessLog processLog;
int invocationCount = 0;
+
public void close() {
}
+
public void log(ProcessLog processLog) {
this.processLog = processLog;
this.invocationCount++;
@@ -162,17 +151,15 @@
}
public void testCustomLoggingService() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='a'>" +
- " <service name='logging' factory='org.jbpm.JbpmContextTest$CustomLoggingServiceFactory' />" +
- " </jbpm-context>" +
- "</jbpm-configuration>"
- );
-
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='a'>"
+ + " <service name='logging' factory='org.jbpm.JbpmContextTest$CustomLoggingServiceFactory' />"
+ + " </jbpm-context>"
+ + "</jbpm-configuration>");
+
CustomLoggingService customLoggingService = null;
MessageLog messageLog = null;
-
+
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext("a");
try {
customLoggingService = (CustomLoggingService) jbpmContext.getServices().getLoggingService();
@@ -181,70 +168,70 @@
processInstance.getLoggingInstance().addLog(messageLog);
jbpmContext.save(processInstance);
- } finally {
+ }
+ finally {
jbpmContext.close();
}
assertEquals(messageLog, customLoggingService.processLog);
assertEquals(1, customLoggingService.invocationCount);
}
-
-
+
public static class TestSaveOperation implements SaveOperation {
+
static int invocationCount = 0;
private static final long serialVersionUID = 1L;
+
public void save(ProcessInstance processInstance, JbpmContext jbpmContext) {
invocationCount++;
}
}
public void testSaveOperation() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='default.jbpm.context'>" +
- " <save-operations>" +
- " <save-operation class='org.jbpm.JbpmContextTest$TestSaveOperation' />" +
- " </save-operations>" +
- " </jbpm-context>" +
- "</jbpm-configuration>"
- );
-
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='default.jbpm.context'>"
+ + " <save-operations>"
+ + " <save-operation class='org.jbpm.JbpmContextTest$TestSaveOperation' />"
+ + " </save-operations>"
+ + " </jbpm-context>"
+ + "</jbpm-configuration>");
+
TestSaveOperation.invocationCount = 0;
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
-
+
try {
-
+
assertEquals(0, TestSaveOperation.invocationCount);
jbpmContext.save(new ProcessInstance());
assertEquals(1, TestSaveOperation.invocationCount);
-
- } finally {
+
+ }
+ finally {
jbpmContext.close();
}
}
public void testSaveOperationInBeanElement() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context name='default.jbpm.context'>" +
- " <save-operations>" +
- " <save-operation>" +
- " <bean class='org.jbpm.JbpmContextTest$TestSaveOperation' />" +
- " </save-operation>" +
- " </save-operations>" +
- " </jbpm-context>" +
- "</jbpm-configuration>"
- );
-
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <jbpm-context name='default.jbpm.context'>"
+ + " <save-operations>"
+ + " <save-operation>"
+ + " <bean class='org.jbpm.JbpmContextTest$TestSaveOperation' />"
+ + " </save-operation>"
+ + " </save-operations>"
+ + " </jbpm-context>"
+ + "</jbpm-configuration>");
+
TestSaveOperation.invocationCount = 0;
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
-
+
try {
-
+
assertEquals(0, TestSaveOperation.invocationCount);
jbpmContext.save(new ProcessInstance());
assertEquals(1, TestSaveOperation.invocationCount);
-
- } finally {
+
+ }
+ finally {
jbpmContext.close();
}
}
Copied: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/instantiation/ConfigurableClassLoadersTest.java (from rev 4689, jbpm3/trunk/modules/core/src/test/java/org/jbpm/instantiation/ConfigurableClassLoadersTest.java)
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/instantiation/ConfigurableClassLoadersTest.java (rev 0)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/instantiation/ConfigurableClassLoadersTest.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -0,0 +1,143 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jbpm.instantiation;
+
+import org.jbpm.AbstractJbpmTestCase;
+import org.jbpm.JbpmConfiguration;
+import org.jbpm.JbpmContext;
+import org.jbpm.JbpmException;
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.util.ClassLoaderUtil;
+
+/**
+ * {@link ProcessClassLoaderFactory} and class loader can be configured via
+ * {@link JbpmConfiguration} / jbpm.cfg.xml. Test if that works. Introduced with
+ * https://jira.jboss.org/jira/browse/JBPM-1148
+ *
+ * @author bernd.ruecker at camunda.com
+ */
+public class ConfigurableClassLoadersTest extends AbstractJbpmTestCase {
+
+ private ProcessDefinition processDefinition = new ProcessDefinition();
+
+ public void testDefaultProcessClassLoaderFactory() {
+ ClassLoader processClassLoader = JbpmConfiguration.getProcessClassLoader(processDefinition);
+ assertSame(ProcessClassLoader.class, processClassLoader.getClass());
+ }
+
+ public void testCustomProcessClassLoaderFactory() {
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <bean name='process.class.loader.factory' class='"
+ + CustomProcessClassLoaderFactory.class.getName()
+ + "' singleton='true' />"
+ + "</jbpm-configuration>");
+ JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
+
+ ClassLoader processClassLoader = JbpmConfiguration.getProcessClassLoader(processDefinition);
+ assertSame(CustomClassLoader.class, processClassLoader.getClass());
+
+ jbpmContext.close();
+ jbpmConfiguration.close();
+ }
+
+ public static class CustomProcessClassLoaderFactory implements ProcessClassLoaderFactory {
+
+ private static final long serialVersionUID = 1L;
+
+ public ClassLoader getProcessClassLoader(ProcessDefinition processDefinition) {
+ return new CustomClassLoader();
+ }
+ }
+
+ public void testDefaultClassLoader() {
+ ClassLoader classLoader = ClassLoaderUtil.getClassLoader();
+ assertSame(ClassLoaderUtil.class.getClassLoader(), classLoader);
+ }
+
+ public void testJbpmClassLoader() {
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <string name='jbpm.class.loader' value='jbpm' /> "
+ + "</jbpm-configuration>");
+ JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
+
+ ClassLoader classLoader = ClassLoaderUtil.getClassLoader();
+ assertSame(ClassLoaderUtil.class.getClassLoader(), classLoader);
+
+ jbpmContext.close();
+ jbpmConfiguration.close();
+ }
+
+ public void testContextClassLoader() {
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <string name='jbpm.class.loader' value='context' /> "
+ + "</jbpm-configuration>");
+ JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
+
+ ClassLoader classLoader = ClassLoaderUtil.getClassLoader();
+ assertSame(Thread.currentThread().getContextClassLoader(), classLoader);
+
+ jbpmContext.close();
+ jbpmConfiguration.close();
+ }
+
+ public void testNonExistentClassLoader() {
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <string name='jbpm.class.loader' value='absent' /> "
+ + "</jbpm-configuration>");
+ JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
+
+ try {
+ ClassLoaderUtil.getClassLoader();
+ fail("expected " + JbpmException.class.getName());
+ }
+ catch (JbpmException ex) {
+ // fine, exception was expected
+ }
+
+ jbpmContext.close();
+ jbpmConfiguration.close();
+ }
+
+ public void testCustomClassLoader() {
+ JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ + " <string name='jbpm.class.loader' value='custom.class.loader' />"
+ + " <bean name='custom.class.loader' class='"
+ + CustomClassLoader.class.getName()
+ + "' /> "
+ + "</jbpm-configuration>");
+ JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
+
+ ClassLoader classLoader = ClassLoaderUtil.getClassLoader();
+ assertSame(CustomClassLoader.class, classLoader.getClass());
+
+ jbpmContext.close();
+ jbpmConfiguration.close();
+ }
+
+ public static class CustomClassLoader extends ClassLoader {
+
+ public CustomClassLoader() {
+ super(Thread.currentThread().getContextClassLoader());
+ }
+ }
+
+}
Deleted: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/instantiation/ConfigurableClassloadersTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/instantiation/ConfigurableClassloadersTest.java 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/instantiation/ConfigurableClassloadersTest.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -1,136 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jbpm.instantiation;
-
-import org.jbpm.AbstractJbpmTestCase;
-import org.jbpm.JbpmConfiguration;
-import org.jbpm.JbpmConfigurationTestHelper;
-import org.jbpm.JbpmContext;
-import org.jbpm.graph.def.ProcessDefinition;
-
-/**
- * {@link ProcessClassLoaderFactory} and class loader can be configured
- * via {@link JbpmConfiguration} / jbpm.cfg.xml. Test if that works.
- *
- * Introduced with https://jira.jboss.org/jira/browse/JBPM-1148
- *
- * @author bernd.ruecker at camunda.com
- */
-public class ConfigurableClassloadersTest extends AbstractJbpmTestCase {
-
- public void testDefaultBehavior() {
- JbpmConfiguration.getInstance();
- ClassLoader processClassLoader = JbpmConfiguration.getProcessClassLoader(null);
-
- assertNotNull(processClassLoader);
- assertEquals(ProcessClassLoader.class, processClassLoader.getClass());
- }
-
- public static class MyClassLoader extends ClassLoader {
- public MyClassLoader() {
- }
- public MyClassLoader(ClassLoader parent) {
- super(parent);
- }
- }
-
- public static class TestProcessClassLoaderFactory implements ProcessClassLoaderFactory {
- public ClassLoader getProcessClassLoader(ProcessDefinition processDefinition) {
- return new MyClassLoader(Thread.currentThread().getContextClassLoader());
- }
- }
-
- public void testOwnProcessFactory() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context>" +
- " </jbpm-context>" +
- " <string name='jbpm.classLoader' value='jbpm' /> " +
- " <bean name='jbpm.processClassLoader' class='org.jbpm.instantiation.ConfigurableClassloadersTest$TestProcessClassLoaderFactory' singelton='true' />" +
- "</jbpm-configuration>"
- );
- JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
-
- ClassLoader processClassLoader = JbpmConfiguration.getProcessClassLoader(null);
- assertNotNull(processClassLoader);
- assertEquals(MyClassLoader.class, processClassLoader.getClass());
-
- jbpmContext.close();
- jbpmConfiguration.close();
- }
-
- public void testContextClassloaderFactory() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context>" +
- " </jbpm-context>" +
- " <string name='jbpm.classLoader' value='context' /> " +
- "</jbpm-configuration>"
- );
- JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
-
- assertNotNull(jbpmContext);
-
- jbpmContext.close();
- jbpmConfiguration.close();
- }
-
- public void testCustomClassloaderFactoryWithoutClassname() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context>" +
- " </jbpm-context>" +
- " <string name='jbpm.classLoader' value='custom' /> " +
- "</jbpm-configuration>"
- );
- JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
- try {
- ClassLoader processClassLoader = JbpmConfiguration.getProcessClassLoader(null);
- fail("we should get an exception because custom class loader class not specified");
- }
- catch (Exception ex) {}
-
- jbpmContext.close();
- jbpmConfiguration.close();
- }
-
- public void testCustomClassloaderFactory() {
- JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString(
- "<jbpm-configuration>" +
- " <jbpm-context>" +
- " </jbpm-context>" +
- " <string name='jbpm.classLoader' value='custom' /> " +
- " <string name='jbpm.customClassLoader.className' value='org.jbpm.instantiation.ConfigurableClassloadersTest$MyClassLoader' />" +
- "</jbpm-configuration>"
- );
- JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
-
- ClassLoader processClassLoader = JbpmConfiguration.getProcessClassLoader(null);
- assertNotNull(processClassLoader);
- // not configured, must be default
- assertEquals(ProcessClassLoader.class, processClassLoader.getClass());
-
- jbpmContext.close();
- jbpmConfiguration.close();
- }
-
-}
Modified: jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/jpdl/par/ProcessClassLoaderTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/jpdl/par/ProcessClassLoaderTest.java 2009-05-07 10:14:21 UTC (rev 4758)
+++ jbpm3/branches/jbpm-3.2.5.SP/modules/core/src/test/java/org/jbpm/jpdl/par/ProcessClassLoaderTest.java 2009-05-07 13:21:23 UTC (rev 4759)
@@ -7,16 +7,15 @@
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.graph.exe.ProcessInstance;
-import org.jbpm.instantiation.ConfigurableClassloadersTest;
+import org.jbpm.instantiation.ConfigurableClassLoadersTest;
import org.jbpm.instantiation.ProcessClassLoader;
import org.jbpm.util.ClassLoaderUtil;
/**
* Test case for ProcessClassLoader hierarchy and setting the ContextClassLoader correctly. Relates
- * to {@link ConfigurableClassloadersTest}.
+ * to {@link ConfigurableClassLoadersTest}.
*
- * @author Tom Baeyens
- * @author bernd.ruecker at camunda.com
+ * @author Tom Baeyens, bernd.ruecker at camunda.com
*/
public class ProcessClassLoaderTest extends AbstractJbpmTestCase {
@@ -26,14 +25,17 @@
super(parent);
}
+ protected synchronized Class loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ return super.loadClass(name, resolve);
+ }
+
+ public Class loadClass(String name) throws ClassNotFoundException {
+ return super.loadClass(name);
+ }
+
protected Class findClass(String name) throws ClassNotFoundException {
- if ("TestContextClassLoader-knows-where-to-find-ContextLoadedAction".equals(name)) {
- return getParent().loadClass(ContextLoadedAction.class.getName());
- }
- else if ("TestContextClassLoader-knows-where-to-find-ContextLoadedExceptionAction".equals(name)) {
- return getParent().loadClass(ContextLoadedExceptionAction.class.getName());
- }
- return null;
+ return super.findClass(name);
}
}
@@ -61,7 +63,7 @@
}
}
- /**
+ /*
* DOES NOT configure usage of the context classloader. So this tests the default (backwards
* compatible) behaviour. so the classloading hierarchy of DefaultLoadedAction should be
* ProcessClassloader -> jbpm-lib classloader
@@ -70,7 +72,9 @@
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition>"
+ " <start-state name='start'>"
+ " <transition to='state'>"
- + " <action class='org.jbpm.jpdl.par.ProcessClassLoaderTest$DefaultLoadedAction' />"
+ + " <action class='"
+ + DefaultLoadedAction.class.getName()
+ + "' />"
+ " </transition>"
+ " </start-state>"
+ " <state name='state'>"
@@ -102,12 +106,13 @@
}
}
- /**
+ /*
* configures usage of the context classloader so the classloading hierarchy of
* ContextLoadedAction should be ProcessClassloader -> TestContextClassLoader ->
* Thread.currentContextClassLoader
*/
public void testContextClassLoader() {
+
JbpmConfiguration jbpmConfiguration = JbpmConfiguration.parseXmlString("<jbpm-configuration>"
+ " <string name='jbpm.classLoader' value='context' />"
+ "</jbpm-configuration>");
@@ -121,7 +126,9 @@
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition>"
+ " <start-state name='start'>"
+ " <transition to='state'>"
- + " <action class='TestContextClassLoader-knows-where-to-find-ContextLoadedAction' />"
+ + " <action class='"
+ + ContextLoadedAction.class.getName()
+ + "' />"
+ " </transition>"
+ " </start-state>"
+ " <state name='state'>"
@@ -135,6 +142,7 @@
assertEquals(1, contextLoadedActionInvocations);
assertSame(testContextClassLoader, Thread.currentThread().getContextClassLoader());
+
}
finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
@@ -142,7 +150,7 @@
}
}
- /**
+ /*
* a third test should set the testcontextClassLoader in the test and then let the action throw an
* exception. Then it should be verified that the original classloader is still restored
* correctly. Easiest is to start from a copy of the testContextClassLoader
@@ -179,7 +187,9 @@
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString("<process-definition>"
+ " <start-state name='start'>"
+ " <transition to='state'>"
- + " <action class='TestContextClassLoader-knows-where-to-find-ContextLoadedExceptionAction' />"
+ + " <action class='"
+ + ContextLoadedExceptionAction.class.getName()
+ + "' />"
+ " </transition>"
+ " </start-state>"
+ " <state name='state'>"
@@ -190,11 +200,13 @@
// create the process instance
ProcessInstance processInstance = new ProcessInstance(processDefinition);
processInstance.signal();
+
}
catch (Exception ex) {
assertEquals(1, contextLoadedActionInvocations);
assertEquals("simulate exception", ex.getMessage());
assertSame(testContextClassLoader, Thread.currentThread().getContextClassLoader());
+
}
finally {
Thread.currentThread().setContextClassLoader(originalClassLoader);
More information about the jbpm-commits
mailing list