users@glassfish.java.net

Servlet referencing remote and stateless ejb

From: <glassfish_at_javadesktop.org>
Date: Thu, 07 Aug 2008 06:22:37 PDT

I'm trying t make a simple example to work.
It's a servlet that references a remote stateless ejb. All the components are packaged in a simple war file.
When the servlet references the bean using the injection @EJB, a message error is thrown and the log shows the root causes:
root cause
com.sun.enterprise.InjectionException: Exception attempting to inject Unresolved Ejb-Ref foo.FooServlet/foo_at_jndi: foo.FooRemote_at_null@foo.FooRemote_at_Session@null into class foo.FooServlet
root cause
javax.naming.NameNotFoundException: foo.FooRemote#foo.FooRemote not found.

I'm sure that should be missing something but I don't know what.
Could you, please, help me on that?
Thanks very much,
Ismael

It follows the example copied from an Internet Forum:

C:\simple-ejb3> tree /A /F
+---classes
| \---foo
\---src
    \---foo
           FooBean.java
           FooRemote.java
2. create java src files under src\foo:
package foo;
import javax.ejb.*;

@Remote
public interface FooRemote {
public String echo(String s);
}
------------
package foo;
import javax.ejb.*;

@Stateless
public class FooBean implements FooRemote {
public String echo(String s) {
  return s;
}
}
------------
package foo;
import javax.ejb.*;
import javax.naming.*;

public class Client {
public static void main(String[] args) throws Exception {
  Context ic = new InitialContext();
  Object obj = ic.lookup(FooRemote.class.getName());
  System.out.println("lookup returned " + obj);

  FooRemote foo = (FooRemote) obj;
  String input = (args.length > 0) ? args[0] :
              "No application arg specified.";
  String s = foo.echo(input);
  System.out.println("foo.echo returned " + s);
}
}
3. Compile java src. An environment variable JAVAEE_HOME is set for convenience but it's not required.
C:\simple-ejb3\classes> set JAVAEE_HOME=C:\glassfish
C:\simple-ejb3\classes> javac -d . -classpath %JAVAEE_HOME%\lib\javaee.jar;. ..\src\foo\*.java
4. start the appserver:
C:\simple-ejb3\classes> %JAVAEE_HOME%\bin\asadmin.bat start-domain
5. package and autodeploy ejb-jar. We can combine the 2 steps in 1 by using %JAVAEE_HOME%\domains\domain1\autodeploy as the destdir:
C:\simple-ejb3\classes> jar cvf %JAVAEE_HOME%\domains\domain1\autodeploy\foo-ejb.jar foo\FooBean.class foo\FooRemote.class
6. run the standalone java client:
C:\simple-ejb3\classes> java -cp %JAVAEE_HOME%\lib\javaee.jar;%JAVAEE_HOME%\lib\appserv-rt.jar;. foo.Client

lookup returned foo._FooRemote_Wrapper_at_e9738564
foo.echo returned No application arg specified.
7. undeploy the ejb module:
del %JAVAEE_HOME%\domains\domain1\autodeploy\*.jar
It's pretty easy, isn't it? No deployment descriptors, no client stubs, no jndi.properties file.

In previous post, I wrote a simple EJB3 bean invoked from a standalone java client. Standalone java client is convenient for prototyping and testing purpose. The most common way to invoke EJB is from a web app. Here I will add such a simple web app to invoke the foo-ejb module written in previous post.

Steps 1 - 5 are the same as in previous post, except in step 2, foo/Client.java is not needed here.

6. Servlet class
package foo;
import java.io.*;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;

public class FooServlet extends HttpServlet {
   @EJB(mappedName="foo.FooRemote")
   private FooRemote foo;
  
   protected void processRequest(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
       response.setContentType("text/html;charset=UTF-8");
       PrintWriter out = response.getWriter();
       out.println("<html>");
       out.println("<head>");
       out.println("<title>Servlet FooServlet</title>");
       out.println("</head>");
       out.println("<body>");
       out.println("<h1>FooRemote.echo returned: " + foo.echo("From FooServlet") + "</h1>");
       out.println("</body>");
       out.println("</html>");
   }
  
   protected void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
       processRequest(request, response);
   }
  
   protected void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
       processRequest(request, response);
   }
}
7. web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
   <servlet>
       <servlet-name>FooServlet</servlet-name>
       <servlet-class>foo.FooServlet</servlet-class>
   </servlet>
   <servlet-mapping>
       <servlet-name>FooServlet</servlet-name>
       <url-pattern>/FooServlet</url-pattern>
   </servlet-mapping>
</web-app>

8. Make sure foo.FooRemote.class is in the webapp's classpath. For example, C:\simple-ejb\build\classes directory is included in the webapp's classpath.

9. Build the webapp to produce a simple-web.war with the following content:
index.jsp
WEB-INF/web.xml
WEB-INF/classes/foo/FooServlet.class
WEB-INF/classes/foo/FooRemote.class
10. Start glassfish server and deploy the war file:
set JAVAEE_HOME=C:\glassfish
%JAVAEE_HOME%\bin\asadmin.bat start-domain
C:\simple-web\dist> copy simple-web.war %JAVAEE_HOME%\domains\domain1\autodeploy

Another way to deploy the war is using asadmin command:
C:\simple-web\dist> %JAVAEE_HOME%\bin\asadmin deploy simple-web.war
11. Run it by entering the following url in browser:
http://localhost:8080/simple-web/FooServlet
.
[Message sent by forum member 'ismaelcramos' (ismaelcramos)]

http://forums.java.net/jive/thread.jspa?messageID=292127