3

I have a following situation:

  1. Client is calling Stateless local EJB - managed transaction begins with this invocation
  2. Local EJB builds InitialContext and looks up remote EJB
  3. Local EJB invokes method on remote EJB
  4. Local EJB closes context and connection to remote EJB
  5. Container tries to commit transaction

Distributed transaction cannot be committed because connection to remote EJB that was taking part in transaction cannot be contacted because connection to it is closed.

My question is: Is it possible to use remote EJB calls when there already is a transaction active? How should I close context that was used to look up remote EJB?

Following pseudo code illustrates my issue:

@Stateless
public class LocalEjb {

  public void localEJBMethod() {
    //transaction starts before this method execution

    Context ctx = //create initial context
    RemoteEjb remoteEjb = (RemoteEjb) ctx.lookup("jndi name");
    remoteEjb.remoteMethod(); //remote EJB takes part in distributed transaction
    ctx.close();    

    //error occurrs when container tries to commit distributed transaction after
    //this method returns
  }
}


public class ClientClass { //a CDI component, for example
    @EJB
    private LocalEjb localEjb;

    public void clientMethod() {
        localEjb.localEjbMethod();
    }
}
povder
  • 187
  • 1
  • 12

1 Answers1

0

The transaction will work because the application servers use XA (distributed) transactions.

get rid of the ctx.close()

it is not actually closing the connection to the remote ejb (that is handled by the dynamic proxy object) you are closing access the JNDI context, which contains the handle for the transaction manager.

Remember as well that you need to let the container know that you are using another EJB. all the container managed objects need to declare their resource needs (ejbs, datasources, etc) to the application server. In the example about you would put your declaration in the ejb-jar.xml.

You might consider using the @EJB annotation for the remote EJB rather than an explicit lookup. this will declare the resource use to the application server and it will manage the reference for you.

Chris
  • 194
  • 6