This sample project consists of a simple EJB3 stateless session bean HelloEJBBean, and an application client with main class hello.Main. A reference to HelloEJBBean's remote business interface is injected into the client main class.
package hello.ejb;Application client main class:
import javax.ejb.Remote;
@Remote
public interface HelloEJBRemote {
void hello();
}
package hello.ejb;
import javax.ejb.Stateless;
@Stateless
public class HelloEJBBean implements HelloEJBRemote {
public void hello() { }
}
package hello;For the above sample app to work, we do not need any deployment descriptors or deployment plan. Why? because all metadata have been provided with annotations, or have defaults, or can be figured out by appserver one way or another.
import hello.ejb.HelloEJBRemote;
import javax.ejb.EJB;
public class Main {
@EJB(beanName="HelloEJBBean")
private static HelloEJBRemote helloEJB;
public static void main(String[] args) {
helloEJB.hello();
}
}
But some IDEs still generate unnecessary deployment descriptors and deployment plans, which may have wrong mapping info. This happens without you knowing it. If you delete these unnecessary and wrong deployment plans, the next time you rebuild project, they will be regenerated.
For instance, NetBeans 5.5 beta generates the following sun-application-client-jar.xml, which is unnecessary and contains the wrong mapping data:
<?xml version="1.0" encoding="UTF-8"?>Both the ejb reference name and ejb JNDI name are wrong. If the IDE really thinks a sun-application-client.xml is helpful for whatever reason, the ejb-ref element should be:
<!DOCTYPE sun-application-client PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Application Client 5.0//EN"
"http://www.sun.com/software/appserver/dtds/sun-application-client_5_0-0.dtd">
<sun-application-client>
<ejb-ref>
<ejb-ref-name>helloEJB</ejb-ref-name>
<jndi-name>ejb/helloEJB</jndi-name>
</ejb-ref>
</sun-application-client>
<ejb-ref>because the default ejb reference name for an injected ejb is the of the format: <fully-qualified-class-name of the injection target class>/field-name. The default ejb JNDI name depends on appserver implementation, and for EJB3 in JavaEE SDK 5/Glassfish/Sun Java System Application Server, it's the fully qualified class name of the remote business interface.
<ejb-ref-name>hello.Main/helloEJB</ejb-ref-name>
<jndi-name>hello.ejb.HelloEJBRemote</jndi-name>
</ejb-ref>
IDE's best effort to generate deployment artifacts is still not good enough. With wrong mapping info in deployment plan, your app may fail to deploy, if the appserver validates the ejb reference at deployment time. Or even if it is deployed, it will fail at request time.
All posts in this series for NameNotFoundException:
Fix NameNotFoundException: Incorrect Lookup Name
Fix NameNotFoundException: Reference Not Declared
Fix NameNotFoundException: Wrong Mapping in Deployment Plan
Tags: