Skip to main content

Call remote EJB3 module from web application.

11 replies [Last post]
petka
Offline
Joined: 2005-08-26

Hello all,
I have following problem, I have remote ejb3 module deployed on glassfish 58g and web application with servlet deployed on the same server. I want to call remote ejb from web application but I get NameNotFoundException. This is my code:

EJB3 module
package org.petka.remote.ejb;
import javax.ejb.Remote;

@Remote
public interface HelloRemote {

public void sayHello();
}

package org.petka.remote.ejb;

import javax.ejb.Remote;
import javax.ejb.Stateless;

import org.petka.remote.ejb.HelloRemote;

@Stateless(mappedName="hello")
@Remote({HelloRemote.class})

public class Hello implements HelloRemote{

public void sayHello() {
System.out.println("Petka say hello EJB3 remote interface.");
}

}

web application
package org.petka.web;

import java.io.IOException;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.petka.remote.ejb.HelloRemote;

public class Hello extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
static final long serialVersionUID = 1L;

public Hello() {
super();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet()");

try {
InitialContext ctx = new InitialContext();
HelloRemote hello = (HelloRemote) ctx.lookup("java:comp/env/hello");
hello.sayHello();
} catch (NamingException e) {
e.printStackTrace();
}
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}
}

web.xml

hello
Session
org.petka.remote.ejb.HelloRemote

sun-web.xml
<?xml version="1.0" encoding="UTF-8"?>

hello
java:comp/env/hello

Where I wrong ???? Please any advice.
If someone post some example will be great.
Thanks in advance.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
cf126330
Offline
Joined: 2005-03-29

Hi Bob,

If you deploy these EARs to glassfish, jboss-*.xml files will be ignored. That means the global jndi name of the EJB is not set, and the mapping of ejb-ref to the target EJB's jndi name is not used. You will need to create corresponding sun-ejb-jar.xml and sun-web.xml.

If you deploy it to jboss, I don't see anything wrong here, though there are a couple of minors things. First, your client looks up by global jndi name, so the ejb-ref declared in web.xml is not used. Second, in the in jboss-web.xml,


ejb/UserAdmin/UserBean
UserBean

shouldn't be ejb/UserAdmin/UserBean, the global jndi-named declared in jboss.xml for the EJB?

-cheng

bpet36
Offline
Joined: 2007-12-14

Hi cheng,

I think the lookup is actually finding the EJB now, but I am getting a ClassCastException
on the line

obj = ctx.lookup("ejb/UserAdmin/UserBean);

Do you thin this is a JBoss classloading issue?

Here is the stack trace:

java.lang.ClassCastException: org.jboss.util.id.GUID cannot be cast to org.jboss
.util.id.GUID
at org.jboss.invocation.InvokerInterceptor.readExternal(InvokerInterceptor.java:358)
at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1792)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at org.jboss.proxy.Interceptor.readExternal(Interceptor.java:80)
at org.jboss.proxy.ejb.RetryInterceptor.readExternal(RetryInterceptor.java:291)
at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1792)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at org.jboss.proxy.Interceptor.readExternal(Interceptor.java:80)
at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1792)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at org.jboss.proxy.Interceptor.readExternal(Interceptor.java:80)
at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1792)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at org.jboss.proxy.Interceptor.readExternal(Interceptor.java:80)
at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1792)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at org.jboss.proxy.ClientContainer.readExternal(ClientContainer.java:156)
at java.io.ObjectInputStream.readExternalData(ObjectInputStream.java:1792)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1751)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1945)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1869)

at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at java.rmi.MarshalledObject.get(MarshalledObject.java:142)
at org.jnp.interfaces.MarshalledValuePair.get(MarshalledValuePair.java:72)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:652)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
at javax.naming.InitialContext.lookup(InitialContext.java:392)

Thanks again,
Bob

cf126330
Offline
Joined: 2005-03-29

Hi Bob,

Since it's a EJB 2.1 bean, you need to narrow it first from corba object:

Object obj = PortableRemoteObject.narrow(ctx.lookup("ejb/UserAdmin/UserBean), UserSessionHome.class);

UserSessionHome home = (UserSessionHome) obj;

This has been simplified in EJB 3.

-cheng

bpet36
Offline
Joined: 2007-12-14

Hi cheng,

I was initially performing the narrowing first and then I also swapped out to use the code you posted and the exception is the same. My only thought is that the GUID class is loaded separately by the ClassLoader for the EJB deployed in app1.ear and the Servlet deployed within app2.ear.

Bob

petka
Offline
Joined: 2005-08-26

Finally I made it. Thanks to both of you.

bpet36
Offline
Joined: 2007-12-14

I have the same problem and am getting no response on another forum. Can you explain how you resolved this issue? I have a servlet deployed in one ear and an ejb deployed in a separate ear. When attempting to lookup the ejb from said servlet, I get a NameNotFoundException. I assume it is a configuration issue or a classloading issue.

Thanks in advance,
Bob

cf126330
Offline
Joined: 2005-03-29

Hi Bob,

Most likely a configuration issue. Your case is well supported in glassfish. Can you post your code and descriptors, if any, especially how you look up the bean.

-cheng

bpet36
Offline
Joined: 2007-12-14

Hi cheng,

Thanks for your response, here are the descriptors and lookup code.

[b]ejb-jar.xml of deployed EJB in app1.ear[/b]

UserBeanSession
UserBeanSession
UserBean
com.ssi.session.UserBeanHome
com.ssi.session.UserBean
com.ssi.session.UserBeanSession
Stateless

Container
SecurityDS
javax.sql.DataSource
Container

[b]Jboss.xml of deployed EJB in app1.ear[/b]

UserBean
ejb/UserAdmin/UserBean
True

${jboss.partition.name:DefaultPartition}
org.jboss.ha.framework.interfaces.RoundRobin


org.jboss.ha.framework.interfaces.RoundRobin



SecurityDS
java:/SecurityDS

[b]Web.xml for Servlet in app2.ear[/b]

ejb/UserAdmin/UserBean
Session
com.ssi.session.UserBeanHome
com.ssi.session.UserBean

[b]Jboss-web.xml for Servlet in app2.ear[/b]


ejb/UserAdmin/UserBean
UserBean

[b]Lookup code[/b]

InitialContext ctx = new InitialContext();
Object obj = null;
try {
obj = ctx.lookup("ejb/UserAdmin/UserBean);
} catch (Exception e) {
logger.log(Level.ERROR, e.getMessage(), e);
}
UserBeanHome home = (UserBeanHome)obj;
UserBean remote = (UserBean) home.create();

Thanks again for your help.

Bob

bpet36
Offline
Joined: 2007-12-14

the missing " in the lookup was just a cut and paste error, still doesn't work

should be
obj = ctx.lookup("ejb/UserAdmin/UserBean");

km
Offline
Joined: 2005-10-28

This is an eternal problem with JNDI names. The name "java:comp" is not required. Just change
the sun-web.xml to say:

[code]

hello
hello

[/code]

and you'll be fine. I just deployed it that way and everything is fine :)

Note: Doing what you did is hard, especially using NetBeans IDE. Here are the steps you
have to take to achieve this:

- Create an EJB Module Project.
- Leave the IDE for a while, resort to say command line and do a "jar cvf ejbif.jar org.petka.ejb.remote.HelloRemote.class".
- Create a Web Project.
- Add the Remote interface as the library (ejbif.jar) in Libraries.
- Compile the Web App.
- Deploy.
Phew!

- Kedar

cf126330
Offline
Joined: 2005-03-29

change this:


hello
[b]java:comp/env/hello[/b]

to



hello
org.petka.remote.ejb.HelloRemote

You can simplify it by using annotation alone without any descriptors.

Some ejb3 samples:
https://glassfish.dev.java.net/javaee5/ejb/EJB30.html

JavaEE Tutorial:
http://java.sun.com/javaee/5/docs/tutorial/doc/

Glassfish EJB FAQ:
https://glassfish.dev.java.net/javaee5/ejb/EJB_FAQ.html

-cheng