With the recent (April 2010) SOA Suite 11g R1 Patch Set 2 (11.1.1.3.0), several new capabilities have been added to the SOA Suite. One these is the EJB Binding. Or rather, an enhanced version of this binding. In previous releases, this binding was available to provide interaction with SDO enabled EJBs – based on a WSDL interface and XML messages. The PS2 release added full Java support to the EJB binding. This means that we do not have to concern ourselves with WSDL and XSD that maps to the Java interface we want to invoke or expose, nor with sending a XML based payload when we invoke the composite service. All we need is the Java interface that describes either the EJB that we want to invoke (for an EJB Binding Reference) or that we want to expose (for an EJB Binding Service).
Steps:
1. Create Composite like always
2. Create a Java Interface (and possibly Java domain classes or bean types describing the structure of the input and ouput of the methods on the EJB (that should correspond with the operations available in the Composite application)
package nl.amis.utilities; public interface FilterAndTranslate { public String translate(String input); }
Note: steps 1 and 2 can be reversed; especially when you want to work according to the contract (or design) driven approach, that would probably be best.
Note: thusfar I have only been successful with a Java interface that only uses simple types (my own domain objects and beans prevented deployment of the EJB for some reason)
3. Create an EJB Binding in the Services lane, based on this Java interface. Specify the JNDI Name for this EJB. For example: FilterAndTranslateEJB
go to the source of the composite.xml to add the javaInterface attribute that is not set by the wizard.
<service name="FilterAndTranslateEJB"> <interface.java interface="nl.amis.utilities.FilterAndTranslate"/> <binding.ejb uri="FilterAndTranslateEJB" ejb-version="EJB3" javaInterface="nl.amis.utilities.FilterAndTranslate"/> </service>
4. Create a Mediator to connect the EJB Binding to the ‘rest of the composite application
When this wire is added, JDeveloper will create a WSDL for the inbound EJB Binding.
Create the mappings in the Mediator for request and response message
5. Deploy the Composite application again
6. When successfully deployed, the EJB with the specified JNDI name will be listed in the JNDI Tree in the WebLogic Administration Console
7. Create a Java application that invokes the Composite Service through its (remote) EJB interface
An example of the code that you can use for this (note: add the Library WebLogic 10.3 RemoteClient to the project) :
package nl.amis.soasuite.ejb.client; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import nl.amis.utilities.FilterAndTranslate; // the interface describing the service public class RemoteSOAServiceClient { public static void main(String [] args) { try { final Context context = getInitialContext(); FilterAndTranslate filterAndTranslate = (FilterAndTranslate)context.lookup("FilterAndTranslateEJB"); System.out.println("The result of filtering and translating hello world is : "+filterAndTranslate.translate("hello world")); } catch (Exception ex) { ex.printStackTrace(); } } private static Context getInitialContext() throws NamingException { Hashtable env = new Hashtable(); // WebLogic Server 10.x connection details env.put( Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory" ); env.put(Context.PROVIDER_URL, "t3://localhost:8001"); return new InitialContext( env ); } }
When this code is run:
The result is retrieved from the SOA Composite Service FilterAndTranslate that exposes an EJB Binding. The Message Fow Trace:
The Mediator Audit trace: