1 Reply Latest reply on Mar 21, 2011 1:12 PM by zecas zecas

    Calling an EJB from WAR, in a standalone Java class

    zecas zecas Newbie

      Hi,

       

       

      I'm getting some difficulties on putting an EJB to work, I hope someone can help me out, as this must be something very simple.

       

       

      I have a EAR project that contains a WAR and an EJB modules. I'm using EJB3 and annotations, and I have the current one defined:

       

       

      @Stateless(name="my-proc")

      public class MyProc implements MyProcRemote, MyProcLocal {

       

       

          /**

           * Default constructor.

           */

          public MyProc() {

          }

       

       

          /**

           * {@inheritDoc}

           */

                public void log(String message) {

                          System.out.println("Received Message: [" + message + "]");

                }

       

       

      }

       

       

      @Local

      public interface MyProcLocal {

       

       

                public void log(String message);

       

       

      }

       

       

      @Remote

      public interface MyProcRemote {

       

       

                public void log(String message);

       

       

      }

       

       

      Looking into JBoss JMX console, I don't know exacly where to find the deployed EJB info, but on the console initial listing, I found:

       

       

      id="jboss.j2ee:ear=myear-1.0.0.ear,jar=myejb-1.0.0.jar,name=QueueMDB,service=EJB3",type=Component  (This is a different EJB)

      id="jboss.j2ee:ear=myear-1.0.0.ear,jar=myejb-1.0.0.jar,name=my-proc,service=EJB3",type=Component

      id="jboss.j2ee:ear=myear-1.0.0.ear,jar=myejb-1.0.0.jar,name=my-proc,service=EJB3_endpoint",type=Component

       

       

      I've created a simple Servlet to inject the EJB, and it worked correctly, so I assume the EJB is well deployed:

       

       

      public class MyServlet extends HttpServlet {

       

       

                private static final long serialVersionUID = 1L;

       

       

                @EJB MyProcRemote proc;

       

       

          /**

           * @see HttpServlet#HttpServlet()

           */

          public MyServlet() {

              super();

          }

       

       

                /**

                 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

                 */

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

                          doPost(request, response);

                }

       

       

                /**

                 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

                 */

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

                          try {

                                    response.setContentType("text/html");

                                    PrintWriter writer = response.getWriter();

                                    writer.println("<html><body>");

                                    writer.println("Hello.");

                                    if( proc!=null ) {

                                              proc.log("MyServlet!");

                                    } else {

                                              writer.println("<br>proc is null.");

                                    }

                                    writer.println("</body></html>");

                                    writer.close();

                          } catch (Exception e) {

                                    e.printStackTrace();

                          }

                }

       

       

      }

       

       

      My web.xml:

       

       

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

      <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">

                <display-name>myweb</display-name>

                <welcome-file-list>

                          <welcome-file>index.html</welcome-file>

                          <welcome-file>index.htm</welcome-file>

                          <welcome-file>index.jsp</welcome-file>

                          <welcome-file>default.html</welcome-file>

                          <welcome-file>default.htm</welcome-file>

                          <welcome-file>default.jsp</welcome-file>

                </welcome-file-list>

                <servlet>

                          <description></description>

                          <display-name>MyServlet</display-name>

                          <servlet-name>MyServlet</servlet-name>

                          <servlet-class>com.test.MyServlet</servlet-class>

                </servlet>

                <servlet-mapping>

                          <servlet-name>MyServlet</servlet-name>

                          <url-pattern>/MyServlet</url-pattern>

                </servlet-mapping>

      </web-app>

       

       

      My application.xml:

       

       

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

      <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" id="Application_ID" version="5">

        <display-name>myear</display-name>

        <module>

          <web>

            <web-uri>myweb-1.0.0.war</web-uri>

            <context-root>/myweb</context-root>

          </web>

        </module>

        <module>

          <ejb>myejb-1.0.0.jar</ejb>

        </module>

      </application>

       

       

      I have no more definitions.

       

       

       

       

      Now my problem:

       

       

      In my WAR, I use an API from my company that lauches a thread for accepting socket connections. When a connection arrives, the code instantiates a plain Java class and executes a method.

       

       

      Since the code runs from from an executing thread, and it calls one class defined by me (not a servlet, not anything JavaEE), I cannot use dependency injection (or can I?), so I'm having difficulties on getting a remote (or local) EJB interface to work.

       

       

      I was hopping to use a JNDI lookup like "java:comp/env/my-proc" but i can't make it to work.

       

       

      At this time I'm using:

       

       

      public class Received {

                ...

                public void exec(String message) {

                          ...

                          try {

                                    Context ctx = new InitialContext();

                                    MyProcRemote proc = (MyProcRemote) ctx.lookup("my-proc/remote");

                                    proc.log("Calling EJB!");

                          } catch(Exception e) {

                                    e.printStackTrace();

                          }

                          ...

                }

                ...

      }

       

       

      The output is something like:

       

       

      javax.naming.NameNotFoundException: my-proc not bound

      at org.jnp.server.NamingServer.getBinding(NamingServer.java:771) ~[jnpserver.jar!/:5.0.3.GA]

      at org.jnp.server.NamingServer.getBinding(NamingServer.java:779) ~[jnpserver.jar!/:5.0.3.GA]

      at org.jnp.server.NamingServer.getObject(NamingServer.java:785) ~[jnpserver.jar!/:5.0.3.GA]

      at org.jnp.server.NamingServer.lookup(NamingServer.java:396) ~[jnpserver.jar!/:5.0.3.GA]

      at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:726) ~[jnpserver.jar!/:5.0.3.GA]

      at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:686) ~[jnpserver.jar!/:5.0.3.GA]

      at javax.naming.InitialContext.lookup(InitialContext.java:392) ~[na:1.6.0_21]

      at com.test.Received.exec(Received.java:42) ~[myweb-1.0.0.war:na]

      at java.lang.Thread.run(Thread.java:619) [na:1.6.0_21]

       

       

      In the future, I'm going to use the local interface, but at this time, I can't put any of them to work.

       

       

      I'm developping in JBoss, and the production environment will be a Websphere, so I'm looking for a cross-platform way of doing it, so JNDI seems to be the way to go.

       

       

      Now the JNDI lookup string would be same? I would prefer so ... but if it is not, I can work out a way of external properties configuration of that JNDI string.

       

       

      Note:

       

      I will also try something like:

           public static void main(String[] args) {
                InitialContext context;
                Properties properties = new Properties();
                properties.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
                properties.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
                properties.put("java.naming.provider.url", "jnp://(ipaddress):1099");
           try {
                context = new InitialContext(properties);
                BeanRemote remoteBean = (BeanRemote)context.lookup("BeanRemote/remote");
           catch (NamingException e){
                System.out.println("testing here");
                e.printStackTrace();
                throw new RuntimeException(e);
           }

      ... that I found somewhere, but I was hopping not to need that many info, because  in Websphere I may not need anything like that, and anyway defining the server (IP, hostname, whatever ...) will add complexity to deploys.

       

       

      Thanks

        • 1. Calling an EJB from WAR, in a standalone Java class
          zecas zecas Newbie

          Looking more clearly to the JBoss logs, I found the following:

           

           

          2011-03-21 11:58:39,276 INFO [org.jboss.ejb3.EJBContainer] (main) STARTED EJB: com.test.bean.MyProc ejbName: my-proc

          2011-03-21 11:58:39,292 INFO [org.jboss.ejb3.proxy.impl.jndiregistrar.JndiSessionRegistrarBase] (main) Binding the following Entries in Global JNDI:

           

           

          myear-1.0.0/my-proc/remote - EJB3.x Default Remote Business Interface

          myear-1.0.0/my-proc/remote-com.test.bean.MyProcRemote - EJB3.x Remote Business Interface

          myear-1.0.0/my-proc/local - EJB3.x Default Local Business Interface

          myear-1.0.0/my-proc/local-com.test.bean.MyProcLocal - EJB3.x Local Business Interface

           

           

           

           

          Then, changing the line of my code to:

           

           

          MyProcRemote proc = (MyProcRemote) ctx.lookup("myear-1.0.0/my-proc/remote");

           

           

          Solved the situation, without needing to define any additional properties.

           

           

          But ... why doesn't it work with "java:comp/env/my-proc"? Or how can I make it work with that? Isn't this the standard way of JNDI lookup (I would prefer not to change it to work in, say, Websphere)?

           

           

          Thanks