tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Blevins <david.blev...@visi.com>
Subject Re: Service locator problem while EJB lookup ...
Date Sat, 03 May 2008 19:59:39 GMT

On May 2, 2008, at 10:19 PM, ManojS wrote:

>
> Hi,
>
> I have an issue while looking up an EJB using service locator  
> pattern. I
> have a "ServiceLocator" class which is being used everywhere in my  
> code to
> lookup any EJB. But now when I use openEJB (version 3.0) it is  
> throwing a
> "javax.naming.NamingException" with message, "Name  
> GenConfigFacadeEJB not
> found".
>
> My service locator class is as follows:
> //imports I removed for here ...
> public class ServiceLocator {
> 	private static Context context = null;
> 	static {
> 		System.setProperty( javax.naming.Context.INITIAL_CONTEXT_FACTORY,
> "org.openejb.client.LocalInitialContextFactory");
> 		System.setProperty( javax.naming.Context.URL_PKG_PREFIXES,
> "org.openejb.client" );
> 		context =  new InitialContext();
> 	}

It's likely that the vm has already pulled and cached the value of  
INITIAL_CONTEXT_FACTORY, it looks for the default only once and is  
probably pointing to Tomcat.  If the NameNotFoundException stack trace  
doesn't show any openejb classes, this is definitely what happened.

Best bet is to construct your InitialContext like so:

   static {
       Properties p = new Properties();
       p.setProperty( javax.naming.Context.INITIAL_CONTEXT_FACTORY,
                      "org.openejb.client.LocalInitialContextFactory");
       context =  new InitialContext(p);
   }

I left the URL_PKG_PREFIXES property out as I know that one is pulled  
and cached very early in startup and Tomcat owns the "java:" prefix,  
which is good.

That should fix the issue.

I like your service locator approach.  Some recommendations for you on  
that.

updated openejb-jar.xml:

   <?xml version="1.0" encoding="UTF-8"?>
   <openejb-jar>
     <properties>
       openejb.deploymentId.format = {ejbName}
       openejb.jndiname.format = {deploymentId}/{interfaceClass}
     </properties>
   </openejb-jar>

updated service locator using generics:

     public static <T extends EJBHome> T getEJB(String ejbName,  
Class<T> homeClass) throws NamingException {
         Object objref = null;
         try {
             objref = context.lookup(ejbName + "/" +  
homeClass.getName());
         } catch (NamingException e) {
             objref = context.lookup("java:comp/env/" + ejbName);
         }
         T home = (T) PortableRemoteObject.narrow(objref, homeClass);
         return home;
     }

then it can be used with no cast as:

     GenConfigFacadeHome home =  
ServiceLocator.getEJB("GenConfigFacadeEJB",GenConfigFacadeHome.class);


Reason for the updated openejb.jndiname.format is that you have two  
interface one local and one remote and with the format set to  
{deploymentId} only one interface will be bound.  Since your locator  
uses ejbName and home interface class, using the same pattern in your  
jndiname.format has advantages.

The updated getEJB method signature with <T extends EJBHome> is  
identical to having the method return EJBHome, which is why I left it  
that way when making it generic.  But, if you yank the "extends  
EJBHome" you can use the same method to lookup your EJBLocalHome  
interaces as well.  So that'd be:

     public static <T> T getEJB(String ejbName, Class<T> homeClass)  
throws NamingException {...}


-David







Mime
View raw message