Friday, 27 May 2011

Using EJB3 Annotations with Weblogic 10.3 / 11g

It seems to me that BEA and now Oracle are usually behind the curve when it comes to implementing the latest JEE specifications and often interpret things rather differently to the guys working on the Glassfish reference implementation.

A case in point is the need to use both the name and mappedName attributes with both the @Stateful, @Stateless and @MessageDriven EJB3 annotations. This means that your EJB or MDB will not be portable across servers; however, I know that this quibble isn’t usually a problem as the vast majority of organisations don’t ask you to write code that runs on more than one server.

The name attribute, which specifies the names of the bean is common across platforms; however, in the Weblogic world, the mappedName refers to the bean’s JNDI name, but it’s not the whole JNDI name only a part of it. Let me explain a little further using the wine search example that I’ve used in previous blogs. If I wrote a wine search services as an EJB, and I wanted to name the bean WineSearchFacade and give it a mapped name of WineSearch, then my class defintion would be:

@Stateless(name = "WineSearchFacade", mappedName = "WineSearch")
public class WineSearchFacadeBean implements WineSearchFacade, WineSearchFacadeLocal { etc.

This is all good and fine, I could then compile, test and package the code into an EAR and deploy it on my Weblogic server.

Having deployed the code, I now need to write some client code to test out the deployment. You may think that this would be straight forward and that all my client code would need to do would be to lookup a bean with the JNDI name of WineSearch, but this isn’t the case as it turns out that the full JNDI name of your EJB is:

mappedName#interface-name

where the interface name is the fully qualified name of the business interface of the bean. Therefore, for my wine search EJB, the Weblogic full JNDI name would be:

WineSearch#marin.tips.ejb3.stateless.winesearchcommon.WineSearchFacade

and the client code would look something like this:

    WineSearchFacade instance = (WineSearchFacade) ctx
    .lookup
("WineSearch#marin.tips.ejb3.stateless.winesearchcommon.WineSearchFacade");

    WineList result = instance.wineSearch
(WineCountry.FRANCE);

No comments: