Session beans are defined by the Java Enterprise Edition specification. They are divided into stateless and stateful beans. A stateless session bean operates on the operation level. This means that after the operation is executed, the state of the session bean is not preserved. On the contrary, stateful beans preserve state across a multi-operation level.
This recipe will explain how to call a session bean operation from the Java Embedding activity from the BPEL process.
To complete the recipe, we will create a project in JDeveloper and a session bean that will act as exchange money operation on ATM. The session bean will calculate how much money the customer will get, based on the amount of money inserted into ATM, exchange rate of the currency, and deduced fee.
ExchangeATM
. Right-click on the project node and select the New… option. Select the Session Bean (EJB) option from the New Gallery window.org.packt.ejb.atm.ExchATM_EJB
.Now we have the session bean created in the JDeveloper project. We have to add the code to perform the calculation and deploy it to the WebLogic server.
public double exchangeMoney(double originalAmount, String currency);
public double exchangeMoney(double originalAmount, String currency) { double fee= 0.95; //5 % double rate= ((Double)rates.get(currency)).doubleValue(); double excMoneyNoFee= originalAmount * rate; double excMoneyWFee= excMoneyNoFee * fee; return excMoneyWFee; }
The following steps will explain how to achieve this:
<element name="process"> <complexType> <sequence> <element name="input_date" type="date"/> <element name="atm_amount" type="double"/> <element name="atm_curr" type="string"/> </sequence> </complexType> </element>
<element name="processResponse"> <complexType> <sequence> <element name="day_of_date" type="string"/> <element name="exchangeMsg" type="string"/> </sequence> </complexType> </element>
BPEL_and_Java_2_0
process. Insert another Java Embedded activity and name it Java_ATM
.String input_amt= ((oracle.xml.parser.v2.XMLElement)getVariableData("inputVariable","payload","/client:process/client:atm_amount")).getTextContent(); String input_curr= ((oracle.xml.parser.v2.XMLElement)getVariableData("inputVariable","payload","/client:process/client:atm_curr")).getTextContent();
double dbl_amt= Double.parseDouble(input_amt);
java.util.Hashtable env = new java.util.Hashtable(); // WebLogic Server 10.x connection details env.put( javax.naming.Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory" ); env.put(javax.naming.Context.PROVIDER_URL, "t3://localhost:7001"); javax.naming.Context context = new javax.naming.InitialContext( env );
Object obj= context.lookup("ExchangeATM_EJB#org.packt.ejb.atm.ExchATM_EJBRemote");
if (obj != null) { org.packt.ejb.atm.ExchATM_EJBRemote atmBean= (org.packt.ejb.atm.ExchATM_EJBRemote)obj; double exchMoney=atmBean.exchangeMoney(dbl_amt, input_curr); setVariableData("outputVariable", "payload", "/client:processResponse/client:exchangeMsg", "ATM gives back " + exchMoney + " EUR."); }
We lookup EJBs (Enterprise JavaBeans) through Java Naming and Directory Interface (JNDI). We have access to the JNDI from the Java Embedding activity. Unfortunately, the JNDI of the BPEL process is connected to the BPEL cube instance and EJBs are registered into the Oracle WebLogic server. That is why we have to set up the JNDI environment manually and address EJBs through our own JNDI context.
To learn more on JNDI and RMI, the following resources are available:
Through the JNDI we receive a link to the remote interface of the EJB. Based on the interface definition, we are able to call the methods on the EJB.
There is also another possibility for calling the EJB from the BPEL process and that is through a Spring component. We can develop the Spring component that calls the EJB. In the SCA composite we than add the Spring component and link it with the BPEL process.