[jbpm-commits] JBoss JBPM SVN: r6572 - in jbpm3/branches/jbpm-3.2-soa/modules/core/src: main/java/org/jbpm/configuration and 8 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Aug 11 08:38:52 EDT 2010


Author: alex.guizar at jboss.com
Date: 2010-08-11 08:38:50 -0400 (Wed, 11 Aug 2010)
New Revision: 6572

Added:
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2605/
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2605/JBPM2605Test.java
Modified:
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmContext.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/AbstractObjectInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BeanInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BooleanInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/CharacterInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ConstructorInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/DoubleInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FieldInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FloatInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/IntegerInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmContextInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmTypeObjectInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ListInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/LongInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/MapInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/NullInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactory.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryParser.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/PropertyInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/RefInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/StringInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ValueInfo.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/converter/SerializableToByteArrayConverter.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/AbstractDbTestCase.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceServiceFactory.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/XmlUtil.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/JbpmConfigurationTest.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/configuration/JbpmContextTest.java
Log:
JBPM-2605 do not close SessionFactory if DbPersistenceServiceFactory did not open it

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmConfiguration.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -22,6 +22,7 @@
 package org.jbpm;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -35,7 +36,6 @@
 import org.jbpm.configuration.ObjectFactory;
 import org.jbpm.configuration.ObjectFactoryImpl;
 import org.jbpm.configuration.ObjectFactoryParser;
-import org.jbpm.configuration.ObjectInfo;
 import org.jbpm.configuration.ValueInfo;
 import org.jbpm.graph.def.ProcessDefinition;
 import org.jbpm.instantiation.DefaultProcessClassLoaderFactory;
@@ -238,18 +238,19 @@
 
   private static final long serialVersionUID = 1L;
   private static final String DEFAULT_RESOURCE = "jbpm.cfg.xml";
+  static final String OBJECT_NAME = "jbpm.configuration";
 
   private static ObjectFactory defaultObjectFactory;
   private static final Map instances = new HashMap();
-  private static final ThreadLocal jbpmConfigurationStacks = new StackThreadLocal();
+  private static final ThreadLocal threadLocalConfigurationStack = new ThreadLocalStack();
 
   private final ObjectFactory objectFactory;
   private final String resourceName;
+  private transient final ThreadLocal threadLocalContextStack = new ThreadLocalStack();
   private JobExecutor jobExecutor;
   private boolean isClosed;
-  private final ThreadLocal jbpmContextStacks = new StackThreadLocal();
 
-  static class StackThreadLocal extends ThreadLocal {
+  static class ThreadLocalStack extends ThreadLocal {
     protected Object initialValue() {
       return new ArrayList();
     }
@@ -260,6 +261,8 @@
   }
 
   private JbpmConfiguration(ObjectFactory objectFactory, String resourceName) {
+    if (objectFactory == null) throw new IllegalArgumentException("object factory is null");
+
     this.objectFactory = objectFactory;
     this.resourceName = resourceName;
   }
@@ -316,19 +319,30 @@
 
   protected static ObjectFactory parseObjectFactory(InputStream inputStream) {
     ObjectFactoryParser objectFactoryParser = new ObjectFactoryParser();
-    ObjectFactoryImpl objectFactoryImpl = new ObjectFactoryImpl();
-    objectFactoryParser.parseElementsFromResource("org/jbpm/default.jbpm.cfg.xml", objectFactoryImpl);
+    ObjectFactoryImpl objectFactory = new ObjectFactoryImpl();
+    objectFactoryParser.load("org/jbpm/default.jbpm.cfg.xml", objectFactory);
 
     if (inputStream != null) {
-      objectFactoryParser.parseElementsStream(inputStream, objectFactoryImpl);
+      objectFactoryParser.load(inputStream, objectFactory);
     }
-    return objectFactoryImpl;
+    return objectFactory;
   }
 
+  private static ObjectFactory loadDefaultObjectFactory() {
+    log.info("loading default configuration");
+    return ObjectFactoryParser.parseResource("org/jbpm/default.jbpm.cfg.xml");
+  }
+
   public static JbpmConfiguration parseXmlString(String xml) {
-    log.info("configuring from xml string");
-    InputStream inputStream = xml != null ? new ByteArrayInputStream(xml.getBytes()) : null;
-    ObjectFactory objectFactory = parseObjectFactory(inputStream);
+    ObjectFactory objectFactory;
+    if (xml != null) {
+      log.info("configuring from xml string");
+      InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
+      objectFactory = parseObjectFactory(inputStream);
+    }
+    else {
+      objectFactory = loadDefaultObjectFactory();
+    }
     return createJbpmConfiguration(objectFactory);
   }
 
@@ -339,11 +353,11 @@
   private static JbpmConfiguration createJbpmConfiguration(ObjectFactory objectFactory,
     String resourceName) {
     JbpmConfiguration jbpmConfiguration = new JbpmConfiguration(objectFactory, resourceName);
-    // make the bean jbpm.configuration always available
+    // make the configuration available to other objects
     if (objectFactory instanceof ObjectFactoryImpl) {
       ObjectFactoryImpl objectFactoryImpl = (ObjectFactoryImpl) objectFactory;
-      ObjectInfo jbpmConfigurationInfo = new ValueInfo("jbpmConfiguration", jbpmConfiguration);
-      objectFactoryImpl.addObjectInfo(jbpmConfigurationInfo);
+      objectFactoryImpl.addObjectInfo(new ValueInfo("jbpmConfiguration", jbpmConfiguration));
+      objectFactoryImpl.addObjectInfo(new ValueInfo(OBJECT_NAME, jbpmConfiguration));
     }
     // honor hide stale state exceptions setting
     if (getHideStaleObjectExceptions(objectFactory)) {
@@ -361,16 +375,36 @@
   }
 
   public static JbpmConfiguration parseInputStream(InputStream inputStream) {
-    log.info("configuring from input stream");
-    ObjectFactory objectFactory = parseObjectFactory(inputStream);
+    ObjectFactory objectFactory;
+    if (inputStream != null) {
+      log.info("configuring from " + inputStream);
+      objectFactory = parseObjectFactory(inputStream);
+    }
+    else {
+      objectFactory = loadDefaultObjectFactory();
+    }
     return createJbpmConfiguration(objectFactory);
   }
 
   public static JbpmConfiguration parseResource(String resource) {
-    log.info("configuring from resource: " + resource);
-    InputStream inputStream = resource != null ? ClassLoaderUtil.getStream(resource, false)
-      : null;
-    ObjectFactory objectFactory = parseObjectFactory(inputStream);
+    ObjectFactory objectFactory;
+    if (resource != null) {
+      log.info("configuring from resource: " + resource);
+      InputStream inputStream = ClassLoaderUtil.getStream(resource, false);
+      if (inputStream == null) {
+        throw new IllegalArgumentException("resource not found: " + resource);
+      }
+      objectFactory = parseObjectFactory(inputStream);
+      try {
+        inputStream.close();
+      }
+      catch (IOException e) {
+        log.warn("failed to close resource: " + resource, e);
+      }
+    }
+    else {
+      objectFactory = loadDefaultObjectFactory();
+    }
     return createJbpmConfiguration(objectFactory, resource);
   }
 
@@ -379,11 +413,14 @@
   }
 
   public JbpmContext createJbpmContext(String name) {
+    // note that this call ends up in createJbpmContext(name, services)
+    return (JbpmContext) objectFactory.createObject(name);
+  }
+
+  public JbpmContext createJbpmContext(String name, Services services) {
     ensureOpen();
 
-    JbpmContext jbpmContext = (JbpmContext) objectFactory.createObject(name);
-    jbpmContext.setName(name);
-    jbpmContext.setJbpmConfiguration(this);
+    JbpmContext jbpmContext = new JbpmContext(name, services, this);
     pushJbpmContext(jbpmContext);
     return jbpmContext;
   }
@@ -403,7 +440,8 @@
   }
 
   private DbPersistenceServiceFactory getPersistenceServiceFactory(String jbpmContextName) {
-    return (DbPersistenceServiceFactory) getServiceFactory(Services.SERVICENAME_PERSISTENCE, jbpmContextName);
+    return (DbPersistenceServiceFactory) getServiceFactory(Services.SERVICENAME_PERSISTENCE,
+      jbpmContextName);
   }
 
   public static ClassLoader getProcessClassLoader(ProcessDefinition processDefinition) {
@@ -418,8 +456,7 @@
   }
 
   /**
-   * gives the jbpm domain model access to configuration information via the current
-   * JbpmContext.
+   * access to configuration information through the current {@link JbpmContext}
    */
   public static class Configs {
 
@@ -504,36 +541,57 @@
   }
 
   public void close(String jbpmContextName) {
-    // prevent configuration from being closed more than once
-    if (isClosed) return;
+    synchronized (this) {
+      // prevent configuration from being closed more than once
+      if (isClosed) return;
 
-    // stop job executor
-    if (jobExecutor != null) {
-      jobExecutor.stop();
-      jobExecutor = null;
-    }
+      // stop job executor
+      if (jobExecutor != null) {
+        try {
+          jobExecutor.stopAndJoin();
+        }
+        catch (InterruptedException e) {
+          // reassert interruption and continue
+          Thread.currentThread().interrupt();
+        }
+        jobExecutor = null;
+      }
 
-    // close service factories
-    JbpmContext jbpmContext = createJbpmContext(jbpmContextName);
-    try {
-      Map serviceFactories = jbpmContext.getServices().getServiceFactories();
-      if (serviceFactories != null) {
-        for (Iterator i = serviceFactories.values().iterator(); i.hasNext();) {
-          ServiceFactory serviceFactory = (ServiceFactory) i.next();
-          serviceFactory.close();
+      // close remaining contexts
+      List contextStack = getJbpmContextStack();
+      if (!contextStack.isEmpty()) {
+        log.warn("closing " + contextStack.size() + " open contexts;"
+          + " make sure to close JbpmContext after use");
+
+        // copy to array because JbpmContext.close() pops the context off the stack
+        JbpmContext[] jbpmContexts = (JbpmContext[]) contextStack.toArray(new JbpmContext[contextStack.size()]);
+        for (int i = 0; i < jbpmContexts.length; i++) {
+          jbpmContexts[i].close();
         }
       }
-    }
-    finally {
-      jbpmContext.close();
-    }
 
-    // closing service factories requires open configuration
-    isClosed = true;
+      // close service factories
+      JbpmContext jbpmContext = createJbpmContext(jbpmContextName);
+      try {
+        Map serviceFactories = jbpmContext.getServices().getServiceFactories();
+        if (serviceFactories != null) {
+          for (Iterator i = serviceFactories.values().iterator(); i.hasNext();) {
+            ServiceFactory serviceFactory = (ServiceFactory) i.next();
+            serviceFactory.close();
+          }
+        }
+      }
+      finally {
+        jbpmContext.close();
+      }
 
-    // release context stack
-    jbpmContextStacks.set(null);
+      // release thread-local context stack
+      threadLocalContextStack.set(null);
 
+      // closing service factories requires open configuration
+      isClosed = true;
+    }
+
     // remove from configuration cache
     if (resourceName != null) {
       synchronized (instances) {
@@ -548,7 +606,7 @@
   }
 
   private static List getJbpmConfigurationStack() {
-    return (List) jbpmConfigurationStacks.get();
+    return (List) threadLocalConfigurationStack.get();
   }
 
   static void clearInstances() {
@@ -563,7 +621,7 @@
   }
 
   private List getJbpmContextStack() {
-    return (List) jbpmContextStacks.get();
+    return (List) threadLocalContextStack.get();
   }
 
   void pushJbpmContext(JbpmContext jbpmContext) {
@@ -607,11 +665,11 @@
 
     if (threadSafetyFlag) {
       log.warn(jbpmContext + " was not closed in the thread that created it;"
-       + " JbpmContext is not safe for access from multiple threads!");
+        + " JbpmContext is not safe for access from multiple threads!");
     }
     else if (creationOrderFlag) {
       log.warn(jbpmContext + " was not closed in a block-structured manner;"
-        + " check your try-finally clauses around JbpmContext blocks");
+        + " check try-finally clauses around JbpmContext blocks");
     }
   }
 

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmContext.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmContext.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/JbpmContext.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -41,7 +41,6 @@
 import org.jbpm.graph.exe.Token;
 import org.jbpm.persistence.PersistenceService;
 import org.jbpm.persistence.db.DbPersistenceService;
-import org.jbpm.security.AuthenticationService;
 import org.jbpm.svc.ServiceFactory;
 import org.jbpm.svc.Services;
 import org.jbpm.taskmgmt.exe.TaskInstance;
@@ -50,8 +49,8 @@
 /**
  * is used to surround persistent operations to processes.
  * <p>
- * Obtain a JbpmContext via {@link org.jbpm.JbpmConfiguration#createJbpmContext()} and
- * manipulate it inside a try-finally block as follows.
+ * Obtain a JbpmContext via {@link JbpmConfiguration#createJbpmContext()} and manipulate it
+ * inside a try-finally block as follows.
  * </p>
  * 
  * <pre>
@@ -101,37 +100,83 @@
 
   public static final String DEFAULT_JBPM_CONTEXT_NAME = "default.jbpm.context";
 
-  private String name;
-  private ObjectFactory objectFactory;
-  private Services services;
-  private JbpmConfiguration jbpmConfiguration;
+  private final String name;
+  private final Services services;
+  private final JbpmConfiguration jbpmConfiguration;
   private List autoSaveProcessInstances;
+  private boolean isClosed;
 
   /**
-   * normally, JbpmContext object are created via a {@link JbpmConfiguration}.
+   * @deprecated call {@link JbpmConfiguration#createJbpmContext(String, Services)} instead
    */
   public JbpmContext(Services services, ObjectFactory objectFactory) {
+    if (services == null) throw new IllegalArgumentException("null services");
+
+    name = DEFAULT_JBPM_CONTEXT_NAME;
     this.services = services;
-    this.objectFactory = objectFactory;
+    jbpmConfiguration = new JbpmConfiguration(objectFactory);
   }
 
+  JbpmContext(String name, Services services, JbpmConfiguration jbpmConfiguration) {
+    if (services == null) throw new IllegalArgumentException("null services");
+    if (jbpmConfiguration == null) throw new IllegalArgumentException("configuration is null");
+
+    this.name = name;
+    this.services = services;
+    this.jbpmConfiguration = jbpmConfiguration;
+  }
+
+  private void ensureOpen() {
+    if (isClosed) throw new JbpmException(this + " is closed");
+  }
+
+  public boolean isClosed() {
+    return isClosed;
+  }
+
   /**
-   * make sure you close your JbpmContext in a finally block.
+   * make sure to close this context in a finally block.
    */
   public void close() {
-    try {
-      if (services != null) {
-        try {
-          autoSave();
+    if (isClosed) return;
+
+    RuntimeException saveException = autoSave();
+    if (saveException != null) {
+      closeServices();
+      throw saveException;
+    }
+
+    RuntimeException serviceException = closeServices();
+    if (serviceException != null) throw serviceException;
+  }
+
+  private RuntimeException autoSave() {
+    if (autoSaveProcessInstances != null) {
+      try {
+        for (Iterator iter = autoSaveProcessInstances.iterator(); iter.hasNext();) {
+          ProcessInstance processInstance = (ProcessInstance) iter.next();
+          save(processInstance);
         }
-        finally {
-          services.close();
-        }
       }
+      catch (RuntimeException e) {
+        return e;
+      }
     }
+    return null;
+  }
+
+  private RuntimeException closeServices() {
+    try {
+      services.close();
+    }
+    catch (RuntimeException e) {
+      return e;
+    }
     finally {
-      if (jbpmConfiguration != null) jbpmConfiguration.popJbpmContext(this);
+      isClosed = true;
+      jbpmConfiguration.popJbpmContext(this);
     }
+    return null;
   }
 
   /**
@@ -144,12 +189,8 @@
    * </p>
    */
   public static JbpmContext getCurrentJbpmContext() {
-    JbpmContext currentJbpmContext = null;
-    JbpmConfiguration currentJbpmConfiguration = JbpmConfiguration.getCurrentJbpmConfiguration();
-    if (currentJbpmConfiguration != null) {
-      currentJbpmContext = currentJbpmConfiguration.getCurrentJbpmContext();
-    }
-    return currentJbpmContext;
+    JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getCurrentJbpmConfiguration();
+    return jbpmConfiguration != null ? jbpmConfiguration.getCurrentJbpmContext() : null;
   }
 
   // convenience methods //////////////////////////////////////////////////////
@@ -392,7 +433,8 @@
    */
   public ProcessInstance getProcessInstanceForUpdate(ProcessDefinition processDefinition,
     String key) {
-    ProcessInstance processInstance = getGraphSession().getProcessInstance(processDefinition, key);
+    ProcessInstance processInstance = getGraphSession().getProcessInstance(processDefinition,
+      key);
     if (processInstance != null) {
       addAutoSaveProcessInstance(processInstance);
     }
@@ -406,7 +448,8 @@
    */
   public ProcessInstance loadProcessInstanceForUpdate(ProcessDefinition processDefinition,
     String key) {
-    ProcessInstance processInstance = getGraphSession().loadProcessInstance(processDefinition, key);
+    ProcessInstance processInstance = getGraphSession().loadProcessInstance(processDefinition,
+      key);
     if (processInstance != null) {
       addAutoSaveProcessInstance(processInstance);
     }
@@ -441,9 +484,8 @@
    * saves the process instance.
    */
   public void save(ProcessInstance processInstance) {
-    if (services != null) {
-      services.save(processInstance, this);
-    }
+    ensureOpen();
+    services.save(processInstance, this);
   }
 
   /**
@@ -465,7 +507,9 @@
    * operation will then perform a rollback.
    */
   public void setRollbackOnly() {
-    TxService txService = (services != null ? services.getTxService() : null);
+    ensureOpen();
+
+    TxService txService = services.getTxService();
     if (txService != null) {
       txService.setRollbackOnly();
     }
@@ -488,26 +532,17 @@
   }
 
   /**
-   * gives access to the object factory containing the configuration to create the service
-   * factories.
+   * gives access to the object factory that builds the service factories.
    */
   public ObjectFactory getObjectFactory() {
-    return objectFactory;
+    return jbpmConfiguration.getObjectFactory();
   }
 
-  /** give access to the configuration that created this jbpm context */
+  /** gives access to the configuration that created this context. */
   public JbpmConfiguration getJbpmConfiguration() {
     return jbpmConfiguration;
   }
 
-  void setJbpmConfiguration(JbpmConfiguration jbpmConfiguration) {
-    this.jbpmConfiguration = jbpmConfiguration;
-  }
-
-  void setName(String name) {
-    this.name = name;
-  }
-
   // persistence methods //////////////////////////////////////////////////////
 
   /**
@@ -518,8 +553,11 @@
    */
   public SessionFactory getSessionFactory() {
     PersistenceService persistenceService = getPersistenceService();
-    return persistenceService instanceof DbPersistenceService ? ((DbPersistenceService) persistenceService).getSessionFactory()
-      : null;
+    if (persistenceService instanceof DbPersistenceService) {
+      DbPersistenceService dbPersistenceService = (DbPersistenceService) persistenceService;
+      return dbPersistenceService.getSessionFactory();
+    }
+    return null;
   }
 
   /**
@@ -543,8 +581,11 @@
    */
   public Session getSession() {
     PersistenceService persistenceService = getPersistenceService();
-    return persistenceService instanceof DbPersistenceService ? ((DbPersistenceService) persistenceService).getSession()
-      : null;
+    if (persistenceService instanceof DbPersistenceService) {
+      DbPersistenceService dbPersistenceService = (DbPersistenceService) persistenceService;
+      return dbPersistenceService.getSession();
+    }
+    return null;
   }
 
   /**
@@ -568,8 +609,11 @@
    */
   public Connection getConnection() {
     PersistenceService persistenceService = getPersistenceService();
-    return persistenceService instanceof DbPersistenceService ? ((DbPersistenceService) persistenceService).getConnection()
-      : null;
+    if (persistenceService instanceof DbPersistenceService) {
+      DbPersistenceService dbPersistenceService = (DbPersistenceService) persistenceService;
+      return dbPersistenceService.getConnection();
+    }
+    return null;
   }
 
   /**
@@ -599,7 +643,7 @@
    */
   public LoggingSession getLoggingSession() {
     PersistenceService persistenceService = getPersistenceService();
-    return (persistenceService != null ? persistenceService.getLoggingSession() : null);
+    return persistenceService != null ? persistenceService.getLoggingSession() : null;
   }
 
   /**
@@ -607,7 +651,7 @@
    */
   public JobSession getJobSession() {
     PersistenceService persistenceService = getPersistenceService();
-    return (persistenceService != null ? persistenceService.getJobSession() : null);
+    return persistenceService != null ? persistenceService.getJobSession() : null;
   }
 
   /**
@@ -615,7 +659,7 @@
    */
   public GraphSession getGraphSession() {
     PersistenceService persistenceService = getPersistenceService();
-    return (persistenceService != null ? persistenceService.getGraphSession() : null);
+    return persistenceService != null ? persistenceService.getGraphSession() : null;
   }
 
   /**
@@ -623,7 +667,7 @@
    */
   public TaskMgmtSession getTaskMgmtSession() {
     PersistenceService persistenceService = getPersistenceService();
-    return (persistenceService != null ? persistenceService.getTaskMgmtSession() : null);
+    return persistenceService != null ? persistenceService.getTaskMgmtSession() : null;
   }
 
   // authentication methods ///////////////////////////////////////////////////
@@ -639,11 +683,12 @@
    * sets the currently authenticated actorId.
    */
   public void setActorId(String actorId) {
-    AuthenticationService authenticationService = services.getAuthenticationService();
-    authenticationService.setActorId(actorId);
+    ensureOpen();
+    services.getAuthenticationService().setActorId(actorId);
   }
 
   public void addAutoSaveProcessInstance(ProcessInstance processInstance) {
+    ensureOpen();
     if (autoSaveProcessInstances == null) autoSaveProcessInstances = new ArrayList();
     autoSaveProcessInstances.add(processInstance);
   }
@@ -658,18 +703,9 @@
 
   // private methods //////////////////////////////////////////////////////////
 
-  private void autoSave() {
-    if (autoSaveProcessInstances != null) {
-      for (Iterator iter = autoSaveProcessInstances.iterator(); iter.hasNext();) {
-        ProcessInstance processInstance = (ProcessInstance) iter.next();
-        save(processInstance);
-      }
-      autoSaveProcessInstances.clear();
-    }
-  }
-
   private PersistenceService getPersistenceService() {
-    return services != null ? services.getPersistenceService() : null;
+    ensureOpen();
+    return services.getPersistenceService();
   }
 
   public String toString() {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/AbstractObjectInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/AbstractObjectInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/AbstractObjectInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -28,8 +28,8 @@
 
   private static final long serialVersionUID = 1L;
   
-  String name = null;
-  boolean isSingleton = false;
+  String name;
+  boolean isSingleton;
 
   public AbstractObjectInfo() {
   }
@@ -37,7 +37,6 @@
   public AbstractObjectInfo(Element element, ObjectFactoryParser objectFactoryParser) {
     if (element.hasAttribute("name")) {
       name = element.getAttribute("name");
-      objectFactoryParser.addNamedObjectInfo(name, this);
     }
     if ("true".equalsIgnoreCase(element.getAttribute("singleton"))) {
       isSingleton = true;

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BeanInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BeanInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BeanInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -75,7 +75,7 @@
     propertyInfos = (PropertyInfo[]) propertyInfoList.toArray(new PropertyInfo[propertyInfoList.size()]);
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     Object object;
 
     if (constructorInfo == null) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BooleanInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BooleanInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/BooleanInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -41,7 +41,7 @@
       b = Boolean.valueOf(s);
     }
   }
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     return b;
   }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/CharacterInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/CharacterInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/CharacterInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -40,7 +40,7 @@
     value = new Character(valueString.charAt(0));
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     return value;
   }
 

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ConstructorInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ConstructorInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ConstructorInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -94,7 +94,7 @@
     }
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     Object[] args = getArgs(objectFactory);
     Class[] parameterTypes = getParameterTypes(objectFactory);
 
@@ -154,7 +154,7 @@
     }
   }
 
-  protected Class[] getParameterTypes(ObjectFactoryImpl objectFactory) {
+  protected Class[] getParameterTypes(ObjectFactory objectFactory) {
     int nbrOfParameters = parameterClassNames != null ? parameterClassNames.length : 0;
     Class[] parameterTypes = new Class[nbrOfParameters];
     for (int i = 0; i < nbrOfParameters; i++) {
@@ -169,7 +169,7 @@
     return parameterTypes;
   }
 
-  protected Object[] getArgs(ObjectFactoryImpl objectFactory) {
+  protected Object[] getArgs(ObjectFactory objectFactory) {
     int nbrOfParameters = (parameterClassNames != null ? parameterClassNames.length : 0);
     Object[] args = new Object[nbrOfParameters];
     for (int i = 0; i < nbrOfParameters; i++) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/DoubleInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/DoubleInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/DoubleInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -34,7 +34,7 @@
     value = new Double(getValueString(doubleElement));
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     return value;
   }
 

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FieldInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FieldInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FieldInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -35,7 +35,7 @@
     super(fieldElement, configParser);
   }
 
-  public void injectProperty(Object object, ObjectFactoryImpl objectFactory) {
+  public void injectProperty(Object object, ObjectFactory objectFactory) {
     Field field = findField(object.getClass());
     field.setAccessible(true);
     Object value = objectFactory.getObject(getPropertyValueInfo());

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FloatInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FloatInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/FloatInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -34,7 +34,7 @@
     value = new Float(getValueString(floatElement));
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     return value;
   }
 

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/IntegerInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/IntegerInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/IntegerInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -34,7 +34,7 @@
     value = new Integer(getValueString(integerElement));
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     return value;
   }
 

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmContextInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmContextInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmContextInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -22,11 +22,11 @@
 package org.jbpm.configuration;
 
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.jbpm.JbpmConfiguration;
 import org.jbpm.JbpmContext;
 import org.jbpm.svc.Services;
 import org.jbpm.util.XmlUtil;
@@ -36,104 +36,114 @@
 
   private static final long serialVersionUID = 1L;
 
-  private Map serviceFactoryObjectInfos;
+  private ObjectInfo[] serviceFactoryInfos;
   private Map serviceFactories;
-  private List serviceNames;
 
-  private ObjectInfo[] saveOperationObjectInfos;
+  private ObjectInfo[] saveOperationInfos;
   private List saveOperations;
 
   public JbpmContextInfo(Element jbpmContextElement, ObjectFactoryParser objectFactoryParser) {
     super(verifyDefaultName(jbpmContextElement), objectFactoryParser);
     if (jbpmContextElement.hasAttribute("singleton")) {
-      throw new ConfigurationException("attribute 'singleton' is not allowed in element 'jbpm-context'");
+      throw new ConfigurationException("attribute singleton is not allowed in element jbpm-context");
     }
 
     // parse the services
-    serviceFactoryObjectInfos = new HashMap();
-    serviceNames = new ArrayList();
-    for (Iterator iter = XmlUtil.elementIterator(jbpmContextElement, "service"); iter.hasNext();) {
-      Element serviceElement = (Element) iter.next();
-      if (!serviceElement.hasAttribute("name")) {
+    List serviceElements = XmlUtil.elements(jbpmContextElement, "service");
+    serviceFactoryInfos = new ObjectInfo[serviceElements.size()];
+
+    for (int i = 0; i < serviceFactoryInfos.length; i++) {
+      Element serviceElement = (Element) serviceElements.get(i);
+
+      String serviceName = serviceElement.getAttribute("name");
+      if (serviceName.length() == 0) {
         throw new ConfigurationException("service has no name");
       }
-      String serviceName = serviceElement.getAttribute("name");
-      serviceNames.add(serviceName);
-      ObjectInfo serviceFactoryObjectInfo;
+
+      ObjectInfo serviceFactoryInfo;
       Element factoryElement = XmlUtil.element(serviceElement, "factory");
       if (factoryElement != null) {
         Element factoryBeanElement = XmlUtil.element(factoryElement);
         if (factoryBeanElement == null) {
-          throw new ConfigurationException("element 'factory' requires either a bean or ref element");
+          throw new ConfigurationException("element factory requires either a bean or ref subelement");
         }
-        serviceFactoryObjectInfo = objectFactoryParser.parse(factoryBeanElement);
+        factoryBeanElement.setAttribute("name", serviceName);
+        serviceFactoryInfo = objectFactoryParser.parse(factoryBeanElement);
       }
       else if (serviceElement.hasAttribute("factory")) {
-        String factoryClassName = serviceElement.getAttribute("factory");
         BeanInfo beanInfo = new BeanInfo();
-        beanInfo.setClassName(factoryClassName);
-        serviceFactoryObjectInfo = beanInfo;
+        beanInfo.setName(serviceName);
+        beanInfo.setClassName(serviceElement.getAttribute("factory"));
+        serviceFactoryInfo = beanInfo;
       }
       else {
-        throw new ConfigurationException("element 'service' requires either a factory attribute or a factory element");
+        throw new ConfigurationException("element service requires either a factory attribute or a factory subelement");
       }
 
-      serviceFactoryObjectInfos.put(serviceName, serviceFactoryObjectInfo);
+      serviceFactoryInfos[i] = serviceFactoryInfo;
     }
 
     // parse the save operations
     Element saveOperationsElement = XmlUtil.element(jbpmContextElement, "save-operations");
     if (saveOperationsElement != null) {
       List saveOperationElements = XmlUtil.elements(saveOperationsElement, "save-operation");
-      saveOperationObjectInfos = new ObjectInfo[saveOperationElements.size()];
-      for (int i = 0; i < saveOperationElements.size(); i++) {
+      saveOperationInfos = new ObjectInfo[saveOperationElements.size()];
+
+      for (int i = 0; i < saveOperationInfos.length; i++) {
         Element saveOperationElement = (Element) saveOperationElements.get(i);
 
         if (saveOperationElement.hasAttribute("class")) {
           String saveOperationClassName = saveOperationElement.getAttribute("class");
           BeanInfo beanInfo = new BeanInfo();
           beanInfo.setClassName(saveOperationClassName);
-          saveOperationObjectInfos[i] = beanInfo;
+          saveOperationInfos[i] = beanInfo;
         }
         else {
           Element saveOperationBeanElement = XmlUtil.element(saveOperationElement);
           if (saveOperationBeanElement == null) {
-            throw new ConfigurationException("element 'save-operation' requires either a class attribute or an element of type 'bean' or 'ref'");
+            throw new ConfigurationException("element save-operation requires either a class attribute or a bean or ref subelement");
           }
-          saveOperationObjectInfos[i] = objectFactoryParser.parse(saveOperationBeanElement);
+          saveOperationInfos[i] = objectFactoryParser.parse(saveOperationBeanElement);
         }
       }
     }
   }
 
-  static Element verifyDefaultName(Element jbpmContextElement) {
+  private static Element verifyDefaultName(Element jbpmContextElement) {
     if (!jbpmContextElement.hasAttribute("name")) {
       jbpmContextElement.setAttribute("name", JbpmContext.DEFAULT_JBPM_CONTEXT_NAME);
     }
     return jbpmContextElement;
   }
 
-  public synchronized Object createObject(ObjectFactoryImpl objectFactory) {
-    if (serviceFactories == null) {
-      serviceFactories = new HashMap();
-      for (Iterator iter = serviceFactoryObjectInfos.entrySet().iterator(); iter.hasNext();) {
-        Map.Entry entry = (Map.Entry) iter.next();
-        String serviceName = (String) entry.getKey();
-        ObjectInfo serviceFactoryObjectInfo = (ObjectInfo) entry.getValue();
-        serviceFactories.put(serviceName, serviceFactoryObjectInfo.createObject(objectFactory));
+  public Object createObject(ObjectFactory objectFactory) {
+    synchronized (this) {
+      if (serviceFactories == null) {
+        serviceFactories = new LinkedHashMap(serviceFactoryInfos.length);
+        for (int i = 0; i < serviceFactoryInfos.length; i++) {
+          ObjectInfo serviceFactoryInfo = serviceFactoryInfos[i];
+          Object serviceFactory = serviceFactoryInfo.createObject(objectFactory);
+          serviceFactories.put(serviceFactoryInfo.getName(), serviceFactory);
+        }
+
+        if (saveOperationInfos != null) {
+          saveOperations = new ArrayList(saveOperationInfos.length);
+          for (int i = 0; i < saveOperationInfos.length; i++) {
+            Object saveOperation = saveOperationInfos[i].createObject(objectFactory);
+            saveOperations.add(saveOperation);
+          }
+        }
       }
     }
 
-    if (saveOperations == null && saveOperationObjectInfos != null) {
-      saveOperations = new ArrayList();
-      for (int i = 0; i < saveOperationObjectInfos.length; i++) {
-        Object saveOperation = saveOperationObjectInfos[i].createObject(objectFactory);
-        saveOperations.add(saveOperation);
-      }
+    Services services = new Services(serviceFactories, saveOperations);
+    if (objectFactory.hasObject("jbpm.configuration")) {
+      JbpmConfiguration configuration = (JbpmConfiguration) objectFactory.createObject("jbpm.configuration");
+      return configuration.createJbpmContext(name, services);
     }
-
-    Services services = new Services(serviceFactories, serviceNames, saveOperations);
-    return new JbpmContext(services, objectFactory);
+    else {
+      return new JbpmContext(services, objectFactory);
+    }
   }
 
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmTypeObjectInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmTypeObjectInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/JbpmTypeObjectInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -95,7 +95,7 @@
           return true;
         }
 
-        public Object createObject(ObjectFactoryImpl objectFactory) {
+        public Object createObject(ObjectFactory objectFactory) {
           return new JbpmTypeMatcher() {
             private static final long serialVersionUID = 1L;
 
@@ -110,7 +110,7 @@
     }
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     JbpmTypeMatcher jbpmTypeMatcher = (JbpmTypeMatcher) objectFactory.createObject(typeMatcherObjectInfo);
     return new JbpmType(jbpmTypeMatcher, converter, variableInstanceClass);
   }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ListInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ListInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ListInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -44,7 +44,7 @@
     }
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     List list = new ArrayList();
     if (elementInfos != null) {
       for (int i = 0; i < elementInfos.length; i++) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/LongInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/LongInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/LongInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -34,7 +34,7 @@
     value = new Long(getValueString(longElement));
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     return value;
   }
 

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/MapInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/MapInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/MapInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -50,7 +50,7 @@
     }
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     Map map = new HashMap();
     if (keyInfos != null) {
       for (int i = 0; i < keyInfos.length; i++) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/NullInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/NullInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/NullInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -31,7 +31,7 @@
     super(nullElement, configParser);
   }
   
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     return null;
   }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactory.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactory.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactory.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -24,7 +24,14 @@
 import java.io.Serializable;
 
 public interface ObjectFactory extends Serializable {
-  
+
+  boolean hasObject(String name);
+
   Object createObject(String name);
-  boolean hasObject(String name);
+  Object createObject(ObjectInfo objectInfo);
+
+  Object getObject(String name);
+  Object getObject(ObjectInfo objectInfo);
+
+  Class classForName(String className) throws ClassNotFoundException;
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryImpl.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -113,7 +113,7 @@
    * create an object of the given name. If the object was created before, that object is
    * returned from the registry.
    */
-  Object getObject(String name) {
+  public Object getObject(String name) {
     Object object = null;
     ObjectInfo objectInfo = (ObjectInfo) namedObjectInfos.get(name);
     if (objectInfo != null) {
@@ -130,7 +130,7 @@
    * create an object for the given {@link ObjectInfo}. If the object was created before, that
    * object is returned from the registry.
    */
-  Object getObject(ObjectInfo objectInfo) {
+  public Object getObject(ObjectInfo objectInfo) {
     Object object = null;
 
     Object registryKey = getRegistryKey(objectInfo);
@@ -158,7 +158,7 @@
     return object;
   }
 
-  Class classForName(String className) throws ClassNotFoundException {
+  public Class classForName(String className) throws ClassNotFoundException {
     if (classLoader == null) {
       classLoader = ClassLoaderUtil.getClassLoader();
     }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryParser.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryParser.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectFactoryParser.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -25,110 +25,120 @@
 import java.io.Serializable;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 
 import org.jbpm.JbpmException;
 import org.jbpm.util.XmlUtil;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 public class ObjectFactoryParser implements Serializable {
 
   private static final long serialVersionUID = 1L;
 
-  private static Map defaultMappings;
+  private static final Class[] constructorParameterTypes = {
+    Element.class, ObjectFactoryParser.class
+  };
 
+  private static final Map defaultMappings = getDefaultMappings();
+
   public static Map getDefaultMappings() {
-    if (defaultMappings == null) {
-      defaultMappings = new HashMap();
-      addMapping(defaultMappings, "bean", BeanInfo.class);
-      addMapping(defaultMappings, "ref", RefInfo.class);
-      addMapping(defaultMappings, "list", ListInfo.class);
-      addMapping(defaultMappings, "map", MapInfo.class);
-      addMapping(defaultMappings, "string", StringInfo.class);
-      addMapping(defaultMappings, "int", IntegerInfo.class);
-      addMapping(defaultMappings, "integer", IntegerInfo.class);
-      addMapping(defaultMappings, "long", LongInfo.class);
-      addMapping(defaultMappings, "float", FloatInfo.class);
-      addMapping(defaultMappings, "double", DoubleInfo.class);
-      addMapping(defaultMappings, "char", CharacterInfo.class);
-      addMapping(defaultMappings, "character", CharacterInfo.class);
-      addMapping(defaultMappings, "boolean", BooleanInfo.class);
-      addMapping(defaultMappings, "true", BooleanInfo.class);
-      addMapping(defaultMappings, "false", BooleanInfo.class);
-      addMapping(defaultMappings, "null", NullInfo.class);
-      addMapping(defaultMappings, "jbpm-context", JbpmContextInfo.class);
-      addMapping(defaultMappings, "jbpm-type", JbpmTypeObjectInfo.class);
-    }
-    return defaultMappings;
+    Map mappings = new HashMap();
+    addMapping(mappings, "bean", BeanInfo.class);
+    addMapping(mappings, "ref", RefInfo.class);
+    addMapping(mappings, "list", ListInfo.class);
+    addMapping(mappings, "map", MapInfo.class);
+    addMapping(mappings, "string", StringInfo.class);
+    addMapping(mappings, "int", IntegerInfo.class);
+    addMapping(mappings, "integer", IntegerInfo.class);
+    addMapping(mappings, "long", LongInfo.class);
+    addMapping(mappings, "float", FloatInfo.class);
+    addMapping(mappings, "double", DoubleInfo.class);
+    addMapping(mappings, "char", CharacterInfo.class);
+    addMapping(mappings, "character", CharacterInfo.class);
+    addMapping(mappings, "boolean", BooleanInfo.class);
+    addMapping(mappings, "true", BooleanInfo.class);
+    addMapping(mappings, "false", BooleanInfo.class);
+    addMapping(mappings, "null", NullInfo.class);
+    addMapping(mappings, "jbpm-context", JbpmContextInfo.class);
+    addMapping(mappings, "jbpm-type", JbpmTypeObjectInfo.class);
+    return mappings;
   }
 
-  private static final Class[] constructorParameterTypes = {
-    Element.class, ObjectFactoryParser.class
-  };
-
   private static void addMapping(Map mappings, String elementTagName, Class objectInfoClass) {
     try {
       Constructor constructor = objectInfoClass.getDeclaredConstructor(constructorParameterTypes);
       mappings.put(elementTagName, constructor);
     }
     catch (NoSuchMethodException e) {
-      throw new JbpmException("couldn't add mapping for element '" + elementTagName
-        + "': constructor(" + Element.class.getName() + ","
-        + ObjectFactoryParser.class.getName() + ") was missing for class '"
-        + objectInfoClass.getName() + "'", e);
+      throw new JbpmException("could not add mapping for element '" + elementTagName
+        + "', constructor(" + Element.class.getName() + ","
+        + ObjectFactoryParser.class.getName() + ") missing from " + objectInfoClass, e);
     }
   }
 
   public static ObjectFactoryImpl parseXmlString(String xml) {
-    Element rootElement = XmlUtil.parseXmlText(xml).getDocumentElement();
-    return createObjectFactory(rootElement);
+    return createObjectFactory(XmlUtil.parseXmlText(xml));
   }
 
-  public static ObjectFactoryImpl parseInputStream(InputStream xmlInputStream) {
-    Element rootElement = XmlUtil.parseXmlInputStream(xmlInputStream).getDocumentElement();
-    return createObjectFactory(rootElement);
+  public static ObjectFactoryImpl parseInputStream(InputStream inputStream) {
+    return createObjectFactory(XmlUtil.parseXmlInputStream(inputStream));
   }
 
   public static ObjectFactoryImpl parseResource(String resource) {
-    Element rootElement = XmlUtil.parseXmlResource(resource, false).getDocumentElement();
-    return createObjectFactory(rootElement);
+    return createObjectFactory(XmlUtil.parseXmlResource(resource, false));
   }
 
-  public static ObjectFactoryImpl createObjectFactory(Element rootElement) {
-    ObjectFactoryParser objectFactoryParser = new ObjectFactoryParser();
-    List objectInfos = new ArrayList();
-    for (Iterator iter = XmlUtil.elementIterator(rootElement); iter.hasNext();) {
-      Element topLevelElement = (Element) iter.next();
-      ObjectInfo objectInfo = objectFactoryParser.parse(topLevelElement);
-      objectInfos.add(objectInfo);
-    }
-    return new ObjectFactoryImpl(objectFactoryParser.namedObjectInfos, objectInfos);
+  public static ObjectFactoryImpl createObjectFactory(Document document) {
+    return createObjectFactory(document.getDocumentElement());
   }
 
-  public void parseElementsFromResource(String resource, ObjectFactoryImpl objectFactoryImpl) {
-    Element rootElement = XmlUtil.parseXmlResource(resource, false).getDocumentElement();
-    parseElements(rootElement, objectFactoryImpl);
+  public static ObjectFactoryImpl createObjectFactory(Element infosElement) {
+    ObjectFactoryImpl objectFactory = new ObjectFactoryImpl();
+    new ObjectFactoryParser().load(infosElement, objectFactory);
+    return objectFactory;
   }
 
-  public void parseElementsStream(InputStream inputStream, ObjectFactoryImpl objectFactoryImpl) {
-    Element rootElement = XmlUtil.parseXmlInputStream(inputStream).getDocumentElement();
-    parseElements(rootElement, objectFactoryImpl);
+  /** @deprecated use {@link #load(String, ObjectFactoryImpl)} instead */
+  public void parseElementsFromResource(String resource, ObjectFactoryImpl objectFactory) {
+    load(resource, objectFactory);
   }
 
-  public void parseElements(Element element, ObjectFactoryImpl objectFactoryImpl) {
-    for (Iterator iter = XmlUtil.elementIterator(element); iter.hasNext();) {
-      Element objectInfoElement = (Element) iter.next();
-      ObjectInfo objectInfo = parse(objectInfoElement);
-      objectFactoryImpl.addObjectInfo(objectInfo);
+  public void load(String resource, ObjectFactoryImpl objectFactory) {
+    load(XmlUtil.parseXmlResource(resource, false), objectFactory);
+  }
+
+  /**
+   * @deprecated use {@link #load(InputStream,ObjectFactoryImpl)} instead
+   */
+  public void parseElementsStream(InputStream inputStream, ObjectFactoryImpl objectFactory) {
+    load(inputStream, objectFactory);
+  }
+
+  public void load(InputStream inputStream, ObjectFactoryImpl objectFactory) {
+    load(XmlUtil.parseXmlInputStream(inputStream), objectFactory);
+  }
+
+  public void load(Document document, ObjectFactoryImpl objectFactory) {
+    load(document.getDocumentElement(), objectFactory);
+  }
+
+  /** @deprecated use {@link #load(Element, ObjectFactoryImpl)} instead */
+  public void parseElements(Element infosElement, ObjectFactoryImpl objectFactory) {
+    load(infosElement, objectFactory);
+  }
+
+  public void load(Element infosElement, ObjectFactoryImpl objectFactory) {
+    for (Iterator iter = XmlUtil.elementIterator(infosElement); iter.hasNext();) {
+      Element infoElement = (Element) iter.next();
+      ObjectInfo objectInfo = parse(infoElement);
+      objectFactory.addObjectInfo(objectInfo);
     }
   }
 
   private Map mappings;
-  private Map namedObjectInfos;
 
   public ObjectFactoryParser() {
     this(getDefaultMappings());
@@ -136,7 +146,6 @@
 
   public ObjectFactoryParser(Map mappings) {
     this.mappings = mappings;
-    this.namedObjectInfos = new HashMap();
   }
 
   public ObjectInfo parse(Element element) {
@@ -146,7 +155,9 @@
       throw new JbpmException("no ObjectInfo class specified for element: " + tagName);
     }
     try {
-      return (ObjectInfo) constructor.newInstance(new Object[] { element, this });
+      return (ObjectInfo) constructor.newInstance(new Object[] {
+        element, this
+      });
     }
     catch (InstantiationException e) {
       throw new JbpmException("failed to instantiate " + constructor.getDeclaringClass(), e);
@@ -159,13 +170,13 @@
     }
   }
 
+  /** @deprecated */
   public void addNamedObjectInfo(String name, ObjectInfo objectInfo) {
-    namedObjectInfos.put(name, objectInfo);
   }
 
   public void addMapping(String elementName, Class objectInfoClass) {
-    if (mappings == getDefaultMappings()) {
-      mappings = new HashMap(getDefaultMappings());
+    if (mappings == defaultMappings) {
+      mappings = new HashMap(defaultMappings);
     }
     addMapping(mappings, elementName, objectInfoClass);
   }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ObjectInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -29,5 +29,5 @@
   String getName();
   boolean isSingleton();
 
-  Object createObject(ObjectFactoryImpl objectFactory);
+  Object createObject(ObjectFactory objectFactory);
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/PropertyInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/PropertyInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/PropertyInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -55,7 +55,7 @@
     propertyValueInfo = configParser.parse(propertyValueElement);
   }
 
-  public void injectProperty(Object object, ObjectFactoryImpl objectFactory) {
+  public void injectProperty(Object object, ObjectFactory objectFactory) {
     Method setterMethod = findSetter(object.getClass());
     setterMethod.setAccessible(true);
     Object value = objectFactory.getObject(propertyValueInfo);

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/RefInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/RefInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/RefInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -40,7 +40,7 @@
     bean = refElement.getAttribute("bean");
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     return objectFactory.getObject(bean);
   }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/StringInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/StringInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/StringInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -34,7 +34,7 @@
     s = getValueString(stringElement);
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     return s;
   }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ValueInfo.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ValueInfo.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/configuration/ValueInfo.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -3,16 +3,16 @@
 public class ValueInfo implements ObjectInfo {
 
   private static final long serialVersionUID = 1L;
-  
-  String name;
-  Object value;
-  
+
+  private final String name;
+  private final Object value;
+
   public ValueInfo(String name, Object value) {
     this.name = name;
     this.value = value;
   }
 
-  public Object createObject(ObjectFactoryImpl objectFactory) {
+  public Object createObject(ObjectFactory objectFactory) {
     return value;
   }
 
@@ -21,10 +21,10 @@
   }
 
   public boolean hasName() {
-    return (name!=null);
+    return name != null;
   }
 
   public boolean isSingleton() {
-    return false;
+    return true;
   }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/converter/SerializableToByteArrayConverter.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/converter/SerializableToByteArrayConverter.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/converter/SerializableToByteArrayConverter.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -38,56 +38,55 @@
 
 public class SerializableToByteArrayConverter implements Converter {
 
-	private static final long serialVersionUID = 1L;
+  private static final long serialVersionUID = 1L;
 
-	public boolean supports(Object value) {
-		if(value == null)
-			return true;
-		return Serializable.class.isAssignableFrom(value.getClass());
-	}
+  public boolean supports(Object value) {
+    return value == null || value instanceof Serializable;
+  }
 
-	public Object convert(Object o) {
-		byte[] bytes = null;
-		try {
-			ByteArrayOutputStream memoryStream = new ByteArrayOutputStream();
-			ObjectOutputStream objectStream = new ObjectOutputStream(memoryStream);
-			objectStream.writeObject(o);
-			objectStream.flush();
-			bytes = memoryStream.toByteArray();
-		}
-		catch(IOException e) {
-			throw new JbpmException("couldn't serialize '" + o + "'", e);
-		}
-		return new ByteArray(bytes);
-	}
+  public Object convert(Object o) {
+    byte[] bytes = null;
+    try {
+      ByteArrayOutputStream memoryStream = new ByteArrayOutputStream();
+      ObjectOutputStream objectStream = new ObjectOutputStream(memoryStream);
+      objectStream.writeObject(o);
+      objectStream.flush();
+      bytes = memoryStream.toByteArray();
+    }
+    catch (IOException e) {
+      throw new JbpmException("failed to serialize: " + o, e);
+    }
+    return new ByteArray(bytes);
+  }
 
-	public Object revert(Object o) {
-		ByteArray byteArray = (ByteArray) o;
-		InputStream memoryStream = new ByteArrayInputStream(byteArray.getBytes());
-		try {
-			ObjectInputStream objectStream = new ObjectInputStream(memoryStream);
-			return objectStream.readObject();
-		}
-		catch(IOException ex) {
-			throw new JbpmException("failed to read object", ex);
-		}
-		catch(ClassNotFoundException ex) {
-			throw new JbpmException("serialized object class not found", ex);
-		}
-	}
+  public Object revert(Object o) {
+    ByteArray byteArray = (ByteArray) o;
+    InputStream memoryStream = new ByteArrayInputStream(byteArray.getBytes());
+    try {
+      ObjectInputStream objectStream = new ObjectInputStream(memoryStream);
+      return objectStream.readObject();
+    }
+    catch (IOException ex) {
+      throw new JbpmException("failed to read object", ex);
+    }
+    catch (ClassNotFoundException ex) {
+      throw new JbpmException("serialized object class not found", ex);
+    }
+  }
 
-	public Object revert(Object o, ProcessDefinition processDefinition) {
-		ByteArray byteArray = (ByteArray) o;
-		InputStream memoryStream = new ByteArrayInputStream(byteArray.getBytes());
-		try {
-		  ObjectInputStream objectStream = new CustomLoaderObjectInputStream(memoryStream, JbpmConfiguration.getProcessClassLoader(processDefinition));
-			return objectStream.readObject();
-		}
-		catch(IOException ex) {
-			throw new JbpmException("failed to read object", ex);
-		}
-		catch(ClassNotFoundException ex) {
-			throw new JbpmException("serialized object class not found", ex);
-		}
-	}
+  public Object revert(Object o, ProcessDefinition processDefinition) {
+    ByteArray byteArray = (ByteArray) o;
+    InputStream memoryStream = new ByteArrayInputStream(byteArray.getBytes());
+    try {
+      ObjectInputStream objectStream = new CustomLoaderObjectInputStream(memoryStream,
+        JbpmConfiguration.getProcessClassLoader(processDefinition));
+      return objectStream.readObject();
+    }
+    catch (IOException ex) {
+      throw new JbpmException("failed to read object", ex);
+    }
+    catch (ClassNotFoundException ex) {
+      throw new JbpmException("serialized object class not found", ex);
+    }
+  }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/AbstractDbTestCase.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/AbstractDbTestCase.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/db/AbstractDbTestCase.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -74,7 +74,7 @@
     }
     catch (Exception e) {
       // prevent unsafe use of the session after an exception occurs
-      jbpmContext.setRollbackOnly();
+      if (!jbpmContext.isClosed()) jbpmContext.setRollbackOnly();
       throw e;
     }
   }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -124,6 +124,7 @@
 
   public void beginTransaction() {
     transaction = session.beginTransaction();
+    // commit does a flush anyway
     mustSessionBeFlushed = false;
   }
 
@@ -161,7 +162,7 @@
         }
         catch (SQLException e) {
           // NOTE that Errors are not caught because that might halt the JVM
-          // and mask the original Error.
+          // and mask the original Error
           throw new JbpmPersistenceException("connection to data source failed", e);
         }
       }
@@ -179,10 +180,8 @@
            */
           Configuration configuration = persistenceServiceFactory.getConfiguration();
           String releaseMode = configuration.getProperty(Environment.RELEASE_CONNECTIONS);
-          if ("after_statement".equals(releaseMode)
-            || ("auto".equals(releaseMode) && isJtaOrCmtStrategy(configuration))) {
-            mustConnectionBeClosed = true;
-          }
+          mustConnectionBeClosed = "after_statement".equals(releaseMode)
+            || ("auto".equals(releaseMode) && isJtaOrCmtStrategy(configuration));
         }
       }
     }
@@ -211,12 +210,12 @@
   public void close() {
     Exception flushException = flushSession();
     if (flushException != null) {
-      // JBPM-1465: here the transaction is already committed or rolled back
-      // alternatively, the transaction is managed externally
-      // hence rolling back is redundant and possibly dangerous
+      // JBPM-1465: enabling transaction disables flush, see beginTransaction()
+      // alternatively, transaction is managed externally
+      // in either case, rolling back is unnecessary and possibly disruptive
       closeSession();
       closeConnection();
-      throw new JbpmPersistenceException("hibernate flush session failed", flushException);
+      throw new JbpmPersistenceException("failed to flush hibernate session", flushException);
     }
 
     endTransaction();
@@ -224,12 +223,14 @@
     Exception closeSessionException = closeSession();
     if (closeSessionException != null) {
       closeConnection();
-      throw new JbpmPersistenceException("hibernate close session failed", closeSessionException);
+      throw new JbpmPersistenceException("failed to close hibernate session",
+        closeSessionException);
     }
 
     Exception closeConnectionException = closeConnection();
     if (closeConnectionException != null) {
-      throw new JbpmPersistenceException("hibernate close connection failed", closeConnectionException);
+      throw new JbpmPersistenceException("failed to close hibernate connection",
+        closeConnectionException);
     }
   }
 
@@ -265,12 +266,17 @@
 
   private Exception flushSession() {
     if (mustSessionBeFlushed) {
-      try {
-        session.flush();
+      if (session != null) {
+        try {
+          session.flush();
+        }
+        catch (HibernateException e) {
+          // avoid log and throw antipattern
+          return e;
+        }
       }
-      catch (HibernateException e) {
-        // avoid log and throw antipattern
-        return e;
+      else {
+        log.warn("no hibernate session to flush");
       }
     }
     return null;
@@ -278,7 +284,7 @@
 
   private Exception closeSession() {
     if (mustSessionBeClosed) {
-      if (session.isOpen()) {
+      if (session != null) {
         try {
           session.close();
         }
@@ -288,7 +294,7 @@
         }
       }
       else {
-        log.warn("hibernate session was already closed");
+        log.warn("no hibernate session to close");
       }
     }
     return null;
@@ -374,13 +380,9 @@
       if (customSession != null) return customSession;
     }
     try {
-      Constructor constructor = sessionClass.getConstructor(new Class[] {
-        Session.class
-      });
+      Constructor constructor = sessionClass.getConstructor(new Class[] { Session.class });
       try {
-        Object customSession = constructor.newInstance(new Object[] {
-          session
-        });
+        Object customSession = constructor.newInstance(new Object[] { session });
         customSessions.put(sessionClass, customSession);
         return customSession;
       }
@@ -395,11 +397,8 @@
       }
     }
     catch (NoSuchMethodException e) {
-      throw new JbpmException("constructor not found: "
-        + sessionClass.getName()
-        + '('
-        + Session.class.getName()
-        + ')', e);
+      throw new JbpmException("constructor not found: " + sessionClass.getName() + '('
+        + Session.class.getName() + ')', e);
     }
   }
 

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceServiceFactory.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceServiceFactory.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceServiceFactory.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -23,6 +23,8 @@
 
 import javax.sql.DataSource;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.hibernate.SessionFactory;
 import org.hibernate.cfg.Configuration;
 import org.hibernate.tool.hbm2ddl.SchemaExport;
@@ -48,7 +50,9 @@
   boolean isTransactionEnabled = true;
   boolean isCurrentSessionEnabled;
 
-  /** @deprecated use {@link #jbpmSchema} instead */
+  boolean mustSessionFactoryBeClosed;
+
+  /** @deprecated replaced by {@link #jbpmSchema} */
   private SchemaExport schemaExport;
   private JbpmSchema jbpmSchema;
 
@@ -92,9 +96,11 @@
     if (sessionFactory == null) {
       if (sessionFactoryJndiName != null) {
         sessionFactory = (SessionFactory) JndiUtil.lookup(sessionFactoryJndiName, SessionFactory.class);
+        mustSessionFactoryBeClosed = false;
       }
       else {
         sessionFactory = getConfiguration().buildSessionFactory();
+        mustSessionFactoryBeClosed = true;
       }
     }
     return sessionFactory;
@@ -132,13 +138,17 @@
   }
 
   public void close() {
-    if (sessionFactory != null) sessionFactory.close();
+    if (mustSessionFactoryBeClosed) {
+      if (sessionFactory != null) {
+        sessionFactory.close();
+      }
+      else {
+        Log log = LogFactory.getLog(DbPersistenceServiceFactory.class);
+        log.warn("no session factory to close");
+      }
+    }
   }
 
-  public void finalize() throws Throwable {
-    close();
-  }
-
   public String getDataSourceJndiName() {
     return dataSourceJndiName;
   }
@@ -169,6 +179,7 @@
 
   public void setSessionFactory(SessionFactory sessionFactory) {
     this.sessionFactory = sessionFactory;
+    mustSessionFactoryBeClosed = false;
   }
 
   public boolean isTransactionEnabled() {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -26,6 +26,7 @@
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -78,7 +79,6 @@
   }
 
   private final Map serviceFactories;
-  private final List serviceNames;
   private final Map services;
   private List saveOperations = defaultSaveOperations;
 
@@ -99,19 +99,32 @@
   }
 
   public Services(Map serviceFactories) {
-    this(serviceFactories, new ArrayList(serviceFactories.keySet()), null);
+    this(serviceFactories, null);
   }
 
-  public Services(Map serviceFactories, List serviceNames, List saveOperations) {
+  public Services(Map serviceFactories, List saveOperations) {
     if (serviceFactories == null) {
-      throw new IllegalArgumentException("service factories map is null");
+      throw new IllegalArgumentException("null service factories");
     }
     this.serviceFactories = serviceFactories;
-    this.serviceNames = serviceNames;
     this.services = new HashMap(serviceFactories.size());
     if (saveOperations != null) this.saveOperations = saveOperations;
   }
 
+  /** @deprecated use {@link #Services(Map, List)} instead */
+  public Services(Map serviceFactories, List serviceNames, List saveOperations) {
+    this(orderedMap(serviceFactories, serviceNames), saveOperations);
+  }
+
+  private static Map orderedMap(Map map, List orderedKeys) {
+    Map orderedMap = new LinkedHashMap(map.size());
+    for (Iterator iter = orderedKeys.iterator(); iter.hasNext();) {
+      Object key = iter.next();
+      orderedMap.put(key, map.get(key));
+    }
+    return orderedMap;
+  }
+
   public void setSaveOperations(List saveOperations) {
     if (saveOperations == null) {
       throw new IllegalArgumentException("save operations list is null");
@@ -224,7 +237,7 @@
 
   public void close() {
     RuntimeException firstException = null;
-    for (Iterator iter = serviceNames.iterator(); iter.hasNext();) {
+    for (Iterator iter = serviceFactories.keySet().iterator(); iter.hasNext();) {
       String serviceName = (String) iter.next();
       Service service = (Service) services.get(serviceName);
       if (service == null) continue;

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/ClassLoaderUtil.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -25,6 +25,7 @@
 import java.io.InputStream;
 import java.util.Properties;
 
+import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import org.jbpm.JbpmConfiguration;
@@ -32,7 +33,7 @@
 import org.jbpm.configuration.ObjectFactory;
 
 /**
- * provides centralized classloader lookup.
+ * centralized class loader access.
  */
 public class ClassLoaderUtil {
 
@@ -68,7 +69,7 @@
       return Class.forName(className, false, Thread.currentThread().getContextClassLoader());
     }
     catch (ClassNotFoundException e) {
-      // try the class loader of the current class
+      // fall back on the loader of this class
       return Class.forName(className, false, ClassLoaderUtil.class.getClassLoader());
     }
   }
@@ -91,17 +92,17 @@
     ObjectFactory objectFactory = JbpmConfiguration.Configs.getObjectFactory();
     if (objectFactory.hasObject("jbpm.class.loader")) {
       String classLoader = (String) objectFactory.createObject("jbpm.class.loader");
-    
+
       if ("jbpm".equals(classLoader)) {
         // use class loader that loaded the jbpm classes
         return ClassLoaderUtil.class.getClassLoader();
       }
-    
+
       if (classLoader.equals("context")) {
         // use the context class loader
         return Thread.currentThread().getContextClassLoader();
       }
-    
+
       // interpret value as a reference to a class loader bean
       return (ClassLoader) objectFactory.createObject(classLoader);
     }
@@ -116,26 +117,24 @@
   }
 
   /**
-   * Loads resource as stream. If <code>useConfiguredLoader</code> is <code>true</code>, this
-   * method searches for the resource in the context class loader, if not found it searches in
-   * the class loader of this class.
-   * <p>
-   * This method helps bootstrap jBPM because the class loader used for locating the
-   * configuration resource cannot be configured in the configuration itself.
-   * </p>
+   * Returns a stream for reading the specified resource. This method helps bootstrap jBPM
+   * because the class loader used for locating the configuration resource cannot be configured
+   * in the configuration itself.
    * 
+   * @param useConfiguredLoader if <code>true</code>, this method searches for the resource in
+   * the context class loader, if not found it falls back on the loader of this class
    * @return a stream for reading the resource, or <code>null</code> if the resource was not
    * found
    */
   public static InputStream getStream(String resource, boolean useConfiguredLoader) {
     if (useConfiguredLoader) return getStream(resource);
 
-    // try context class loader first, allowing applications to hide the provided resources
+    // try context class loader first, allowing applications to override built-in resources
     InputStream stream = Thread.currentThread()
       .getContextClassLoader()
       .getResourceAsStream(resource);
     if (stream == null) {
-      // try class loader of the current class
+      // fall back on the loader of this class
       stream = ClassLoaderUtil.class.getClassLoader().getResourceAsStream(resource);
     }
     return stream;
@@ -157,8 +156,8 @@
         inStream.close();
       }
       catch (IOException e) {
-        LogFactory.getLog(ClassLoaderUtil.class)
-          .warn("failed to close resource: " + resource, e);
+        Log log = LogFactory.getLog(ClassLoaderUtil.class);
+        log.warn("failed to close resource: " + resource, e);
       }
     }
   }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/XmlUtil.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/XmlUtil.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/util/XmlUtil.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -22,6 +22,7 @@
 package org.jbpm.util;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringWriter;
 import java.util.ArrayList;
@@ -30,7 +31,6 @@
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.FactoryConfigurationError;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.Result;
 import javax.xml.transform.Source;
@@ -48,9 +48,20 @@
 import org.w3c.dom.Node;
 import org.w3c.dom.Text;
 import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
 
 public class XmlUtil {
 
+  private static final DocumentBuilderFactory documentBuilderFactory = createDocumentBuilderFactory();
+
+  private static DocumentBuilderFactory createDocumentBuilderFactory() {
+    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+    factory.setNamespaceAware(true);
+    factory.setCoalescing(true);
+    factory.setIgnoringComments(true);
+    return factory;
+  }
+
   private XmlUtil() {
     // hide default constructor to prevent instantiation
   }
@@ -61,14 +72,14 @@
   }
 
   /**
-   * @param useConfiguredLoader specifies if the resource should be loaded with the "limited"
-   * bootstrap class loader for jbpm config.
+   * @param useConfiguredLoader if <code>true</code>, this method searches for the resource in
+   * the context class loader, if not found it falls back on the class loader of this class
+   * @see <a href="https://jira.jboss.org/jira/browse/JBPM-1148">JBPM-1148</a>
    */
   public static Document parseXmlResource(String resource, boolean useConfiguredLoader) {
-    // see https://jira.jboss.org/jira/browse/JBPM-1148
     InputStream inputStream = ClassLoaderUtil.getStream(resource, useConfiguredLoader);
     if (inputStream == null) {
-      throw new IllegalArgumentException("Cannot load resource: " + resource);
+      throw new IllegalArgumentException("resource not found: " + resource);
     }
     InputSource inputSource = new InputSource(inputStream);
     return parseXmlInputSource(inputSource);
@@ -79,9 +90,12 @@
     try {
       document = getDocumentBuilder().parse(inputStream);
     }
-    catch (Exception e) {
-      throw new XmlException("couldn't parse xml", e);
+    catch (IOException e) {
+      throw new XmlException("could not read input", e);
     }
+    catch (SAXException e) {
+      throw new XmlException("failed to parse xml", e);
+    }
     return document;
   }
 
@@ -90,16 +104,22 @@
     try {
       document = getDocumentBuilder().parse(inputSource);
     }
-    catch (Exception e) {
-      throw new XmlException("couldn't parse xml", e);
+    catch (IOException e) {
+      throw new XmlException("could not read input", e);
     }
+    catch (SAXException e) {
+      throw new XmlException("failed to parse xml", e);
+    }
     return document;
   }
 
-  public static DocumentBuilder getDocumentBuilder() throws FactoryConfigurationError,
-    ParserConfigurationException {
-    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-    return factory.newDocumentBuilder();
+  public synchronized static DocumentBuilder getDocumentBuilder() {
+    try {
+      return documentBuilderFactory.newDocumentBuilder();
+    }
+    catch (ParserConfigurationException e) {
+      throw new XmlException("failed to create document builder", e);
+    }
   }
 
   public static String attribute(Element element, String attrName) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/JbpmConfigurationTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/JbpmConfigurationTest.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/JbpmConfigurationTest.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -26,6 +26,8 @@
 import org.jbpm.configuration.ObjectFactory;
 import org.jbpm.configuration.ObjectFactoryImpl;
 import org.jbpm.configuration.ObjectFactoryParser;
+import org.jbpm.configuration.ObjectInfo;
+import org.jbpm.util.ClassLoaderUtil;
 import org.jbpm.util.XmlException;
 
 public class JbpmConfigurationTest extends AbstractJbpmTestCase {
@@ -146,13 +148,31 @@
 
     private static final long serialVersionUID = 1L;
 
+    public boolean hasObject(String name) {
+      return "myproperty".equals(name);
+    }
+
     public Object createObject(String name) {
       return "myproperty".equals(name) ? "mycustomfactoriedvalue" : null;
     }
 
-    public boolean hasObject(String name) {
-      return "myproperty".equals(name);
+    public Object createObject(ObjectInfo objectInfo) {
+      String name = objectInfo.getName();
+      return hasObject(name) ? createObject(name) : objectInfo.createObject(this);
     }
+
+    public Object getObject(String name) {
+      return "myproperty".equals(name) ? "mycustomfactoriedvalue" : null;
+    }
+
+    public Object getObject(ObjectInfo objectInfo) {
+      String name = objectInfo.getName();
+      return hasObject(name) ? getObject(name) : objectInfo.createObject(this);
+    }
+
+    public Class classForName(String className) throws ClassNotFoundException {
+      return ClassLoaderUtil.classForName(className);
+    }
   }
 
   public void testDomainModelConfigsWithCustomObjectFactory() {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/configuration/JbpmContextTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/configuration/JbpmContextTest.java	2010-08-11 09:01:40 UTC (rev 6571)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/configuration/JbpmContextTest.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -21,82 +21,81 @@
  */
 package org.jbpm.configuration;
 
+import java.util.Iterator;
+import java.util.Map;
+
 import org.jbpm.AbstractJbpmTestCase;
 import org.jbpm.JbpmContext;
 import org.jbpm.svc.Service;
 import org.jbpm.svc.ServiceFactory;
-import org.jbpm.svc.Services;
 
 public class JbpmContextTest extends AbstractJbpmTestCase {
 
-  protected ObjectFactoryImpl objectFactory = null;
-
-  protected void parse(String xml) {
-    objectFactory = ObjectFactoryParser.parseXmlString(xml);
+  private static ObjectFactory parse(String xml) {
+    return ObjectFactoryParser.parseXmlString(xml);
   }
 
   public void testEmptyJbpmContext() {
-    parse(
-      "<jbpm-configuration>" +
-      "  <jbpm-context name='mycontext' />" +
-      "</jbpm-configuration>"
-    );
-    
+    ObjectFactory objectFactory = parse("<jbpm-configuration>"
+      + "  <jbpm-context name='mycontext' />"
+      + "</jbpm-configuration>");
+
     JbpmContext jbpmContext = (JbpmContext) objectFactory.createObject("mycontext");
-    assertNotNull(jbpmContext);
     assertNotNull(jbpmContext.getServices());
-    assertNotNull(jbpmContext.getServices());
   }
-  
+
   public static class MyServiceFactory implements ServiceFactory {
     private static final long serialVersionUID = 1L;
+
     public Service openService() {
       return null;
     }
+
     public void close() {
     }
   }
 
   public void testJbpmContextWithBeanServiceFactory() {
-    parse(
-      "<jbpm-configuration>" +
-      "  <jbpm-context name='mycontext'>" +
-      "    <service name='myservice' factory='org.jbpm.configuration.JbpmContextTest$MyServiceFactory' />" +
-      "  </jbpm-context>" +
-      "</jbpm-configuration>"
-    );
-    
+    ObjectFactory objectFactory = parse("<jbpm-configuration>"
+      + "  <jbpm-context name='mycontext'>"
+      + "    <service name='myservice' factory='"
+      + MyServiceFactory.class.getName()
+      + "' />"
+      + "  </jbpm-context>"
+      + "</jbpm-configuration>");
+
     JbpmContext jbpmContext = (JbpmContext) objectFactory.createObject("mycontext");
-    assertNotNull(jbpmContext);
-    assertEquals(1, jbpmContext.getServices().getServiceFactories().size());
-    assertTrue(jbpmContext.getServices().getServiceFactories().containsKey("myservice"));
+    Map serviceFactories = jbpmContext.getServices().getServiceFactories();
+    assertEquals(1, serviceFactories.size());
+    assertEquals("myservice", serviceFactories.keySet().iterator().next());
   }
 
   public void testJbpmContextWithTwoServiceFactories() {
-    parse(
-      "<jbpm-configuration>" +
-      "  <bean name='myservicebean' class='org.jbpm.configuration.JbpmContextTest$MyServiceFactory' />" +
-      "  <jbpm-context name='mycontext'>" +
-      "    <service name='myservice'>" +
-      "      <factory>" +
-      "        <ref bean='myservicebean' />" +
-      "      </factory>" +
-      "    </service>" +
-      "    <service name='mysecondservice'>" +
-      "      <factory>" +
-      "        <ref bean='myservicebean' />" +
-      "      </factory>" +
-      "    </service>" +
-      "  </jbpm-context>" +
-      "</jbpm-configuration>"
-    );
-    
+    ObjectFactory objectFactory = parse("<jbpm-configuration>"
+      + "  <bean name='myservicebean' class='"
+      + MyServiceFactory.class.getName()
+      + "' />"
+      + "  <jbpm-context name='mycontext'>"
+      + "    <service name='myservice'>"
+      + "      <factory>"
+      + "        <ref bean='myservicebean' />"
+      + "      </factory>"
+      + "    </service>"
+      + "    <service name='myservice2'>"
+      + "      <factory>"
+      + "        <ref bean='myservicebean' />"
+      + "      </factory>"
+      + "    </service>"
+      + "  </jbpm-context>"
+      + "</jbpm-configuration>");
+
     JbpmContext jbpmContext = (JbpmContext) objectFactory.createObject("mycontext");
-    assertNotNull(jbpmContext);
-    Services services = jbpmContext.getServices();
-    assertEquals(2, services.getServiceFactories().size());
-    assertTrue(services.getServiceFactories().containsKey("myservice"));
-    assertTrue(services.getServiceFactories().containsKey("mysecondservice"));
-    assertSame(services.getServiceFactory("myservice"), services.getServiceFactory("mysecondservice"));
+    Map serviceFactories = jbpmContext.getServices().getServiceFactories();
+    assertEquals(2, serviceFactories.size());
+    // iteration order is guaranteed!
+    Iterator serviceNames = serviceFactories.keySet().iterator();
+    assertEquals("myservice", serviceNames.next());
+    assertEquals("myservice2", serviceNames.next());
+    assertSame(serviceFactories.get("myservice"), serviceFactories.get("myservice2"));
   }
 }

Added: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2605/JBPM2605Test.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2605/JBPM2605Test.java	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2605/JBPM2605Test.java	2010-08-11 12:38:50 UTC (rev 6572)
@@ -0,0 +1,65 @@
+/*
+ * 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.jbpm2605;
+
+import org.hibernate.SessionFactory;
+import org.hibernate.cfg.Configuration;
+import org.jbpm.db.AbstractDbTestCase;
+import org.jbpm.graph.def.ProcessDefinition;
+import org.jbpm.persistence.db.DbPersistenceServiceFactory;
+
+/**
+ * {@link DbPersistenceServiceFactory} should not close {@link SessionFactory} if it did not
+ * open it.
+ * 
+ * @see <a href="https://jira.jboss.org/browse/JBPM-2605">JBPM-2605</a>
+ * @author Alejandro Guizar
+ */
+public class JBPM2605Test extends AbstractDbTestCase {
+
+  private SessionFactory sessionFactory;
+
+  protected void setUp() throws Exception {
+    super.setUp();
+    sessionFactory = new Configuration().configure().buildSessionFactory();
+    jbpmContext.setSessionFactory(sessionFactory);
+  }
+
+  protected void tearDown() throws Exception {
+    super.tearDown();
+    sessionFactory.close();
+  }
+
+  public void testExternalSessionFactory() {
+    deployProcessDefinition(new ProcessDefinition(getName()));
+    closeJbpmContext();
+    try {
+      jbpmConfiguration.close();
+      jbpmConfiguration = null;
+      assertFalse("expected external session factory to remain open", sessionFactory.isClosed());
+    }
+    finally {
+      createJbpmContext();
+      jbpmContext.setSessionFactory(sessionFactory);
+    }
+  }
+}


Property changes on: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/jbpm2605/JBPM2605Test.java
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the jbpm-commits mailing list