7
votes

I have a EJB defined as this:

package com.foo;
@Stateless (mappedName="HelloWorld")
public class HelloWorldBean implements HelloWorld, HelloWorldLocal
....

When it's deployed to Weblogic (WL), it gets the name myBean. I'm not sure if this is important.

I try to call the bean with this code:

Hashtable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL, "t3://localhost:7001");
ic = new InitialContext(ht);
tp = (HelloWorld) ic.lookup("HelloWorld#com.foo.HelloWorldBean");

Anyone know why I get the following error?

javax.naming.NameNotFoundException: While trying to lookup 'HelloWorld#com.foo.HelloWorldBean' didn't find subcontext 'HelloWorld#com'.
 Resolved '' [Root exception is javax.naming.NameNotFoundException: While trying
 to lookup 'HelloWorld#com.foo.HelloWorldBean' didn't find
 subcontext 'HelloWorld#com'. Resolved '']; remaining name 'HelloWorld#com/foo/HelloWorldBean'
1
Does your bean have multiple Remote Business Interface? - Pascal Thivent
Yes, the HelloWorld interface. Sorry for lame names. I'm trying to get familiar with EJBs. - Sajee
That's only one, not multiple :) I've answered both cases anyway. - Pascal Thivent
Not sure you were notified so I'm pasting my answer here: In @Stateless, @name() is the annotation equivalent of <ejb-name> in ejb-jar.xml. If no @Stateless name() is specified, it defaults to the unqualified bean class name. So I don't know from where "myBean" comes from. Then, yes, your EJB should definitely be visible in the JNDI tree as "HelloWorld" (the name you specified). Are you sure that the deployment went well and that your EJB is deployed? - Pascal Thivent
Yes, it appears my bean was deployed correctly. No errors from WL and the Deployment page in the Admin console shows the "MyBean" deployment of type "Library" having a state of "Active". - Sajee

1 Answers

10
votes

To lookup a Remote Interface of a Session Bean with multiple Remote Business interfaces (e.g.com.acme.FooBusiness1, com.acme.FooBusiness2), you need to lookup a name derived from the combination of the target ejb's global JNDI name (the mappedName() in @Stateless) and the specific Remote Business Interface, separated by a "#":

InitialContext ic = new InitialContext();
FooBusiness1 bean1 = (FooBusiness1) ic.lookup("FooEJB#com.acme.FooBusiness1");
FooBusiness2 bean2 = (FooBusiness2) ic.lookup("FooEJB#com.acme.FooBusiness2");

In the typical case of a bean only having one Remote Business Interface, this fully-qualified form is not needed. In that case, the bean's JNDI name can be used directly :

FooBusiness bean = (FooBusiness) ic.lookup("FooEJB");

That was the theoretical part. Now the practice. In your case, from what I can see, you are accessing the EJB from Weblogic so I'd rather use the no-arg InitialContext() constructor (and use a jndi.properties configuration file for other environments) but this is just a side note. Then, you should look up com.foo.HelloWorld, the Remote Interface, not com.foo.HelloWorldBean, the implementation:

InitialContext ic = new InitialContext();
(HelloWorld) ic.lookup("HelloWorld#com.foo.HelloWorld");

And if your bean has only one Remote Business Interface, this should work:

(HelloWorld) ic.lookup("HelloWorld");