7 Replies Latest reply on Feb 17, 2010 1:09 PM by pmuir

    Using Weld - get BeanManager from Google App Engine Servlet?

    ceefour

      Dear Weld experts,


      How do I get a CDI bean from Weld on a GAE Servlet?


      Weld docs say: (section 16)



      Java EE components may obtain an instance of BeanManager from JNDI by looking up the name java:comp/BeanManager. Any operation of BeanManager may be called at any time during the execution of the application.

      But GAE doesn't support JNDI. So, how can I get a BeanManager instance to get a bean?


      Another confusion:



      15.3. Calling a bean from a servlet It's easy to use a bean from a servlet in Java EE 6. Simply inject the bean using field or initializer method injection.

      However, on containers which do not support servlet injection, like GAE (or Jetty?) the simply inject the bean isn't simple anymore.


      Thank you in advance for the help.

        • 1. Re: Using Weld - get BeanManager from Google App Engine Servlet?
          ceefour

          I tried this:


               public void doGet(HttpServletRequest req, HttpServletResponse resp)
                         throws IOException {
                    WeldManager beanManager = (WeldManager)ServletHelper.getModuleBeanManager(getServletContext());
                    Bean[] pets = beanManager.getBeans(Pet.class).toArray(new Bean[] {});
                    Pet pet = (Pet) pets[0].create(null);
                    resp.setContentType("text/plain");
                    resp.getWriter().println("Hello, " + pet.getName());
               }


          But I get:


          java.lang.NullPointerException
               at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget.produce(ManagedBean.java:230)
               at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:329)
               at com.soluvas.petstore.Pet_StoreServlet.doGet(Pet_StoreServlet.java:31)
               at javax.servlet.http.HttpServlet.service(HttpServlet.java:693)
               at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
               at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
               at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)
               at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:51)
               at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
               at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
               at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
               at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:121)
               at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
               at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
               at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
               at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
               at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712)
               at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
               at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:70)
               at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
               at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:352)
               at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
               at org.mortbay.jetty.Server.handle(Server.java:313)
               at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506)
               at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:830)
               at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
               at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
               at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)
               at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396)
               at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)

          • 2. Re: Using Weld - get BeanManager from Google App Engine Servlet?
            ceefour

            In addition, my Pet object doesn't get created.


            I've added the Weld servlet listener to web.xml, and it seems to initialize alright.


            Making the Pet class @ApplicationScoped, using the code:


                 public Pet() {
                      Logger.getLogger(Pet.class.getName()).warning("Pet is created!");
                 }


            However, no log output is shown at all during webapp startup.

            • 3. Re: Using Weld - get BeanManager from Google App Engine Servlet?
              shane.bryzak

              Try this (non portable) code:




                 private static BeanManagerImpl getBeanManager(ServletContext ctx)
                 {
                    BeanDeploymentArchive war = Container.instance().services().get(ServletServices.class).getBeanDeploymentArchive(ctx);
                    if (war == null)
                    {
                       throw new ForbiddenStateException(BEAN_DEPLOYMENT_ARCHIVE_MISSING, ctx);
                    }
                    BeanManagerImpl beanManager = Container.instance().beanDeploymentArchives().get(war);
                    if (beanManager == null)
                    {
                       throw new ForbiddenStateException(BEAN_MANAGER_FOR_ARCHIVE_NOT_FOUND, ctx, war);
                    }
                    return beanManager;
                 }



              • 4. Re: Using Weld - get BeanManager from Google App Engine Servlet?
                ceefour

                Thank you Shane, though I think this way is simpler:


                WeldManager beanManager = (WeldManager)ServletHelper.getModuleBeanManager(getServletContext());
                



                How do I use this beanManager ? For:


                1. To create a new bean of a specific type
                2. To get an existing bean (i.e. @ApplicationScoped) with eager=true


                Thank you.

                • 5. Re: Using Weld - get BeanManager from Google App Engine Servlet?
                  shane.bryzak

                  Ah, I didn't realise that ServletHelper was one of our classes.  Anyway, if you can get a reference to the BeanManager then you can get an instance of your bean like this:


                  Bean petBean = beanManager.getBeans(Pet.class).iterator().next();
                  Pet pet = (Pet) petBean.create(beanManager.createCreationalContext(petBean));
                  resp.setContentType("text/plain"); 
                  resp.getWriter().println("Hello, " + pet.getName()); 





                  • 6. Re: Using Weld - get BeanManager from Google App Engine Servlet?
                    ceefour

                    Thanks a lot Shane!


                    That example is exactly what I'm looking for. It should be added to the Weld docs.

                    • 7. Re: Using Weld - get BeanManager from Google App Engine Servlet?
                      pmuir

                      We are working on supporting proper Servlet Injection in GAE - using ServletHelper is really a hack, and liable to break at any time ;-)


                      https://jira.jboss.org/jira/browse/WELDX-23