Apache ODE Process to Process Communication Issues

by Milinda Lakmal

When two different BPEL processes deployed in Apache ODE need to communication with each other, Apache ODE bypass the integration layer and directly talks to the process from another process. But we recently discovered that when one process is in-memory and other process is persisted, there will be a class cast exception when engine invokes the in-memory process in P2P manner from persisted process or other way around(in-memory process invokes persisted process).

This happens at the DAO layer. Even though data access layer was implemented using several abstraction level, this error cannot be handle by those abstractions. Here is the code fragment which handles Process to Process communication in ODEProcess class.

partnerRoleMex.setInvocationStyle(

Boolean.parseBoolean(

partnerRoleMex.getProperty(MessageExchange.PROPERTY_SEP_MYROLE_TRANSACTED))

? InvocationStyle.P2P_TRANSACTED

: InvocationStyle.P2P);

// Plumbing

MessageExchangeDAO myRoleMex = target.createMessageExchange(new GUID().toString(),

MessageExchangeDAO.DIR_PARTNER_INVOKES_MYROLE);

myRoleMex.setStatus(Status.REQ);

myRoleMex.setCallee(serviceName);

myRoleMex.setOperation(partnerRoleMex.getOperation());

myRoleMex.setPattern(partnerRoleMex.getPattern());

myRoleMex.setTimeout(partnerRoleMex.getTimeout());

myRoleMex.setRequest(partnerRoleMex.getRequest());

myRoleMex.setInvocationStyle(partnerRoleMex.getInvocationStyle());

// Piped cross-references.

myRoleMex.setPipedMessageExchangeId(partnerRoleMex.getMessageExchangeId());

myRoleMex.setPipedPID(getPID());

partnerRoleMex.setPipedPID(target.getPID());

partnerRoleMex.setPipedMessageExchangeId(myRoleMex.getMessageExchangeId());

setStatefulEPRs(partnerRoleMex, myRoleMex);

// A classic P2P interaction is considered reliable. The invocation should take place

// in the local transaction but the invoked process is not supposed to hold our thread

// and the reply should come in a separate transaction.

target.invokeProcess(myRoleMex);

The problem occurred when we trying to set the request to my role message exchange object. The request must be a implementation of MessageDAO interface. myRoleMex object returned from ODEProcess’s createMessageExchange method will depend on the persistence type of that process. If it’s a JPA based persisted process it’ll return a object of org.apache.ode.bpel.jpa.MessageExchangeDAOImpl class. When setting the request attribute of that class it’ll try to cast that object to org.apache.ode.dao.jpa.MessageDAOImpl. But the request generated from in-memory process is object of org.apache.ode.dao.memdao.MessageDAOImpl class, so that the class cast exception will be thrown. In this situation we can’t use in-memory implementation’s MessageDAO object with JPA based DAO implementation because annotations and some other details required for JPA will not be there in the in-memory DAO implementation.

So when there are process to process communication in you BPEL processes, users must  avoid deploying one process in-memory and other process persisted. If your processes are deployed in two different Apache ODE instances, this thing doesn’t have any effect.