Jboss AS 6 - How to find an EJB via JNDI
ziggy25 Dec 20, 2011 11:12 AMI am trying out a simple EJB 2.1 HelloWorld using Jboss AS 6. I created an EJB jar file with the following structure:
HelloWorldEjb
|-ex1
|-ejb21
|-ejb.jar.xml
|-Hello.java
|-HelloBean.java
|-HelloHome.java
|-HelloLocal.java
|-HelloLocalHome.java
I also created a client standalone java class to test the above ejb. I deployed the jar file using the Jboss 6 admin console under Applications > EJB2 jars and clicked on "Add new resource". When i add the jar file it gives me this message so i assume it was deployed correctly.
Resource HelloWorldEjb.jar created successfully!
Now when i run the client i get this error:
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
javax.naming.NameNotFoundException: HelloHome not bound
at org.jnp.server.NamingServer.getBinding(NamingServer.java:771)
at org.jnp.server.NamingServer.getBinding(NamingServer.java:779)
at org.jnp.server.NamingServer.getObject(NamingServer.java:785)
at org.jnp.server.NamingServer.lookup(NamingServer.java:443)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
at java.lang.Thread.run(Thread.java:619)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
at org.jnp.server.NamingServer_Stub.lookup(Unknown Source)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:728)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:688)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at client.HelloClient.main(HelloClient.java:58)
Exception in thread "main" java.lang.NullPointerException
at client.HelloClient.main(HelloClient.java:72)
Initially i thought that i had to configure the JNDI resource for which the client will use to connect to find the EJB on the application server. Is this not necessary? The example i am using is using the EJB name in the lookup statement. Here is the section of the client code for making the connection. :
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory" );
env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
env.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");
//env = new InitialContext(env);
InitialContext ctx = null;
try {
ctx = new InitialContext(env);
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object obj = null;
try {
obj = ctx.lookup("HelloHome");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HelloHome home = (HelloHome) javax.rmi.PortableRemoteObject.narrow(obj, HelloHome.class);
And here is the ejb-jar.xml file
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instalce"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"
version="2.1">
<enterprise-beans>
<session>
<ejb-name>HelloWorldEJB</ejb-name>
<home>ex1.ejb21.HelloHome</home>
<remote>ex1.ejb21.Hello</remote>
<local-home>ex1.ejb21.HelloLocalHome</local-home>
<local>ex1.ejb21.HelloLocal</local>
<ejb-class>ex1.ejb21.HelloBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
One thing i found interesting is that when i compiled the client class, it refused to compile unless it had a reference to the HelloHome class. To resolve this i had to add the ejb jar file to the classpath of the client class. Is this how it is supposed to work? i.e. the ejb jar file needs to be on the classpath of the client?
In terms of the jndi name used for the lookup, do i need to create a new name? In the above example, it looks the EJB name is used as a lookup.