I've added the following in my web.xml:
<ejb-ref>
<ejb-ref-name>ejb/userManagerBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>gha.ywk.name.entry.ejb.usermanager.UserManagerHome</home>
<remote>what should go here??</remote>
</ejb-ref>
The following java code is giving me NamingException:
public UserManager getUserManager () throws HUDException {
String ROLE_JNDI_NAME = "ejb/userManagerBean";
try {
Properties props = System.getProperties();
Context ctx = new InitialContext(props);
UserManagerHome userHome = (UserManagerHome) ctx.lookup(ROLE_JNDI_NAME);
UserManager userManager = userHome.create();
WASSSecurity user = userManager.getUserProfile("user101", null);
return userManager;
} catch (NamingException e) {
log.error("Error Occured while getting EJB UserManager" + e);
return null;
} catch (RemoteException ex) {
log.error("Error Occured while getting EJB UserManager" + ex);
return null;
} catch (CreateException ex) {
log.error("Error Occured while getting EJB UserManager" + ex);
return null;
}
}
The code is used inside the container. By that I mean that the .WAR is deployed on the server (Sun Application Server).
StackTrace (after jsight's suggestion):
>Exception occurred in target VM: com.sun.enterprise.naming.java.javaURLContext.<init>(Ljava/util/Hashtable;Lcom/sun/enterprise/naming/NamingManagerImpl;)V
java.lang.NoSuchMethodError: com.sun.enterprise.naming.java.javaURLContext.<init>(Ljava/util/Hashtable;Lcom/sun/enterprise/naming/NamingManagerImpl;)V
at com.sun.enterprise.naming.java.javaURLContextFactory.getObjectInstance(javaURLContextFactory.java:32)
at javax.naming.spi.NamingManager.getURLObject(NamingManager.java:584)
at javax.naming.spi.NamingManager.getURLContext(NamingManager.java:533)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:279)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at gov.hud.pih.eiv.web.EjbClient.EjbClient.getUserManager(EjbClient.java:34)
I think you want to access an EJB application (known as EJB module) from a web application in Sun Application Server, right ?
ok, let's go.
When you deploy an EJB into an application server, the application server gives it an address - known as global JNDI address - as a way you can access it (something like your address). It changes from an application server to another.
In JBoss Application Server, you can see global JNDI address (after starting it up) in the following address
http://127.0.0.1:8080/jmx-console/HtmlAdaptor
In Sun Application Server, if you want to see global JNDI address (after starting it up), do the following
Access the admin console in the following address
http://127.0.0.1:4848/asadmin
And click JNDI browsing
If your EJB IS NOT registered right there, there is something wrong
EJB comes in two flavors: EJB 2.1 and EJB 3.0. So what is the difference ?
Well, well, well...
Let's start with EJB 2.1
It defines methods for CREATING, destroying, and finding local or remote EJB objects. It acts as life cycle interfaces for the EJB objects. All home interfaces have to extend standard interface javax.ejb.EJBHome - if you a using a remote ejb object - or javax.ejb.EJBLocalHome - if you are using a local EJB object.
// a remote EJB object - extends javax.ejb.EJBHome
// a local EJB object - extends javax.ejb.EJBLocalHome
public interface MyBeanRemoteHome extends javax.ejb.EJBHome {
MyBeanRemote create() throws javax.ejb.CreateException, java.rmi.RemoteException;
}
Application Server will create Home objects as a way you can obtain an EJB object, nothing else.
Take care of the following
A session bean’s remote home interface MUST DEFINE ONE OR MORE create<METHOD> methods. A stateless session bean MUST DEFINE exactly one <METHOD> method with no arguments.
...
throws clause MUST INCLUDE javax.ejb.CreateException
...
If your Home interface extends javax.ejb.EJBHome, throws clauses MUST INCLUDE the java.rmi.RemoteException. If it extends javax.ejb.EJBLocalHome, MUST NOT INCLUDE the java.rmi.RemoteException.
...
Each create method of a stateful session bean MUST BE NAMED create<METHOD>, and it must match one of the Init methods or ejbCreate<METHOD> methods defined in the session bean class. The matching ejbCreate<METHOD> method MUST HAVE THE SAME NUMBER AND TYPES OF ARGUMENTS. The create method for a stateless session bean MUST BE NAMED create but need not have a matching “ejbCreate” method.
Now create an business interface in order to define business logic in our EJB object
// a remote EJB object - extends javax.ejb.EJBObject
// a local EJB object - extends javax.ejb.EJBLocalObject
public interface MyBeanRemote extends javax.ejb.EJBObject {
void doSomething() throws java.rmi.RemoteException;
}
Now take care of the following
If you are using a remote EJB object, remote interface methods MUST NOT EXPOSE local interface types or local home interface types.
...
If your Home interface extends javax.ejb.EJBObject, throws clauses MUST INCLUDE the java.rmi.RemoteException. If it extends javax.ejb.EJBLocalObject, MUST NOT INCLUDE the java.rmi.RemoteException.
Now our EJB
public class MyBean implements javax.ejb.SessionBean {
// why create method ? Take a special look at EJB Home details (above)
public void create() {
System.out.println("create");
}
public void doSomething() throws java.rmi.RemoteException {
// some code
};
}
Now take care of the following
It MUST IMPLEMENTS javax.ejb.SessionBean. It defines four methods - not shown above: setSessionContext, ejbRemove, ejbPassivate, and ejbActivate.
Notice our bean DOES NOT IMPLEMENT our business interface because of EJB specification says:
For each method defined in the interface, there must be a matching method in the session bean’s class. The matching method must have:
And YOU HAVE TO DECLARE a ejb-jar.xml file according to
<?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-instance" 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>br.com.MyBeanRemoteHome</home>
<remote>br.com.MyBeanRemote</remote>
<local-home>br.com.MyBeanLocalHome</local-home>
<local>br.com.MyBeanLocal</local>
<ejb-class>br.com.MyBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
If you do not have a local EJB object remove from the deployment descriptor above
<local-home>br.com.MyBeanLocalHome</local-home>
<local>br.com.MyBeanLocal</local>
If you do not have a remote EJB object remove from the deployment descriptor above
<home>br.com.MyBeanRemoteHome</home>
<remote>br.com.MyBeanRemote</remote>
And put in META-INF directory
Our jar file will contain the following
/META-INF/ejb-jar.xml
br.com.MyBean.class
br.com.MyBeanRemote.class
br.com.MyBeanRemoteHome.class
Now our EJB 3.0
// or @Local
// You can not put @Remote and @Local at the same time
@Remote
public interface MyBean {
void doSomething();
}
@Stateless
public class MyBeanStateless implements MyBean {
public void doSomething() {
}
}
Nothing else,
In JBoss put jar file in
<JBOSS_HOME>/server/default/deploy
In Sun Application Server access (after starting it up) admin console
http://127.0.0.1:4848/asadmin
And access EJB Modules in order to deploy your ejb-jar file
As you have some problems when deploying your application in NetBeans, i suggest the following
Now create another war PROJECT
And implement the following code in your Servlet or something else whether you are using JBoss
public static Context getInitialContext() throws javax.naming.NamingException {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
p.put(Context.URL_PKG_PREFIXES, " org.jboss.naming:org.jnp.interfaces");
p.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");
return new javax.naming.InitialContext(p);
}
Or the following whether you are using Sun Application Server - put the file appserv-rt.jar (I do not know which past contain appserv-rt.jar in Sun Application Server) in your classpath
public static Context getInitialContext() throws javax.naming.NamingException {
return new javax.naming.InitialContext();
}
In order to access your EJB in our Servlet or something else
MyBeanRemote myBean = (MyBeanRemote) getInitialContext().lookup(<PUT_EJB_GLOBAL_ADDRESS_RIGHT_HERE>);
myBean.doSomething();
regards,