0 Replies Latest reply on Jan 23, 2009 12:13 PM by jhsingle

    JUnit throws TransactionRequiredException

    jhsingle

      I am porting an app from JBoss 4.2.0 to JBoss 5.0.0.GA. Our ear deploys, but our JUnit integration tests throw the following exception when calling a method on our SLSB:

      -------------------------------------------------------------------------------
      Test set: workflow.test.ejb.LoopTest
      -------------------------------------------------------------------------------
      Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 3.567 sec <<< FAILURE!
      testDefine(workflow.test.ejb.LoopTest) Time elapsed: 3.525 sec <<< ERROR!
      javax.persistence.TransactionRequiredException: EntityManager must be access within a transaction
       at org.jboss.jpa.deployment.ManagedEntityManagerFactory.verifyInTx(ManagedEntityManagerFactory.java:155)
       at org.jboss.jpa.tx.TransactionScopedEntityManager.persist(TransactionScopedEntityManager.java:186)
       at workflow.ejb.server.WorkflowManager.persistExecutionSummaryImplementation(WorkflowManager.java:386)
       at workflow.ejb.server.WorkflowManager.persistExecutionSummary(WorkflowManager.java:93)
       at workflow.ejb.server.WorkflowManager.startImplementation(WorkflowManager.java:717)
       at workflow.ejb.server.WorkflowManager.start(WorkflowManager.java:263)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeTarget(MethodInvocation.java:122)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:111)
       at org.jboss.ejb3.EJBContainerInvocationWrapper.invokeNext(EJBContainerInvocationWrapper.java:69)
       at org.jboss.ejb3.interceptors.aop.InterceptorSequencer.invoke(InterceptorSequencer.java:73)
       at org.jboss.ejb3.interceptors.aop.InterceptorSequencer.aroundInvoke(InterceptorSequencer.java:59)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.aop.advice.PerJoinpointAdvice.invoke(PerJoinpointAdvice.java:174)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.fillMethod(InvocationContextInterceptor.java:72)
       at org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor_z_fillMethod_25059428.invoke(InvocationContextInterceptor_z_fillMethod_25059428.java)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor.setup(InvocationContextInterceptor.java:88)
       at org.jboss.aop.advice.org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor_z_setup_25059428.invoke(InvocationContextInterceptor_z_setup_25059428.java)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:62)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:56)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:68)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.aspects.tx.TxPolicy.invokeInNoTx(TxPolicy.java:66)
       at org.jboss.ejb3.tx.TxInterceptor$NotSupported.invoke(TxInterceptor.java:114)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.security.RunAsSecurityInterceptorv2.invoke(RunAsSecurityInterceptorv2.java:94)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.security.RoleBasedAuthorizationInterceptorv2.invoke(RoleBasedAuthorizationInterceptorv2.java:201)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:159)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:65)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:486)
       at org.jboss.ejb3.session.InvokableContextClassProxyHack._dynamicInvoke(InvokableContextClassProxyHack.java:56)
       at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:91)
       at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
       at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:908)
       at org.jboss.remoting.transport.socket.ServerThread.completeInvocation(ServerThread.java:742)
       at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:695)
       at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:522)
       at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:230)
       at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:206)
       at org.jboss.remoting.Client.invoke(Client.java:1708)
       at org.jboss.remoting.Client.invoke(Client.java:612)
       at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:60)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.security.client.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:65)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:76)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
       at $Proxy32.invoke(Unknown Source)
       at org.jboss.ejb3.proxy.handler.ProxyInvocationHandlerBase.invoke(ProxyInvocationHandlerBase.java:261)
       at org.jboss.ejb3.proxy.handler.session.SessionSpecProxyInvocationHandlerBase.invoke(SessionSpecProxyInvocationHandlerBase.java:101)
       at $Proxy3.start(Unknown Source)
       at workflow.test.ejb.LoopTest.testDefine(LoopTest.java:128)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at junit.framework.TestCase.runTest(TestCase.java:164)
       at junit.framework.TestCase.runBare(TestCase.java:130)
       at junit.framework.TestResult$1.protect(TestResult.java:106)
       at junit.framework.TestResult.runProtected(TestResult.java:124)
       at junit.framework.TestResult.run(TestResult.java:109)
       at junit.framework.TestCase.run(TestCase.java:120)
       at junit.framework.TestSuite.runTest(TestSuite.java:230)
       at junit.framework.TestSuite.run(TestSuite.java:225)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:213)
       at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
       at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
       at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
       at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)
       at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:72)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.security.client.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:65)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:76)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
       at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
       at $Proxy32.invoke(Unknown Source)
       at org.jboss.ejb3.proxy.handler.ProxyInvocationHandlerBase.invoke(ProxyInvocationHandlerBase.java:261)
       at org.jboss.ejb3.proxy.handler.session.SessionSpecProxyInvocationHandlerBase.invoke(SessionSpecProxyInvocationHandlerBase.java:101)
       at $Proxy3.start(Unknown Source)
       at workflow.test.ejb.LoopTest.testDefine(LoopTest.java:128)
      


      Here is the code of LoopTest:
      package workflow.test.ejb;
      
      
      
      import java.io.FileNotFoundException;
      
      import java.io.InputStream;
      
      import java.util.List;
      
      import java.util.Properties;
      
      
      
      import javax.naming.InitialContext;
      
      
      
      import junit.framework.TestCase;
      
      
      
      import org.wfmc._2004.xpdl2.Activity;
      
      import org.wfmc._2004.xpdl2.DataField;
      
      import org.wfmc._2004.xpdl2.ExtendedAttributes;
      
      import org.wfmc._2004.xpdl2.Loop;
      
      import org.wfmc._2004.xpdl2.Transition;
      
      
      
      import workflow.ejb.client.ExecutionDetail;
      
      import workflow.ejb.client.ExecutionSummary;
      
      import workflow.ejb.client.WorkflowManagerRemote;
      
      import workflow.ejb.client.WorkflowPackage;
      
      
      
      /**
      
       * Test Looping
      
       *
      
       */
      
      public class LoopTest extends TestCase {
      
       /**
      
       * Remote interface for Workflow Manager
      
       */
      
       private WorkflowManagerRemote mgr = null;
      
      
      
       /**
      
       * Polling time
      
       */
      
       private static final int POLL_TIME = 10000;
      
      
      
       /**
      
       * Loop wait time
      
       */
      
       private static final int LOOP_WAIT_TIME = 5000;
      
      
      
       /**
      
       * Maximum number of iterations (i < 6)
      
       */
      
       private static final int MAX_ITERATIONS = 3;
      
      
      
       /**
      
       * Initial iteration value (i = 0)
      
       */
      
       private static final int INITIAL_ITERATION_VALUE = 0;
      
      
      
       /**
      
       * When to test after = do/while loop before = for loop
      
       */
      
       private static final String WHEN_TO_TEST = "after";
      
      
      
       /**
      
       * main()
      
       *
      
       * @param args
      
       */
      
       public static void main(String[] args) {
      
       junit.textui.TestRunner.run(BasicWorkflowTest.class);
      
       }
      
      
      
       /**
      
       * Constructor()
      
       *
      
       * @param name
      
       */
      
       public LoopTest(String name) {
      
       super(name);
      
       }
      
      
      
       /**
      
       * This method is the actual test case that is executed
      
       *
      
       * @throws Exception
      
       */
      
       public void testDefine() throws Exception {
      
       long id = -1;
      
      
      
       String name = "Name_" + System.currentTimeMillis() + "_"
      
       + Thread.currentThread().getId();
      
       try {
      
       // Construct XPDL
      
      
      
       WorkflowPackage pkg = new WorkflowPackage(name, "0", "BasicPD1_"
      
       + name);
      
       // Activity 0
      
       Activity a0 = pkg.addActivity("0", "0_cm");
      
       // Activity Data Fields.
      
      
      
       DataField df = WorkflowPackage.createDataField("numStmts",/* 0, */
      
       false, false, 10 + "");
      
       WorkflowPackage.addDataFieldToActivity(a0, df);
      
       ExtendedAttributes eas = WorkflowPackage.createExternalAttributes(
      
       "ModelManagerRemote", "workflow/ModelManager/remote",
      
       "ModelManagerRemote", "getModelAsString", "result0");
      
       a0.setExtendedAttributes(eas);
      
       Loop loop = WorkflowPackage.createStandardLoop(LOOP_WAIT_TIME,
      
       MAX_ITERATIONS, INITIAL_ITERATION_VALUE, WHEN_TO_TEST);
      
       a0.setLoop(loop);
      
      
      
       // Activity 1
      
       Activity a1 = pkg.addActivity("07777", "0_pass");
      
       // Activity Data Fields.
      
       DataField df2 = WorkflowPackage
      
       .createDataField("result0" /* , 0 */);
      
       WorkflowPackage.addDataFieldToActivity(a1, df2);
      
       eas = WorkflowPackage.createExternalAttributes(
      
       "ModelManagerRemote", "workflow/ModelManager/remote",
      
       "ModelManagerRemote", "passModel", "result07777");
      
       a1.setExtendedAttributes(eas);
      
      
      
       // Transition
      
       Transition t = new Transition();
      
       t.setName("0_cm_to_0_pass");
      
       t.setId("09999");
      
       t.setTo("07777");
      
       t.setFrom("0");
      
       pkg.addTransition(t); // Loop
      
      
      
       String xpdl = pkg.generateXPDL();
      
      
      
       id = mgr.persistProcessDefinition(xpdl);
      
       long pid = mgr.start(id);
      
      
      
       // give a chance for all actions to complete.
      
       ExecutionSummary executionSummary = mgr
      
       .retrieveProcessInstanceStatus(pid);
      
       int ctr = 0;
      
       boolean foundCount1 = false;
      
       boolean foundCount2 = false;
      
      
      
       while (executionSummary.getWhenCompleted() == null && ctr++ < 10) {
      
       Thread.sleep(POLL_TIME);
      
       executionSummary = mgr.retrieveProcessInstanceStatus(pid);
      
       }
      
      
      
       assertNotNull(executionSummary.getWhenCompleted());
      
       if (executionSummary.getWhenCompleted() != null) {
      
       List<ExecutionDetail> edList = executionSummary
      
       .getExecutionDetails();
      
       for (ExecutionDetail ed : edList) {
      
       if (ed.getResultingParams().containsKey("result0")) {
      
       foundCount1 = true;
      
       }
      
       if (ed.getResultingParams().containsKey("result07777")) {
      
       foundCount2 = true;
      
       }
      
       }
      
       }
      
      
      
       assertTrue(foundCount1);
      
       assertTrue(foundCount2);
      
      
      
       } finally {
      
       mgr.removeProcessDefinition(id);
      
       }
      
       }
      
      
      
       /**
      
       * @see TestCase#setUp()
      
       */
      
       @Override
      
       protected void setUp() throws Exception {
      
       super.setUp();
      
      
      
       InputStream in = getClass()
      
       .getResourceAsStream("/bootstrap.properties");
      
       if (in == null) {
      
       throw new FileNotFoundException(
      
       "Can't find file in classpath: bootstrap.properties");
      
       }
      
       Properties props = new Properties();
      
       props.load(in);
      
      
      
       InitialContext ic = new InitialContext(props);
      
      
      
       mgr = (WorkflowManagerRemote) ic
      
       .lookup("workflow/WorkflowManager/remote");
      
      
      
       }
      
      
      
       /**
      
       * @see TestCase#tearDown()
      
       */
      
       @Override
      
       protected void tearDown() throws Exception {
      
       super.tearDown();
      
       }
      
      
      
      }
      
      


      And here is the code for WorkflowManager which sets transactionManagement to CONTAINER, and transactionAttribute of the persistExecutionSummary() method to REQUIRES_NEW.
      package workflow.ejb.server;
      
      import java.io.Serializable;
      import java.util.ArrayList;
      import java.util.Date;
      import java.util.List;
      
      import javax.annotation.security.RolesAllowed;
      import javax.ejb.EJBContext;
      import javax.ejb.Stateless;
      import javax.ejb.TransactionAttribute;
      import javax.ejb.TransactionAttributeType;
      import javax.ejb.TransactionManagement;
      import javax.ejb.TransactionManagementType;
      import javax.jws.WebService;
      import javax.jws.soap.SOAPBinding;
      import javax.persistence.EntityExistsException;
      import javax.persistence.EntityManager;
      import javax.persistence.PersistenceContext;
      import javax.persistence.Query;
      
      import org.apache.commons.lang.StringUtils;
      import org.apache.commons.logging.Log;
      import org.apache.commons.logging.LogFactory;
      import org.jboss.ejb3.annotation.RemoteBinding;
      import org.jboss.wsf.spi.annotation.WebContext;
      
      import security.authorization.AuthorizationPluginException;
      import security.authorization.BlackbookAuthorizationManager;
      import security.ejb.client.User;
      import workflow.ejb.client.ExecutionDetail;
      import workflow.ejb.client.ExecutionSummary;
      import workflow.ejb.client.ProcessDefinition;
      import workflow.ejb.client.ProcessDefinitionDigester;
      import workflow.ejb.client.StepDefinition;
      import workflow.ejb.client.TransitionReference;
      import workflow.ejb.client.WorkflowManagerRemote;
      import workflow.ejb.util.ParamUtil;
      
      /**
       * Implementation for the workflow management API.
       */
      @Stateless
      @WebService(endpointInterface = "workflow.ejb.client.WorkflowManagerEndpoint")
      @SOAPBinding(style = SOAPBinding.Style.RPC)
      @RolesAllowed( { "UNCLASSIFIED" })
      @RemoteBinding(jndiBinding = "workflow/WorkflowManager/remote")
      @TransactionManagement(value = TransactionManagementType.CONTAINER)
      @WebContext(contextRoot = "/workflowws", authMethod = "CLIENT-CERT", transportGuarantee = "CONFIDENTIAL", secureWSDLAccess = false)
      public class WorkflowManager implements Serializable, WorkflowManagerRemote {
       /**
       * The message queue
       */
       public static String queueName = "queue/WorkflowQ";
      
       /**
       * The class logger
       */
       private static Log logger = LogFactory.getLog(WorkflowManager.class);
      
       /**
       * The entity manager
       */
       @PersistenceContext(unitName = "workflow")
       protected EntityManager em;
      
       /** EJB context */
       @javax.annotation.Resource
       EJBContext ctx;
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#copyProcessDefinition(long)
       */
       public long copyProcessDefinition(long id) {
       return copyProcessDefinitionImplementation(getUser(), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#copyProcessDefinitionProxy(java.lang.String,
       * long)
       */
       @RolesAllowed( { "PROXY_USER" })
       public long copyProcessDefinitionProxy(String publicKey, long id) {
       return copyProcessDefinitionImplementation(getUser(publicKey), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#persistExecutionSummary(workflow.ejb.client.ExecutionSummary)
       */
       @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
       public ExecutionSummary persistExecutionSummary(
       ExecutionSummary executionSummaryCopy) {
       return persistExecutionSummaryImplementation(getUser(),
       executionSummaryCopy);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#persistExecutionSummaryProxy(java.lang.String,
       * workflow.ejb.client.ExecutionSummary)
       */
       @RolesAllowed( { "PROXY_USER" })
       @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
       public ExecutionSummary persistExecutionSummaryProxy(String publicKey,
       ExecutionSummary executionSummaryCopy) {
       return persistExecutionSummaryImplementation(getUser(publicKey),
       executionSummaryCopy);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#persistProcessDefinition(java.lang.String)
       */
       public long persistProcessDefinition(String definition) {
       return persistProcessDefinitionImplementation(getUser(), definition);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#persistProcessDefinitionProxy(java.lang.String,
       * java.lang.String)
       */
       @RolesAllowed( { "PROXY_USER" })
       public long persistProcessDefinitionProxy(String publicKey,
       String definition) {
       return persistProcessDefinitionImplementation(getUser(publicKey),
       definition);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#removeExecution(long)
       */
       public void removeExecution(long id) {
       removeExecutionImplementation(getUser(), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#removeExecutionProxy(java.lang.String,
       * long)
       */
       @RolesAllowed( { "PROXY_USER" })
       public void removeExecutionProxy(String publicKey, long id) {
       removeExecutionImplementation(getUser(publicKey), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#removeProcessDefinition(long)
       */
       public void removeProcessDefinition(long id) {
       removeProcessDefinitionImplementation(getUser(), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#removeProcessDefinitionProxy(java.lang.String,
       * long)
       */
       @RolesAllowed( { "PROXY_USER" })
       public void removeProcessDefinitionProxy(String publicKey, long id) {
       removeProcessDefinitionImplementation(getUser(publicKey), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#retrieveProcessDefinition(long)
       */
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public String retrieveProcessDefinition(long id) {
       return retrieveProcessDefinitionImplementation(getUser(), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#retrieveProcessDefinitionProxy(java.lang.String,
       * long)
       */
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       @RolesAllowed( { "PROXY_USER" })
       public String retrieveProcessDefinitionProxy(String publicKey, long id) {
       return retrieveProcessDefinitionImplementation(getUser(publicKey), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#retrieveMostRecentProcessInstanceID(long)
       */
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public long retrieveMostRecentProcessInstanceID(long pdId) {
       return retrieveMostRecentProcessInstanceIDImplementation(getUser(),
       pdId);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#retrieveMostRecentProcessInstanceIDProxy(java.lang.String,
       * long)
       */
       @RolesAllowed( { "PROXY_USER" })
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public long retrieveMostRecentProcessInstanceIDProxy(String publicKey,
       long pdId) {
       return retrieveMostRecentProcessInstanceIDImplementation(
       getUser(publicKey), pdId);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#retrieveProcessInstanceIDs(long)
       */
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public long[] retrieveProcessInstanceIDs(long pdId) {
       return retrieveProcessInstanceIDsImplementation(getUser(), pdId);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#retrieveProcessInstanceIDsProxy(java.lang.String,
       * long)
       */
       @RolesAllowed( { "PROXY_USER" })
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public long[] retrieveProcessInstanceIDsProxy(String publicKey, long pdId) {
       return retrieveProcessInstanceIDsImplementation(getUser(publicKey),
       pdId);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#retrieveProcessInstanceStatus(long)
       */
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public ExecutionSummary retrieveProcessInstanceStatus(long id) {
       return retrieveProcessInstanceStatusImplementation(getUser(), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#retrieveProcessInstanceStatusProxy(java.lang.String,
       * long)
       */
       @RolesAllowed( { "PROXY_USER" })
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public ExecutionSummary retrieveProcessInstanceStatusProxy(
       String publicKey, long id) {
       return retrieveProcessInstanceStatusImplementation(getUser(publicKey),
       id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#retrieveProcessInstanceStatusNoResults(long)
       */
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public ExecutionSummary retrieveProcessInstanceStatusNoResults(long id) {
       return retrieveProcessInstanceStatusNoResultsImplementation(getUser(),
       id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#retrieveProcessInstanceStatusNoResultsProxy(java.lang.String,
       * long)
       */
       @RolesAllowed( { "PROXY_USER" })
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public ExecutionSummary retrieveProcessInstanceStatusNoResultsProxy(
       String publicKey, long id) {
       return retrieveProcessInstanceStatusNoResultsImplementation(
       getUser(publicKey), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#start(long)
       */
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public long start(long id) {
       return startImplementation(getUser(), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#startProxy(java.lang.String,
       * long)
       */
       @RolesAllowed( { "PROXY_USER" })
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public long startProxy(String publicKey, long id) {
       return startImplementation(getUser(publicKey), id);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#updateProcessDefinition(long,
       * java.lang.String)
       */
       public long updateProcessDefinition(long id, String definition) {
       return updateProcessDefinitionImplementation(getUser(), id, definition);
       }
      
       /**
       * @see workflow.ejb.client.WorkflowManagerEndpoint#updateProcessDefinitionProxy(java.lang.String,
       * long, java.lang.String)
       */
       @RolesAllowed( { "PROXY_USER" })
       public long updateProcessDefinitionProxy(String publicKey, long id,
       String definition) {
       return updateProcessDefinitionImplementation(getUser(publicKey), id,
       definition);
       }
      
       /**
       * Implementation of copy.
       *
       * @param user
       * the user information
       * @param id
       * the ID of the process definition to copy
       * @return the ID of the new process definition
       */
       private long copyProcessDefinitionImplementation(User user, long id) {
       try {
       ProcessDefinition pd = em.find(ProcessDefinition.class, id);
       return persistProcessDefinitionImplementation(user, pd
       .getDefinition());
       } catch (EntityExistsException e) {
       logger.error("Error copying ProcessDefinition", e);
       throw e;
       } catch (Exception e) {
       logger.error("An error occurred while copying ProcessDefinition.",
       e);
       throw new RuntimeException(
       "An error occurred while copying ProcessDefinition.");
       }
       }
      
       /**
       * @param exId
       * @return String
       */
       private String getResultingParams(long exId) {
       Query query = em.createQuery(
       "SELECT rp.resultingParamsAsXML FROM ResultingParams rp "
       + " WHERE rp.exDetailId =:first ").setHint(
       "org.hibernate.readOnly", Boolean.TRUE);
      
       // get execution detail of previous step.
       query.setParameter("first", exId);
      
       List<?> resultList = query.getResultList();
       String results = "";
       if (resultList != null && resultList.size() != 0) {
       results = (String) resultList.get(0);
       }
       return results;
       }
      
       /**
       * @return the user information from the EJB context
       */
       private User getUser() {
       User user = new User(ctx);
       return user;
       }
      
       /**
       * @param publicKey
       * the public key for the user
       * @return the user information from the authorization system
       */
       private User getUser(String publicKey) {
       if (StringUtils.isBlank(publicKey)) {
       throw new RuntimeException("'publicKey' cannot be null or blank.");
       }
      
       User user = null;
       try {
       user = new User(BlackbookAuthorizationManager
       .getBlackbookPrincipal(publicKey));
       } catch (AuthorizationPluginException e) {
       logger.error("Error retrieving user information.", e);
       throw new RuntimeException("Error retrieving user information.");
       }
       return user;
       }
      
       /**
       * Implementation for persist execution summary.
       *
       * @param user
       * the user information
       * @param executionSummaryCopy
       * the new execution summary
       * @return the newly persisted execution summary
       */
       private ExecutionSummary persistExecutionSummaryImplementation(User user,
       ExecutionSummary executionSummaryCopy) {
       ExecutionSummary executionSummary = new ExecutionSummary();
       executionSummary.setProcessDefinitionId(executionSummaryCopy
       .getProcessDefinitionId());
       executionSummary.setLogin(executionSummaryCopy.getLogin());
       executionSummary.setWhenStarted(executionSummaryCopy.getWhenStarted());
       em.persist(executionSummary);
      
       return executionSummary;
       }
      
       /**
       * Implementation for persist process definition.
       *
       * @param user
       * the user information
       * @param definition
       * the process definition XPDL
       * @return the id of the persisted process definition
       */
       private long persistProcessDefinitionImplementation(User user,
       String definition) {
       ProcessDefinition pd = new ProcessDefinition();
      
       logger.debug("process def is: " + definition);
      
       try {
       pd = ProcessDefinitionDigester.digestPD(definition);
       logger.debug("pd is " + pd);
       List<TransitionReference> trList = pd.getTransitionReferences();
       pd.setTransitionReferences(null);
       StepDefinition startingStepDefinition = pd
       .getStartingStepDefinition();
       pd.setLogin(user.getLogin());
       pd.setStartingStepDefinition(null);
       em.persist(pd);
       pd.setTransitionReferences(trList);
       pd.setStartingStepDefinition(startingStepDefinition);
       em.persist(pd);
       } catch (EntityExistsException e) {
       logger.error("Cannot persist ProcessDefinition, entity exists", e);
       throw e;
       } catch (Exception e) {
       logger.error("An error occurred persisting ProcessDefinition", e);
       throw new RuntimeException(
       "An error occurred persisting ProcessDefinition");
       }
      
       return new Long(pd.getId());
       }
      
       /**
       * Implementation for remove execution.
       *
       * @param user
       * the user information
       * @param id
       * the ID of the exeuction to remove
      
       */
       private void removeExecutionImplementation(User user, long id) {
       try {
       Query deleteQuery = em
       .createNativeQuery("DELETE FROM RESULTING_PARAMS "
       + " WHERE EX_SUMMARY_ID IN "
       + " (SELECT S.ID FROM EXECUTION_SUMMARY S WHERE S.PD_ID = :first)");
       deleteQuery.setParameter("first", id);
       deleteQuery.executeUpdate();
      
       Query query = em
       .createNativeQuery("DELETE FROM EXECUTION_DETAIL "
       + "WHERE EX_SUMMARY_ID IN (SELECT ID FROM EXECUTION_SUMMARY WHERE PD_ID = :first)");
       query.setParameter("first", id);
       query.executeUpdate();
      
       query = em
       .createNativeQuery("DELETE FROM EXECUTION_SUMMARY WHERE PD_ID = :first ");
       query.setParameter("first", id);
       query.executeUpdate();
      
       } catch (Exception e) {
       logger.error("An error occurred while removing a running process.",
       e);
       throw new RuntimeException(
       "An error occurred while removing a running process.");
       }
       }
      
       /**
       * Implementation for remove process definition.
       *
       * @param user
       * the user information
       * @param id
       * the ID of the process definition to remove
       */
       private void removeProcessDefinitionImplementation(User user, long id) {
       try {
       logger.debug(" removing process definition for " + id);
      
       Query deleteQuery = em
       .createNativeQuery("DELETE FROM RESULTING_PARAMS "
       + " WHERE EX_SUMMARY_ID IN "
       + " (SELECT S.ID FROM EXECUTION_SUMMARY S WHERE S.PD_ID = :first)");
       deleteQuery.setParameter("first", id);
       deleteQuery.executeUpdate();
      
       Query query = em
       .createNativeQuery("DELETE FROM EXECUTION_DETAIL WHERE EX_SUMMARY_ID IN (SELECT ID FROM EXECUTION_SUMMARY WHERE PD_ID = :first)");
       query.setParameter("first", id);
       query.executeUpdate();
      
       query = em
       .createNativeQuery("DELETE FROM EXECUTION_SUMMARY WHERE PD_ID = :first ");
       query.setParameter("first", id);
       query.executeUpdate();
      
       query = em
       .createNativeQuery("DELETE FROM TRANSITION_DEFINITION WHERE TRANSITION_REFERENCE_ID IN (SELECT ID FROM TRANSITION_REFERENCE WHERE PD_ID = :first) ");
       query.setParameter("first", id);
       query.executeUpdate();
      
       query = em
       .createNativeQuery("DELETE FROM TRANSITION_REFERENCE WHERE PD_ID =:first ");
       query.setParameter("first", id);
       query.executeUpdate();
      
       query = em
       .createNativeQuery(" DELETE FROM STATE_DEFINITION WHERE ID IN (SELECT ID FROM STEP_DEFINITION WHERE PD_ID = :first)");
       query.setParameter("first", id);
       query.executeUpdate();
      
       query = em
       .createNativeQuery(" UPDATE PROCESS_DEFINITION set START_STEP_ID = NULL WHERE ID = :first");
       query.setParameter("first", id);
       query.executeUpdate();
      
       query = em
       .createNativeQuery(" DELETE FROM STEP_DEFINITION WHERE PD_ID = :first");
       query.setParameter("first", id);
       query.executeUpdate();
      
       query = em
       .createNativeQuery("DELETE FROM PROCESS_DEFINITION WHERE ID = :first ");
       query.setParameter("first", id);
       query.executeUpdate();
      
       logger.debug(" finishing remove");
      
       } catch (Exception e) {
       logger.error("An error occurred while removing ProcessDefinition.",
       e);
       throw new RuntimeException(
       "An error occurred while removing ProcessDefinition.");
       }
       }
      
       /**
       * Implementation for retrieve process definition.
       *
       * @param user
       * the user information
       * @param id
       * the ID of the process definition being retrieve
       * @return the process definition
       */
       private String retrieveProcessDefinitionImplementation(User user, long id) {
       ProcessDefinition pd = em.find(ProcessDefinition.class, id);
       if (pd == null) {
       return null;
       }
       return pd.getDefinition();
       }
      
       /**
       * Implementation for retrieve most recent process instance ID.
       *
       * @param user
       * the user information
       * @param pdId
       * process definition ID
       * @return ID for the most recently completed process instance ID
       */
       private long retrieveMostRecentProcessInstanceIDImplementation(User user,
       long pdId) {
       Query query = em.createQuery(
       "SELECT e.id from ExecutionSummary e "
       + "WHERE e.processDefinitionId = :pdId "
       + "AND e.whenCompleted is not null "
       + "ORDER BY e.whenCompleted DESC").setHint(
       "org.hibernate.readOnly", Boolean.TRUE);
       query.setParameter("pdId", pdId);
      
       List resultList = query.getResultList();
      
       long id = -1;
       if(resultList != null && resultList.size() > 0)
       {
       id = (Long) resultList.get(0);
       }
      
       return id;
       }
      
       /**
       * Implementation for retrieve process instance IDs.
       *
       * @param user
       * the user information
       * @param pdId
       * the process definition ID
       * @return IDs of all of the process instances related to the specified
       * process definition
       */
       private long[] retrieveProcessInstanceIDsImplementation(User user, long pdId) {
       Query query = em.createQuery(
       "SELECT e.id from ExecutionSummary e "
       + "WHERE e.processDefinitionId = :pdId").setHint(
       "org.hibernate.readOnly", Boolean.TRUE);
       query.setParameter("pdId", pdId);
      
       long[] ids = new long[query.getResultList().size()];
       int i = 0;
       for (Object resultObject : query.getResultList()) {
       long id = (Long) resultObject;
       ids[i++] = id;
       }
      
       return ids;
       }
      
       /**
       * Implementation for retrieve process instance status.
       *
       * @param user
       * the user information
       * @param id
       * the process instance ID
       * @return the execution summary
       */
       private ExecutionSummary retrieveProcessInstanceStatusImplementation(
       User user, long id) {
       logger.debug(" retrieving process instances with id = " + id);
      
       Query queryES = em.createQuery(
       "from ExecutionSummary e WHERE e.id = :first ").setHint(
       "org.hibernate.readOnly", Boolean.TRUE);
       queryES.setParameter("first", id);
      
       ExecutionSummary executionSummary = (ExecutionSummary) queryES
       .getSingleResult();
      
       Query query = em.createQuery(
       "SELECT e.id, s.id from ExecutionDetail e, StateDefinition s "
       + "WHERE e.executionSummaryId = :first "
       + "AND s.id = e.associatedStepId "
       + "AND s.actionMethod is not empty "
       + "AND s.actionMethod is not null "
       + "AND s.actionClass is not empty "
       + "AND e.completed = 1").setHint(
       "org.hibernate.readOnly", Boolean.TRUE);
       query.setParameter("first", id);
      
       List<ExecutionDetail> edList = new ArrayList<ExecutionDetail>();
       for (Object resultList : query.getResultList()) {
       Object[] result = ((Object[]) resultList);
       ExecutionDetail executionDetail = new ExecutionDetail();
       executionDetail.setId((Long) result[0]);
      
       String results = getResultingParams(executionDetail.getId());
       executionDetail.setResultingParams(ParamUtil.paramsAsXML(results,
       true));
       edList.add(executionDetail);
       }
       executionSummary.setExecutionDetails(edList);
       return executionSummary;
       }
      
       /**
       * Implementation for retrieve process instance status without step results.
       *
       * @param user
       * the user information
       * @param id
       * the process instance ID
       * @return the execution summary
       */
       private ExecutionSummary retrieveProcessInstanceStatusNoResultsImplementation(
       User user, long id) {
       logger.debug(" retrieving process instances with id = " + id);
      
       Query queryES = em.createQuery(
       "from ExecutionSummary e WHERE e.id = :first ").setHint(
       "org.hibernate.readOnly", Boolean.TRUE);
       queryES.setParameter("first", id);
      
       ExecutionSummary executionSummary = (ExecutionSummary) queryES
       .getSingleResult();
      
       Query query = em.createQuery(
       "SELECT e.id, s.id from ExecutionDetail e, StateDefinition s "
       + "WHERE e.executionSummaryId = :first "
       + "AND s.id = e.associatedStepId "
       + "AND s.actionMethod is not empty "
       + "AND s.actionMethod is not null "
       + "AND s.actionClass is not empty "
       + "AND e.completed = 1").setHint(
       "org.hibernate.readOnly", Boolean.TRUE);
       query.setParameter("first", id);
      
       List<ExecutionDetail> edList = new ArrayList<ExecutionDetail>();
       for (Object resultList : query.getResultList()) {
       Object[] result = ((Object[]) resultList);
       ExecutionDetail executionDetail = new ExecutionDetail();
       executionDetail.setId((Long) result[0]);
       edList.add(executionDetail);
       }
       executionSummary.setExecutionDetails(edList);
       return executionSummary;
       }
      
       /**
       * Implementation of start.
       *
       * @param user
       * the user information
       * @param id
       * the id of the process definition to start
       * @return the id of the execution summary of the started process
       */
       private long startImplementation(User user, long id) {
       ProcessDefinition pd = em.find(ProcessDefinition.class, id);
       StepDefinition startStep = pd.getStartingStepDefinition();
       if (startStep != null) {
       ExecutionSummary executionSummary = new ExecutionSummary();
       executionSummary.setProcessDefinitionId(pd.getId());
       executionSummary.setLogin(user.getLogin());
       executionSummary.setWhenStarted(new Date());
       executionSummary =
       persistExecutionSummary(executionSummary);
       logger.debug(" start state id is " + startStep.getId());
       WorkflowUtil.sendMessage(queueName, startStep.getId(), getUser(),
       executionSummary.getId());
       return executionSummary.getId();
       }
      
       return -1;
       }
      
       /**
       * Implementation for update process definition.
       *
       * @param user
       * the user information
       * @param id
       * the ID of the process definition
       * @param definition
       * the new process definition XPDL
       * @return the new process definition ID
       */
       private long updateProcessDefinitionImplementation(User user, long id,
       String definition) {
       try {
       removeProcessDefinition(id);
       long newId = persistProcessDefinitionImplementation(user,
       definition);
       return newId;
      
       } catch (EntityExistsException e) {
       logger.error("Error updating ProcessDefinition", e);
       throw e;
       } catch (Exception e) {
       logger.error("Error updating ProcessDefinition.", e);
       throw new RuntimeException("Error updating ProcessDefinition.");
       }
       }
      }
      


      The server.log is too large to post but a zip of it can be found at
      http://rabasrv.jhuapl.edu/server.log.zip[/url]

      So why is this exception being thrown? Is this a problem in my EJB code or in my JUnit client?