I am working on the solace integration with WebSphere Liberty using ejb 2.x as the project is written based on ejb 2.X. I found lot of examples which uses the solace resource adapter with ejb 3 but couldn't find any example using ejb 2.x.
Can someone help me here to configure the solace resource adapter using ejb 2 (i.e configuration in ejb-jar.xml, ibm-ejb-jar-bnd.xmi, server.xml files) in WAS liberty.
Since EJB 3.x continues to support all the EJB 2.x APIs, it may not be difficult to upgrade your application. In ejb-jar.xml
, you would just need to update the top of the file from 2.x to 3.x and everything else remains the same. Where things get tricky is if you have extensive configuration in ibm-ejb-jar-bnd.xmi
and/or ibm-ejb-jar-ext.xmi
, as those both need to be converted to the newer XML equivalents. The advantage to upgrading is that EJB 3.x tends to need much less XML configuration and you can take advantage of injection, which is used in the Solace example.
However, if you would like to stick with EJB 2.x, then much of the existing Solace example is still applicable, you just need to convert the annotations to XML, add in the missing EJBLocalHome interface, and then perform JNDI lookups instead of injection. So, assuming you start with this Solace EJB 3.x example, then you need to convert @MessageDriven
to message-driven
, @Stateless
to session
, @EJB
to ejb-local-ref
and @Resoruce
to resource-ref
and resource-env-ref
. And finally, perform JNDI lookups of those references in place of injection.
Since modifying an existing EJB 2.x application can be tricky if you are not using the original tooling, I've provided the following key pieces of configuration for what the Solace EJB 3.x example would look like for EJB 2.x:
First, everything in server.xml
would remain the same.
Second, the ejb-jar.xml
for the two beans in the Solace example would look something like this:
<message-driven id="MessageDriven_1050954917281">
<ejb-name>ConsumerMDB</ejb-name>
<ejb-class>com.xxx.yyy.ConsumerMDB</ejb-class>
<transaction-type>Bean</transaction-type>
<ejb-local-ref id="EJBLocalRef_1037123589807">
<ejb-ref-name>ejb/Producer</ejb-ref-name>
<ejb-ref-type>Stateless</ejb-ref-type>
<local-home>com.xxx.yyy.ProducerHome</local-home>
<local>com.xxx.yyy.Producer</local>
<ejb-link>ProducerSB</ejb-link>
</ejb-local-ref>
</message-driven>
<session id="Session_1051542150766">
<ejb-name>ProducerSB</ejb-name>
<local-home>com.xxx.yyy.ProducerHome</local-home>
<local>com.xxx.yyy.Producer</local>
<ejb-class>com.xxx.yyy.ProducerSB</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Bean</transaction-type>
<resource-ref id="ResourceRef_101">
<res-ref-name>myCF</res-ref-name>
<res-type>avax.jms.ConnectionFactory</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<resource-env-ref id="ResourceEnvRef_102">
<resource-env-ref-name>myReplyQueue</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
</resource-env-ref>
</session>
The EJB 3.x example annotations have been mapped to their XML equivalents, and then the ProducerHome
interface has been added. The EJB 3.x example does not provide the Producer
interface, though shows it being injected into the MDB; a no-interface view was probably intended, but a Producer
interface is required for EJB 2.x.
Be aware that the id
values in ejb-jar.xml
are important for EJB 2.x, as they are used to link elements with the corresponding elements in ibm-ejb-jar-bnd.xmi
.
Third, the ibm-ejb-jar-bnd.xmi
file is needed to bind the references to the resources declared in server.xml, which would look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<ejbbnd:EJBJarBinding xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ejbbnd="ejbbnd.xmi" xmlns:commonbnd="commonbnd.xmi" xmlns:ejb="ejb.xmi" xmlns:common="common.xmi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmi:id="ejb-jar_ID_Bnd" currentBackendId="DB2UDBNT_V72_1">
<ejbJar href="META-INF/ejb-jar.xml#ejb-jar_ID"/>
<ejbBindings xmi:type="ejbbnd:MessageDrivenBeanBinding" xmi:id="MessageDrivenBeanBinding_1" activationSpecJndiName="JNDI/J2C/AS">
<enterpriseBean xmi:type="ejb:MessageDriven" href="META-INF/ejb-jar.xml#MessageDriven_1050954917281"/>
<ejbRefBindings xmi:id="EjbRefBinding_1037123589787" jndiName="java:module/ProducerSB!com.xxx.yyy.ProducerHome">
<bindingEjbRef href="META-INF/ejb-jar.xml#EJBLocalRef_1037123589807"/>
</ejbRefBindings>
</ejbBindings>
<ejbBindings xmi:id="EnterpriseBeanBinding_1037123589767" jndiName="ejb/ProducerSBHome">
<enterpriseBean xmi:type="ejb:Session" href="META-INF/ejb-jar.xml#Session_1051542150766"/>
<resRefBindings xmi:id="ResourceRefBinding_1" jndiName="JNDI/J2C/CF">
<bindingResourceRef href="META-INF/ejb-jar.xml#ResourceRef_101"/>
</resRefBindings>
<resourceEnvRefBindings xmi:id="ResourceEnvRefBinding_1" jndiName="JNDI/J2C/Q/replies">
<bindingResourceEnvRef href="META-INF/ejb-jar.xml#ResourceEnvRef_102"/>
</resourceEnvRefBindings>
</ejbBindings>
</ejbbnd:EJBJarBinding>
The syntax is a bit more complicated than the newer ibm-ejb-jar-bnd.xml
in the EJB 3.x example, but basically it is mapping the references declared in XML to the jndi names of the resources in server.xml
, whereas the EJB 3.x example is mapping the references declared via annotations to the jndi names of the resources in server.xml
Finally, the code from the EJB 3.x would be very similar for an EJB 2.x implementation, except the beans needs to implement javax.ejb.MessageDrivenBean
and javax.ejb.SessionBean
, etc. Then, in the ejbCreate()
methods, they would perform JNDI lookups (since there is no injection):
sbHome = (ProducerHome)new InitialContext().lookup("java:comp/env/ejb/Producer");
sb = sbHome.create();
myCF = (ConnectionFactory)new InitialContext().lookup("java:comp/env/myCF");
myReplyQueue = (Queue)new InitialContext().lookup("java:comp/env/myReplyQueue");