Thursday, September 1, 2011

Using the EJB adapter in SOA Suite 11g

In Oracle SOA Suite 11g you can use the EJB adapter to expose a Remote interface as a Service or use it in a Reference Service.  From PS2 you only need to have an interface jar for the EJB adapter. The interface jar only contains the entities and the Session Bean interfaces (local and remote ) and does not contains the bean or the persistence unit.  Off course you can still generate an SDO interface on the EJB Session and use that in the EJB adapter like I did in this blogpost but this is not necessary.

In this blogpost I will focus on how to use the EJB adapter as a reference service. With this you can think of replacing your database adapters.  Off course you can make some composites in which you expose some database adapters for optimal reuse but maybe it is easier to use an EJB Session Bean deployed on a model tier which can cache your data, is cluster aware and can be also used by your Java (Web) applications.

We start by dropping an EJB adapter on the reference side of the composite.  Lookup the interface jar and provide the remote interface class. Add some text to the JNDI Name, we need to delete this entry and replace it with the right value ( a jdeveloper bug)

Choose for the JAVA interface else you need to have an EJB Session Bean with a SDO interface.

After the creation of the EJB adapter you can select the adapter and optional add some properties( in the property window ) like the java.naming.provider.url in case when the EJB Session Bean is not deployed on the SOA Suite server.

Now go the source mode of your composite where we fix the JNDI url. Delete the uri attribute of the binding.ejb element.

Now we need to add the JNDI name of your EJB Session Bean to the ejb binding. You can select the binding.ejb element and add the jndi url in the property window.

It need to have the jndiName attribute and not the uri attribute.


That's all for the EJB adapter but to use it in a Service Component we need to follow the rules of exposing a java class as a web service. The bottom up approach with JAX-WS like I describe in this blogpost. This is also necessary when you use the EJB transport in the OSB.

We start with the Remote Interface of the EJB Session bean. With the JAX-WS annotations like WebParam, WebMethod or WebResult we can control and influence the WSDL generation.  This WSDL will be used by the Service Components.

If we don't do this you will get arg0 as argument name and return as Response element.

With JPA you can have a reference entity attribute between two entities. For example the employee entity has a department attribute and department has a collection of employees. With this you can create a loop in loading employee and department entities. JPA don't allow this and you can control it with eager of lazy loading.
For JAX-WS and the EJB adapter you need to decide where you want to stop this loading by adding the XmlTransient attribute to a getter. So in this example you can add this to the getDepartment method of the employee entity or add this to the getEmployees of the department entity.


In the WSDL you can see that the employee does not have the department element.

The last important thing is, to avoid the use of java.util.Date, Timestamp or java.sql.Date. This will be ignored by the EJB adapter. You need to use Calendar as java type.

11 comments:

  1. Hi there, thanks for the cool article. I have a question im hoping you can help me with, I am using the same idea you have on this blog post, EJB Adapter with my remote interface in the jar annotated with WebService, Webparam and WebMethod. Instead of using JPA i am merely returning a POJO with String fields in it. Upon testing this service I get a :

    Failed to convert Java payload to XML, and another message saying :

    A descriptor class was not found in the project.

    Any chance you could help with this ??

    Many thanks for your time... :-)

    ReplyDelete
  2. Hi,

    are you using a session bean and deployed this on a server. Does it work with the EJB session client.

    And on the soa suite side you need a jar without the bean and only with the remote interface and the java pojo.

    hope this helps

    thanks Edwin

    ReplyDelete
  3. Hi, thanks for your reply :-)

    Yes i use a stateless session bean thats already been deployed to my soa_server1. I have also tested it using a client too. I've even put a logger on the EJB and tailed it when i test the SOA app calling this EJB. The EJB gets called and completes it operation but the issue is with the Mediator. It seems the mediator cannot pass the payload back to the service that called it, ie, the exposed webservice.

    I have not copied a jar with the remote interface and pojo but rather copied the source across(both remote interface and pojo).

    This is what i see in weblogics test console page when testing :

    No mapping found for class .

    Failed to convert Java payload to XML. Exception follows. [Interface= Method=

    Got an exception: java.lang.NullPointerException

    Null interface type ;default;

    Anything else you might think is the matter ?

    Many many many thanks... just about pulling teeth right now :-p

    ReplyDelete
  4. Hi Edwin, Ive checked your github examples and dont find this specific example... any chance you can commit this example you ve shown here ? Maybe that way i can see where im going wrong... anyways thanks again...

    ReplyDelete
  5. Hi,

    here we go, you need to update the server names in the initial contexts

    Deploy the ejb to the soa server ( it need the jdbc/hrDS datasource ) , generate the interface jar , add this jar to soa composite and change the jndi name on the reference in the composite.xml

    https://github.com/biemond/soa11g_examples/tree/master/SoaEjbReference

    thanks

    ReplyDelete
  6. Hi Edwin, wow thanks :-)

    Ok, the ejb is deployed, the client gets all departments and employees, all is dandy here :-) ... although when i invoke using the Weblogic Test page on the admin console i get pretty mcuh the same as what i do on my own examples... which is :

    No mapping found for class nl.whitehorses.soa.model.hr.services.HrModelSessionEJB.

    Im terribly sorry to disturb and waste your time, but alas all examples of this technology leads to your blog page... :-p sowwy...

    Anyways any help will be appreciated here.. I see in your example you have both an exposed EJB and exposed webservice to get the employees name. This is actually do-able with me too, i can return a string but once i return a complex type (Bean with strings and ints and whatever) this is where i get the issues...

    Can i commit my example ?? can you work your magic on it and see what stupid thing i have left out ??

    Anyways, hoping your well... :-)
    take care

    ReplyDelete
  7. Hi,

    ok

    although when i invoke using the Weblogic Test page on the admin console i get pretty mcuh the same

    are you testing in the wls console or the soa in the EM application

    you have both an exposed EJB and exposed webservice to get the employees name. This is actually do-able with me too

    Ok you don't soa just an ejb which is also exposed as a web service.

    like I do here http://biemond.blogspot.com/2011/08/expose-your-session-bean-with-jax-ws.html


    thanks

    ReplyDelete
  8. Hi there,

    ok i am testing using the EM application to test the SOA project. The EJB is fine, the client invoking is fine too :-)

    the issue is when i use SOA to return a complex type object from the ejb (for example return a Employee domain object instead of a string), like a pojo.. i have changed your example a tad so that it returns me complex type object / user defined object instead of a string. This is where i have an issue. I can only think that the issue is maybe a namespace issue or something in my xsd that maybe incorrect, dont know though...

    thanks for the above example anyways... :-)

    ReplyDelete
  9. Hi,

    Can you send your example to biemond at gmail dot com

    Then I can take a look.

    Thanks

    ReplyDelete
  10. Hi Edwin.

    Thank you, your example works using BPEL instead of a mediator.

    Thanks again :-)

    ReplyDelete
  11. Hi,
    How can I create an interface jar for the EJB adapter to start this workshop?

    thx

    ReplyDelete