4 Replies Latest reply on Dec 14, 2012 9:57 AM by kolaye

    Calling an EJB from servlet

    nautilusiii

      Hi!

       

      I successfully deployed a simple EJB 3.

       

      Here is the code:

       

      {code}

      package ejb;

       

      import javax.ejb.Remote;

       

      @Remote

      public interface HelloWorld {

          public String sayHello();

      }

       

       

       

      package ejb;

       

      import javax.ejb.Stateless;

      import ejb.HelloWorld;

       

      public @Stateless class HelloWorldBean implements HelloWorld {

          public String sayHello()

          {

              return "Hello world...";

          }

      }

      {code}

       

       

      The deployment tells me about the following bindings:

       

      {code}

        java:global/MyEJBProject/HelloWorldBean!ejb.HelloWorld

        java:app/MyEJBProject/HelloWorldBean!ejb.HelloWorld

        java:module/HelloWorldBean!ejb.HelloWorld

        java:jboss/exported/MyEJBProject/HelloWorldBean!ejb.HelloWorld

        java:global/MyEJBProject/HelloWorldBean

        java:app/MyEJBProject/HelloWorldBean

        java:module/HelloWorldBean

      {code}

       

       

      Looking up from a standalone client works:

       

      {code}

      import java.util.Properties;

       

      import javax.naming.Context;

      import javax.naming.InitialContext;

       

      import ejb.HelloWorld;

      import ejb.HelloWorldBean;

       

      public class Client {

       

          public static void main(String[] args) {

              try {

                  Properties env = new Properties();

                  env.put(Context.INITIAL_CONTEXT_FACTORY,

                          "org.jboss.naming.remote.client.InitialContextFactory");

                  env.put(Context.PROVIDER_URL, "remote://localhost:4447");

                  env.put(Context.SECURITY_PRINCIPAL, "xxx");

                  env.put(Context.SECURITY_CREDENTIALS, "xxx");

                  env.put("jboss.naming.client.ejb.context", true);

       

                  Context ctx = new InitialContext(env);

                  HelloWorld hello = (HelloWorld) ctx.lookup("MyEJBProject/HelloWorldBean!ejb.HelloWorld");

       

                  System.out.println("EJB says: " + hello.sayHello());

              } catch (Exception e) {

                  e.printStackTrace();

              }

          }

      }

      {code}

       

       

      But invocation from a servlet results in error messages due to unsuccessful lookups.

       

      I tried:

       

      {code}

      protected void doGet(HttpServletRequest request,

              HttpServletResponse response) throws ServletException, IOException {

          try {

              response.setContentType("text/plain");

              PrintWriter out = response.getWriter();

       

              Context ctx = new InitialContext();

              HelloWorld hello = (HelloWorld) ctx

                      .lookup("MyEJBProject/HelloWorldBean!ejb.HelloWorld");

       

              out.println("EJB says: " + hello.sayHello());

          } catch (Exception e) {

              e.printStackTrace();

          }

       

      }

      {code}

       

      Any idea?

        • 1. Re: Calling an EJB from servlet
          nautilusiii

          Okay, if I do the lookup like this I get another error (not sure if that one is better at all):

           

          {code}

          HelloWorld hello = (HelloWorld) ctx

                  .lookup("ejb:/MyEJBProject/HelloWorldBean!ejb.HelloWorld");

          {code}

           

          Now I get this error:

           

           

          {code}

          11:13:19,796 ERROR [stderr] (http--127.0.0.1-8080-1) javax.naming.NamingException: Could not load ejb proxy class ejb.HelloWorld

          [Root exception is java.lang.ClassNotFoundException: ejb.HelloWorld from [Module "deployment.ServletTest2.war:main" from Service Module Loader]]

          {code}

           

          The EJB is located in another project than the servlet is.

          I have deployed both from within JBoss Dev Stuido via Run on server.

           

          Anyone?

          • 2. Re: Calling an EJB from servlet
            nautilusiii

            I now packaged the EJB project and the project holding the servlet into an EAR.

            This works.

             

            Am I supposed to package these things into a single EAR to allow them to find each other?

             

            Update:

            Seems as with JBoss AS 7 stuff is handled more isolated than before; so packaging things into EARs seems to be the right way.

             

            Thx.

            • 3. Re: Calling an EJB from servlet
              jmartisk

              You don't have to put them both into an EAR, but you have to make sure that the servlet will 'see' the EJB's class - in this case the HelloWorld interface is enough- , that means the class will be on the classpath. Deployments are indeed isolated and don't see others' classes.

              You may for example copy the HelloWorld interface and put it also into the application with the Servlet.

              The enterprise way is to have a separate 'API-jar' containing just the API, in this case the HelloWorld interface, which can be used as a dependency for the application with the Servlet.

              • 4. Re: Calling an EJB from servlet
                kolaye

                You are right, the servlet can't see the EJB's class if they deploy separately!

                I met a problem like this, and I resovle it now!