0 Replies Latest reply on Feb 22, 2007 10:37 PM by Ryan McDonough

    Help w/ a custom RESTful Servlet with EJBs

    Ryan McDonough Newbie

      I am working on a REST toolkit which routes URI to an invoker and marshalls entity beans to XML using JAXB. So far, everything is working pretty good. One issue I have is that the marshalling/unmarshalling is done on the web tier. The marshaller is writing directly to the Servlet OutputStream and reading directly from the Servelt InputStream. To get a better idea of what I am up to, please have a look here:

      http://www.damnhandy.com/2007/02/21/resteasy-preview-a-restful-web-services-framework-for-java/

      When using a SessionBean, I run into the obvious problem of getting a LazyInitializationException from Hibernate. To get around it, I'm starting a UserTransaction in the servlet if the WebResource is an EJB. This isn't ideal because I may not always want to start a transaction in there.

      Seam appears to offer a much more elegant solution to this type of issue, so I have started creating a custom servlet that could hook into Seam. The SeamRemotingServlet isn't quite adaptable to what I'm trying to do, but I have started taking it apart to understand what it does. What my servlet needs to do is the following:

      * Get the path info and look up the ResourceInvoker (effectively a RequestHandler)
      * Calls the invoke() method on the ResourceInvoker and execute the Java method. The return value is generally an entity bean that will be marshalled to XML but it may not have been fully initialized yet.
      * If the method has a return value, it is marshalled to XML.

      My experimentation so far has yielded this in my service() method:

      
      ResourceInvoker invoker =
       ResourceDispatcher.instance().findResourceInvoker(request.getPathInfo());
      if(invoker != null) {
       logger.info("Executing Method: "+request.getMethod());
       try {
       HttpSession session = request.getSession(true);
       Lifecycle.setPhaseId(PhaseId.INVOKE_APPLICATION);
       Lifecycle.setServletRequest(request);
       Lifecycle.beginRequest(getServletContext(), session, request);
       invoker.invoke(request, response);
       } finally {
       Lifecycle.endRequest();
       Lifecycle.setServletRequest(null);
       Lifecycle.setPhaseId(null);
       }
      } else { ...
      


      At the moment, I still get a LazyInitializationException and I am not sure why? I also don't know that I need to be utilizing the HttpSession, but I'm sure on weather or not it's required for something like this. Any pointers woudl be greatly appreciated!