Transaction propagation is the mechanism that allows transactions to be used across multiple application components. In general, transaction propagation is supported by Liberty and you do not need to modify Enterprise Java Beans (EJBs) that are running on WebSphere Application Server to make them run on Liberty.
However, if an application uses transaction propagation with remote interfaces (remote transaction propagation), you must wrap the EJBs in web services before deploying the application to Liberty. You then use the web service client to call the EJB web service. Liberty can then manage the transactions as distributed global transactions by using Web Service Atomic Transaction (WS-AT).
What is remote transaction propagation?
The following diagram illustrates two forms of remote transaction propagation:
- The client application calling a remote EJB from a different JVM.
- One EJB (EJB1) calling another EJB (EJB2) from a different JVM.
If the client application and the remote EJB that the client calls are both in the same JVM, or if the call is between two remote EJBs that are running in the same JVM, the call and transaction propagation are local. In these cases, the application can use transaction propagation on Liberty without any changes. This is the case for most applications.
If the transaction propagation is remote, you must modify the EJB and client applications before they can run on Liberty. It might be possible to migrate some of the applications, such as EJB1 and EJB2 in the diagram, to run in the same JVM so that calls between them are local, in which case only the client call into EJB1 would need to be addressed (and, if necessary, only EJB1 would be modified). Alternatively, you would modify both EJBs.
The recommended modification is to wrap each EJB in a web service and to use the web service client to call the EJB web service. You can then manage the transactions as distributed global transactions by using Web Service Atomic Transaction (WS-AT), which is supported by Liberty.
Later in this blog post are instructions on how to wrap an EJB in a web service. However, it is essential to first confirm that the application is actually using remote transaction propagation; it could be that remote interfaces were enabled by default in the application but not actually used, which is often the case.
How do I check if my application uses remote transaction propagation?
If you are certain that your application uses remote transaction propagation, see Modifying applications that require remote transaction propagation and follow the instructions to wrap the EJBs in web services to run your application on Liberty.
If you are not certain about whether your application uses remote transaction propagation but you think it might, read on.
Why might I think that an application uses remote transaction propagation?
If you run one of the WebSphere modernization tools (Migration Toolkit for Application Binaries, IBM Transformation Advisor, or Application Modernization Accelerator) against an EJB application, the tool typically flags up the rule Transaction propagation is not supported for Enterprise JavaBeans (EJB) remote interfaces
.
For example, the following screenshot shows the rule flagged up in Application Modernization Accelerator:

This can be for one of the following reasons:
- The default behavior for EJB 2.x beans is to enable remote interfaces in
ejb-jar.xml
to allow remote transaction propagation, even when they are not used. The modernization tools therefore flag applications that have a remote EJB interface, but that does not mean remote transaction propagation is in use by each application.
- CORBA information, such as an
iiop://
provider URL, is detected in an EJB lookup.
In most cases, applications do not use remote transaction propagation, even if they use remote EJBs.
There is no problem in the following situations:
- If the EJB remote interface is used between two applications installed in the same application server or JVM, transaction propagation is supported by Liberty.
- If the client is calling an EJB remote interface that has bean-managed transactions, transactions are never propagated, and the application works fine on Liberty.
- If the client is calling an EJB remote interface with the
NotSupported
transaction attribute, again, there is no propagation and the application works fine on Liberty.
- If the client is calling an EJB remote interface with the
Required
transaction attribute, this might work fine as long as the client does not actually start a transaction before calling the method.
So, it is likely that you do not need to do anything. But, if you are unsure whether your application is using remote transaction propagation, you can check by using trace.
Using trace to check if an application is propagating transactions via remote EJB interfaces
You can determine if transactions are being propagated on remote EJB calls by turning on trace in WebSphere Application Server. Trace is needed across several packages, so it is easiest just to turn on trace for EJB in general. This also provides better detail in complex scenarios.
Enabling and collecting trace
Enable the following trace setting:
*=info:EJBContainer=all
Then run various application scenarios to write the trace.
Next, we'll look at how to check whether a transaction is being propagated, then whether it has been called remotely.
Finding the relevant part of the trace log
After running various application scenarios, open the trace.log
file in an editor that supports regular expression filtering and use the following regex to search the log file:
EJBpreInvoke|preInvoke : p|Required |RequiresNew |NotSupported |Mandatory |Never |Supports |Began TX|Began LTC
A filtered file looks similar to the following screenshot:

Where:
EJBPreInvoke
tells you the name of the method called (in this example, the method name is findByPrimaryKey
).
WrapperManager preInvoke
indicates a remote method call. (If you don't see WrapperManager preInvoke
after EJBpreInvoke
, the call is a local method call and you can ignore it.)
- The EJB transaction attribute can be one of the following values:
BeanManaged
, Mandatory
, Never
, NotSupported
, Required
, RequiresNew
, Supports
.
Began TX
indicates that a new transaction was started for the EJB.
Identifying whether a remote transaction is being propagated
Work through the steps in the following flow diagram to analyze the trace and assess whether remote transactions are being propagated:

In summary, for each instance of EJBpreInvoke
that you find in the trace (labelled 1 in the flow diagram):
- If there is not then an instance of
WrapperManager preInvoke
, ignore it because it is a local call (2).
- If the transaction attribute is:
BeanManaged
, Never
, NotSupported
, or RequiresNew
, ignore it. Transactions are never propagated with these attributes.
- If the transaction attribute is:
Mandatory
, this requires transaction propagation and you need to make a code change to migrate the application (3).
- If the transaction attribute is:
Required
or Supports
, look for a Began Tx
trace. Began Tx
after Required
or Supports
means a transaction was not propagated, so you can ignore this method (4, 5).
So, of the various combinations, there are 3 scenarios that would indicate transaction propagation:
1 – Mandatory
(3)
2 – Required
, without a subsequent trace for Began TX
(4, 5)
3 – Supports
, without a subsequent trace for Began TX
(4, 5)
If you do find one of these 3 scenarios, a transaction is being propagated… but that is still not always a problem.
Checking whether the method has been called remotely
The final check is to verify that the method in question has indeed been called remotely by another EJB or servlet running on a different application server or JVM (7). It is only remote calls that need modification.
If you are having difficulty determining which EJB a method call is for, that information is logged immediately after the EJBpreInvoke
trace, and looks like this:
pinOnce: BeanId(RemoteServerApp#RemoteServerEJB.jar#TxAttrBean, null) Entry
It might be that you can change the remote interfaces to local interfaces.
Changing calls to use local EJB interfaces
If you find that applications are calling EJB beans using a remote interface but the beans are actually running in the same JVM, you can change the beans to use the local interface instead, which performs better anyway. Where this is possible, change annotations from @Remote
to @Local
and from @RemoteHome
to @LocalHome
and then test all your code scenarios. Likewise, for ejb-jar.xml
configuration, remove the <remote/>
and <business-remote/>
definitions and test all scenarios.
While Liberty does support transaction propagation for local calls (within the same JVM) to remote EJB interfaces, it is best practice to change them to use local interfaces to improve performance and to remove the perception that the methods can be called externally from the same JVM.
However, if you found that the remote interfaces are definitely called remotely, you need to make other changes to the EJBs.
Modifying applications that require remote transaction propagation
For those EJB beans that require remote access, you have the following options:
- Migrate the applications to run in the same JVM.
- Wrap the EJB beans in web services.
You might be able to change the applications (eg EJB1 and EJB2 in the first diagram at the beginning of this post) to run together in the same JVM. That way, you need only make modifications for the remote client call.
For any remote EJB beans that need to be called remotely, wrap each bean in a web service to run it on Liberty using remote transaction propagation. Liberty provides Web Services Atomic Transaction (WS-AT) support which enables distributed global transactions. When your EJBs are deployed as web services, WS-AT can be used to manage the transactions. See Web Services Atomic Transaction overview for more information. WS-AT is built on top of JAX-WS; for more information about developing JAX-WS applications from EJBs, see Developing JAX-WS web services (bottom-up).
Wrapping EJB beans in web services
Check the META-INF/ejb-jar.xml
file to find out which class implements the EJB. In the following example, the EJB implementation class is called hello.HelloEJBImpl
.
Open the EJB implementation class in an editor:
package hello;
...
import hello.HelloIF;
public class HelloEJBImpl implements SessionBean, HelloIF {
public String message = "Hello ";
private static String activateInfo;
private static String createInfo;
private static String passivateInfo;
...
Add the @WebService
annotation to the class. For example:
package hello;
...
import javax.jws.WebService;
import hello.HelloIF;
@WebService(
name = "HelloService",
serviceName = "HelloService",
targetNamespace = "http://hello/",
endpointInterface = "hello.HelloIF"
)
public class HelloEJBImpl implements SessionBean, HelloIF {
For your EJB to work properly as a web service, add the following attributes to the @WebService
annotation:
name
which specifies the name of the web service endpoint.
serviceName
which specifies the name of the web service.
targetNamespace
which specifies the namespace for the web service.
endpointInterface
which specifies the SEI (Service Endpoint Interface) that this implementation is exposing as a web service.
For example:
@WebService(
name = "HelloService",
serviceName = "HelloService",
targetNamespace = "http://hello/",
endpointInterface = "hello.HelloIF"
)
The endpointInterface
attribute is particularly important because it specifies that your service should use the HelloIF
interface as the service contract. This ensures that the WSDL generated for your web service will match the methods defined in that interface.
Without these attributes, the web service would still work but default values would be used for the service name and namespace. Also, the implementation class (not the interface) would be used to generate the WSDL, which might expose methods you don't intend to make public.
Finally, add the javax.jws.WebService
import. For example:
package hello;
...
import javax.jws.WebService;
import hello.HelloIF;
@Stateless(name="hello HelloIF")
@WebService(
name = "HelloService",
serviceName = "HelloService",
targetNamespace = "http://hello/",
endpointInterface = "hello.HelloIF"
)
public class HelloEJBImpl implements SessionBean, HelloIF {
After wrapping the EJB bean in a web service, deploy the web service to Liberty so that you can use the web service client to call the EJB web service. As a Web Service EJB, the HTTP endpoint of the service is now published as a URL that can be used to invoke the web service. You must now modify the EJB client to be a JAX-WS client so that it can call the JAX-WS (web service) endpoint.
Modifying the client code
To modify the client code that calls the HTTP endpoint of the EJB web service, you need a valid WSDL document. A WSDL is a contract for the web service and describes what the web service can do and how to call it, including the parameters you can use. When you deploy the EJB web service, a WSDL is generated for you; you can then use that WSDL to generate your client code (see Developing a JAX-WS client from a WSDL file). Alternatively, you can generate the WSDL using WebSphere's wsgen
command.
Replace the EJB client code with the JAX-WS client code. Deploy and test your code.
WS-AT can now manage the transactions when the application runs on Liberty.
Cleaning up your EJB code
After testing, you can remove the EJB remote annotations or configuration, including:
- In
HelloIF.java
- Remove the
extends
part of the interface declaration.
For example public interface HelloIF extends java.rmi.Remote
would become public interface HelloIF
.
- Remove the
throws
statement.
For example throws java.rmi.RemoteException
- In
ejb-jar.xml
Conclusion
Remote transaction propagation in remote EJBs is often not required by applications, even when configured. In those cases, there is no problem running the application on Liberty. For applications that you find do propagate transactions remotely, you can wrap the EJBs in web services and then Liberty can support the transactions for the application through its support for distributed global transactions.
Related information