4 Replies Latest reply on Aug 15, 2006 7:27 AM by basel

    servlet in seam application

    jason_rency

      All,
      my question may looks strange,

      I tried to get a common java servlet work within a seam application by adding the following line in web.xml: (calculator is the servlet name)

      <servlet>
       <servlet-name>Calculator</servlet-name>
       <servlet-class>server.Calculator</servlet-class>
       </servlet>
      
       <servlet-mapping>
       <servlet-name>Calculator</servlet-name>
       <url-pattern>/Calculator</url-pattern>
       </servlet-mapping>


      the servlet worked fine (I called it from a mobile phone, that's why I need a servlet) after I deployed the seam app with this servlet. but when I tried to use the seam app itself by browser (the hotel booking example), it just didn't work. seems there are conflicts between the new lines I added and the old lines in web.xml .

      then I changed the servlet by adding ejb3 annotation (it's strange, huh? a ejb3 staless session bean servlet) and re-deploy the app again (with the new lines in the web.xml). then the servlet (also a session bean) worked well and the hotel booking example worked fine as normal.

      then added persistency statement to this servlet (the session bean) but I got a NPE, which seems the Entity manager is null and I can't get the entity manager properly in a servlet which is also a ejb3 session bean?

      the code is like this:

      package server;
      
      import javax.ejb.Stateless;
      import javax.servlet.*;
      import javax.servlet.http.*;
      import java.io.*;
      import java.text.*;
      import javax.persistence.EntityManager;
      import javax.persistence.PersistenceContext;
      
      
      @Stateless
      public class Calculator extends HttpServlet implements cacu
      {
       @PersistenceContext
       private EntityManager em;
       private Reguser user;
      
       public void doPost(HttpServletRequest request,HttpServletResponse response)
       throws IOException, ServletException
       {
       response.setContentType("text/plain");
       PrintWriter out = response.getWriter();
       String uid = request.getParameter("uid");
       String passwd =request.getParameter("passwd");
       user = em.find(Reguser.class, "rency"); (exception here, em is null)
       String email = user.getEmail();
       System.out.print(email);
       out.println("just a test: "+ uid);
       }
      
      }


      exception was:

      10:16:49,501 ERROR [[Calculator]] Servlet.service() for servlet Calculator threw exception
      java.lang.NullPointerException
       at server.Calculator.doPost(Calculator.java:26) (the entity manager) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
       at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
       at java.lang.Thread.run(Thread.java:595)



      also I added a ejb3 web service in the app, the web service work well: code like this:

      interface:

      package server;
      
      import javax.jws.WebService;
      import javax.jws.WebMethod;
      
      
      @WebService
      public interface findEmail {
      
       @WebMethod public String findemail(String username);
      
      }


      the implementation:

      package server;
      
      import javax.ejb.Stateless;
      import javax.jws.WebService;
      import javax.persistence.EntityManager;
      import javax.persistence.PersistenceContext;
      
      
      @Stateless
      @WebService(endpointInterface="server.findEmail")
      
      public class findemailimpl implements findemail {
      
       @PersistenceContext
       private EntityManager em;
       private Reguser user;
      
       public String finduser(String username)
       {
       em.find(Reguser.class, username);
       String email = user.getEmail();
       return email;
       }
      }
      



        • 1. Re: servlet in seam application
          basel

          Injecting an EntityManager into a servlet is not recommended since the former is not thread safe. Here is what I do in my current web application:

          @PersistenceUnit(name = "myPU")
          private EntityManagerFactory factory;
          
          protected void doGet(HttpServletRequest request,
           HttpServletResponse response) throws ServletException,
           IOException{
           try{
           if(factory == null){
           String name = "java:/myEntityManagerFactory";
           factory = (EntityManagerFactory)
           Naming.getInitialContext().lookup(name);
           }
           if(em == null){
           em = factory.createEntityManager();
           }
           }
           }catch(NamingException e){
           err.println("NamingException when trying to get an " +
           "EntityManager: "+e.getMessage());
           e.printStackTrace();
           }
          }
          
          
          


          • 2. Re: servlet in seam application
            jason_rency

            thanks basel,

            I tried to add the your code in my servlet,
            em is not null but I got the following exceptions:

            2:06:51,995 ERROR [[Calculator]] Servlet.service() for servlet Calculator threw exception
            java.lang.IllegalStateException: No transaction.
             at org.jboss.tm.TxManager.setRollbackOnly(TxManager.java:397)
             at org.hibernate.ejb.AbstractEntityManagerImpl.markAsRollback(AbstractEntityManagerImpl.java:392)
             at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:545)
             at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:567)
             at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:168)
             at src.reg.server.Calculator.doPost(Calculator.java:46)


            another question, I should place the servlet class in the war file if it a pure servlet?

            thanks a lot
            Jason

            • 3. Re: servlet in seam application
              basel

              With EJB3 the application server makes sure that your methods are executed within a transaction. This is not the case with Servlets so you have to start and commit the transaction yourself. Here is the code:

              UserTransaction utx = Transactions.getUserTransaction();
              if(utx.getStatus() != Status.STATUS_ACTIVE)
               utx.begin();
              em.joinTransaction();
              utx.commit();
              

              The if statement is not required however I needed that in my web application due to an exception that I don't recall right now.

              • 4. Re: servlet in seam application
                basel

                 

                em.joinTransaction();
                em.createQuery(query)
                 .setParameter("param1", param1)
                 .getSingleResult();
                utx.commit();