7/03/2006

Fix NameNotFoundException: Wrong Mapping in Deployment Plan

In previous posts, I wrote about two common causes of javax.naming.NameNotFoundException: incorrect lookup name and reference not declared. This post covers a third cause: wrong mapping of EJB/resource in appserver-specific deployment plans.

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;
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() { }
}
Application client main class:
package hello;
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();
}
}
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.

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"?>
<!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>
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:
<ejb-ref>
<ejb-ref-name>hello.Main/helloEJB</ejb-ref-name>
<jndi-name>hello.ejb.HelloEJBRemote</jndi-name>
</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.

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: , , , , , , , , , , , ,

2 comments:

Anonymous said...

You can additionally browse/view the jndi tree on the app server to see under which 'name' your object is deployed.

http://tripoverit.blogspot.com/2007/03/print-jndi-tree.html

Anna said...

Great and Useful Article.

Online Java Training

Java Online Training India

Java Online Course

Java EE course

Java EE training

Best Recommended books for Spring framework

Java Interview Questions








Java Course in Chennai

Java Online Training India