Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface

I am currently reworking Chapter 12 for the SOA Suite 11g Handbook. This chapter describes various types of interaction SOA Composite Applications can have with Java applications and components. Since the initial creation of this chapter – some 6 months ago – we have had the Patch Set 2 release of the SOA Suite. This patch set introduced some additional functionality in this particular area of the SOA Suite, including the EJB Binding directly based on a Java Interface rather than on an SDO service created for the EJB. While that last option did the job, it requires manipulation of the EJB that is to be invoked – to SDO enable it – and that was undesirable and sometimes even impossible.

This article describes about the simplest way to get going with the EJB Binding – Java based – in Patch Set 2 (11.1.1.3.0). Building on this example, you will probably find yourself able to do useful things with it.

The steps we will go through are:

1. Create the EJB that is to be invoked from the Composite application through EJB Binding. Make sure the remote interface is created as well.
2. Deploy this EJB (in this simple example to the same WebLogic Managed Server that is running the SOA Suite)

3. Create a new SOA Composite Application
4. Copy the remote interface to the SCA-INF/src directory (or copy a JAR containing that interface to SCA-INF/lib)
5. Create an EJB Binding Reference. Configure it to invoke the EJB created and deployed above; specify the Java Interface that describes the interaction
6. Create a Mediator that is wired to the EJB Binding Reference; create mappings from the input and output of the Mediator to the XML structure derived by JDeveloper from the Java Interface definition
7. Finish the composite application; from here on it is ‘business as usual’ since none of the other components in the applications are aware that the Mediator talks to something ‘special’ like an EJB.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface wireMediatorToEJB

1. Create the EJB

Open JDeveloper. Create a new (generic) application. Call the application CalculatorApplication and the default Project Calculator. I set the application’s package prefix to nl.amis.calculator (though you can choose anything you like).

Open the New Gallery, select category EJB and click on item Session Bean.
Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface newSBSelectEJBVersion

The Create Session Bean dialog appears. On the first tab, select Enterise JavaBeans 3.0 as the EJB version.
Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface newSBSelectEJBVersion
On the EJB Name and options page, set the name to CalculatorEJB and the mapped name to Calculator-CalculatorEJB. This mapped name is used later on to locate the EJB when it is deployed.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface newSBName

On the next page, Class Definitions, accept the defaults.
Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface newSBClassDefs
Press Next.

On the page EJB Home and Component interface, check the checkbox for Remote Interface and set the name of the Interface to Calculator. Uncheck the checkbox for Local Interface.

Press Finish.

(note: the wizard is not adding an awful lot of value over simply creating the Interface and Class yourself, it is just a matter of a few annotations; so feel free to completely skip the wizard and create the Java objects manually).

Add the following method signature to the Calculator interface definition:

 public int add(int operand1, int operand2);

(heavy stuff going on here)

and provide the implementation of this method in the CalculatorEJB class:

 public int add(int operand1, int operand2) {
   return operand1 + operand2;
 }

The interface and class with appropriate annotations now becomes:

package nl.amis.calculator;

import javax.ejb.Remote;

@Remote
public interface Calculator {

 public int add(int operand1, int operand2);
}

and

package nl.amis.calculator;

import javax.ejb.Remote;
import javax.ejb.Stateless;

@Stateless(name = "CalculatorEJB", mappedName = "Calculator-CalculatorEJB")
@Remote
public class CalculatorEJBBean implements Calculator {
 public int add(int operand1, int operand2) {
 return operand1 + operand2;
 }

}

2. Deploy this EJB

The EJB in all its simplicity is complete – or at least ready for first deployment and testing. Right click the CalculatorEJB class and from the context menu select the option Create EJB JAR Deployment Profile.
Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface createDeploymentProfile

Specify the name for the deployment profile as CalculatorEJB_EJBProfile – or any other name you fancy.
Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface createDeploymentProfile2

Click OK and click OK again (twice) – accepting all defaults.

To actually deploy the EJB, right click the project in the navigator, click on the option Deploy and select the CalculatorEJB_EJBProfile from the submenu.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface deployEJB
The Deployment Wizard appears. Select Deploy to Application Server on the first page.

Select your Application Server connection to the WebLogic domain running the SOA Suite on the second page. On page three, select Managed Server soa_server1 as the deployment target. Make sure the radio button Deploy as standalone Application has been selected.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface deployEJB4Press Finish to commence deployment, or first inspect the summary on the next page and press Finish there.

Deployment is performed – preceded by compilation, build and package to EAR file.

2b. Test the EJB using a simple client application

If you like, you could test the EJB that was just deployed. Right click the CalculatorEJB Session Bean and select the menu item New Sample Java Client.

Click on the button New Project in the popup that appears.
Specify a project name, for example CalculatorClient. Press OK.

A CalculatorClient class is generated and subsequently opened in the Java Source editor. You need to make a change in the getInitialContext method. The PROVIDER_URL property is defined using port name 7001. However, since we selected the managed server soa_server1 – and not the default AdminServer, you may need to use a different port number. In my case the port number is 8001.

Next, add the following line of Java code to do at least something with the Calculator object the JNDI lookup retrieves for us:

System.out.println("The result of adding 21 and 21 is: "+calculator.add(21, 21));

Run the CalculatorClient and see the result coming in. This demonstrates that the EJB as deployed is accessible and doing it (trivial) job.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface testEJBwithSampleClient

3. Create a new SOA Composite Application

Create a new SOA application. In my case it is called EJBConsumer, as is the project. The template used is simply Empty Composite.

4. Make the Java Interface Calculator available to the Composite

Copy the remote interface Calculator to the SCA-INF/src directory (or copy a JAR containing that interface to SCA-INF/lib). Note: remove the @Remote annotation and the import of javax.ejb.Remote because otherwise the Java interface won’t compile.

5. Create an EJB Binding Reference.

Open the composite editor. Drag the EJB Service from the Service Adapters list on the Component Palette to the References lane.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface dragEJBBinding

The Create EJB Service dialog appears. Enter a name – for example CalculatorService. Type is Reference, Interface is Java (instead of WSDL). JNDI Name is Calculator-CalculatorEJB#nl.amis.calculator.Calculator, composed of the Mapped Name of the EJB and the interface describing the interaction. (note: this mapped name is used in the JNDI Lookup in the EJB Sample Client we created above in step 2b; you can copy it from there).

Browse for the Java Interface – nl.amis.calculator.Calculator. Press OK to complete the EJB Service definition.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface createEJBService

The composite editor appears with the EJB Binding Reference as expected.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface compositeWithEJBBinding

However: the Create EJB Service dialog is flawed! Even though everything seems to be correct, it is not so. When you try later on to wire a Mediator or another Service Component to this Reference, you will run into an Interface Conversion Error such as “Could not convert from java interface to interface type wsdl.Exception=nl.amis.calculator.Calculator”

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface interfaceConversionError

The problem is that the dialog upon completion did not write an attribute to the Reference definition. It created:

 <reference name="CalculatorService">
   <interface.java interface="nl.amis.calculator.Calculator"/>
   <binding.ejb uri="Calculator-CalculatorEJB#nl.amis.calculator.Calculator"
                ejb-version="EJB3"/>
 </reference>

and it should have created:

 <reference name="CalculatorService">
   <interface.java interface="nl.amis.calculator.Calculator"/>
   <binding.ejb uri="Calculator-CalculatorEJB#nl.amis.calculator.Calculator"
                javaInterface="nl.amis.calculator.Calculator"
                ejb-version="EJB3"/>
 </reference>

Go into the source view of the composite editor and add the atribute javaInterface:

 javaInterface="nl.amis.calculator.Calculator"

6. Create a Mediator that is wired to the EJB Binding Reference

First, create an XSD document – called Calculating.xsd – with the following element definition:

<schema attributeFormDefault="unqualified"
   elementFormDefault="qualified"
   targetNamespace="http://nl.amis.calculator"
   xmlns="http://www.w3.org/2001/XMLSchema">
   <element name="calculatorParameter">
     <complexType>
       <sequence>
         <element name="operand1" type="int" />
         <element name="operand2" type="int" />
       </sequence>
     </complexType>
   </element>
   <element name="calculatorResult">
      <complexType>
         <sequence>
            <element name="outcome" type="int" />
         </sequence>
      </complexType>
   </element>
</schema>

Next, drag a Mediator to the composite and drop it in the central area.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface addMediator

Set the name to CalculatorMediator.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface addMediator2

Select Template Interface Definition from WSDL and click on the generate icon after the WSDL URL field. The Request message is to be based on the calculatorParameter element in the Calculating.xsd schema definition. The Response message is based on the element calculatorResult.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface addMediator2b

Press OK. The Mediator configuration is as follows:

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface addMediator3

Press OK.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface addMediator4

Wire the Mediator to the CalculatorService EJB Binding.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface wireMediatorToEJB2

JDeveloper creates the WSDL based on the Calculator Java interface.

Click on the CalculatorMediator to bring up the editor and create mappings from the input and output of the Mediator to the XML structure derived by JDeveloper from the Java Interface definition.

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface mapMediatorToEJB

create the mapping:

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface mapMediatorToEJB2

and

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface mapMediatorToEJB3

7.Deploy and Test the Composite application

Finish the composite application; from here on it is ‘business as usual’ since none of the other components in the applications are aware that the Mediator talks to something ‘special’ like an EJB.

Deploy the composite application in the normal way. Now we can test the composite application with EJB binding from the FWM EM Console:

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface testCalc1

Set input:

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface testCalc2

and press the Test WebService button.

The response appears.:

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface testCalc3

The flow trace:

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface flowtrace

And the detailed audit overview for the Mediator:

Calling an EJB from a SOA Composite Application using the EJB Binding based on Java Interface mediatorAudit

5 Comments

  1. Souvik December 20, 2011
  2. David Tildesley November 24, 2011
  3. Mayank November 21, 2011
  4. Ivan December 20, 2010
  5. Markus Zehnder November 16, 2010