6 Replies Latest reply on Jul 27, 2010 7:38 AM by Pete Muir

    Should seam servlet event move to weld-servlet-init?

    he youlin Novice
      I think seam servlet module's event should move to weld-servlet-init.Sometimes i want to get ServletContext in weld Extension but too late.I want to get ServletContext before AfterBeanDiscovery.So i only can modify Listener.java such as:
      
      
       @Override
         public void contextInitialized(ServletContextEvent sce)
         {
      ...........
       bootstrap.startContainer(Environments.SERVLET, deployment, applicationBeanStore).startInitialization();
            manager = bootstrap.getManager(deployment.getWebAppBeanDeploymentArchive());
            manager.fireEvent(sce, new AnnotationLiteral<BeforeContextInitialized>(){private static final long serialVersionUID = -768170329007831903L;}); 
      
      ..................
      bootstrap.deployBeans().validateBeans().endInitialization();
            super.contextInitialized(sce);
      manager.fireEvent(sce, new AnnotationLiteral<AfterContextInitialized>(){private static final long serialVersionUID = -3853738946507041621L;});
      


        • 1. Re: Should seam servlet event move to weld-servlet-init?
          Pete Muir Master

          Can you post your proposed changes in unified diff format please, I can't really read what you are proposing above.

          • 2. Re: Should seam servlet event move to weld-servlet-init?
            he youlin Novice
            There are two problem in sean servlet module.
            
            1.It cannot run in servlet2.5 container
            2.It cannot inject ServletContext into extension observe method
            
            if add BeforeContextInitialized event befor deployBeans i can do a extension to make ServletContext can injected to extension observe method.
            
            In Listener.java add
            
            manager = bootstrap.getManager(deployment.getWebAppBeanDeploymentArchive());
            manager.fireEvent(sce, new AnnotationLiteral<BeforeContextInitialized>(){});
            
            and below extension
            
            public void beforeContextInitialized(@Observes @BeforeContextInitialized ServletContextEvent e,BeanManagerImpl bm) throws Exception
                      {
                         final ServletContext servletContext = e.getServletContext();
                          
                         AnnotatedTypeBuilder<ServletContext> builder = (AnnotatedTypeBuilder<ServletContext>) AnnotatedTypeBuilder
                                                                            .newInstance(servletContext.getClass())
                                                                            .readAnnotationsFromUnderlyingType();
                                    
                             BeanBuilder<ServletContext> beanBuilder = new BeanBuilder<ServletContext>(builder.create(), bm);
                             beanBuilder.defineBeanFromAnnotatedType();
                             beanBuilder.setBeanLifecycle(new BeanLifecycleImpl<ServletContext>() {
                                    public ServletContext create(BeanImpl bean, CreationalContext creationalContext) {
                                             bean.getInjectionTarget().inject(servletContext, creationalContext);
                                             bean.getInjectionTarget().postConstruct(servletContext);
                                             return servletContext;
                                    }               
                                    });
                             beanBuilder.getQualifiers().add(new AnnotationLiteral<Default>(){});
                             Bean<ServletContext> bean = beanBuilder.create();
                             bm.addBean(bean);                      
                      }
            
            
            
            and i can use ServletContext in any extension such as 
            
            <T> void processServlet(@Observes ProcessInjectionTarget<T> pit,ServletContext servletContext)
            
            

            • 3. Re: Should seam servlet event move to weld-servlet-init?
              he youlin Novice
              
              So we can separate tomcat6 and jetty servlet inject from weld-servlet-int
              
              
              extension:
              
              public void beforeContextInitialized(@Observes @BeforeContextInitialized ServletContextEvent e,BeanManagerImpl bm) throws Exception
                        {
                           final ServletContext servletContext = e.getServletContext();
                            
                           AnnotatedTypeBuilder<ServletContext> builder = (AnnotatedTypeBuilder<ServletContext>) AnnotatedTypeBuilder
                                                                              .newInstance(servletContext.getClass())
                                                                              .readAnnotationsFromUnderlyingType();
                                      
                               BeanBuilder<ServletContext> beanBuilder = new BeanBuilder<ServletContext>(builder.create(), bm);
                               beanBuilder.defineBeanFromAnnotatedType();
                               beanBuilder.setBeanLifecycle(new BeanLifecycleImpl<ServletContext>() {
                                      public ServletContext create(BeanImpl bean, CreationalContext creationalContext) {
                                               bean.getInjectionTarget().inject(servletContext, creationalContext);
                                               bean.getInjectionTarget().postConstruct(servletContext);
                                               return servletContext;
                                      }               
                                      });
                               beanBuilder.getQualifiers().add(new AnnotationLiteral<Default>(){});
                               Bean<ServletContext> bean = beanBuilder.create();
                               bm.addBean(bean);   
              boolean tomcat = true;
                    try
                    {
                       Reflections.classForName("org.apache.AnnotationProcessor");
                    }
                    catch (IllegalArgumentException e)
                    {
                       tomcat = false;
                    }
              if (tomcat)
                    {
                       try
                       {
                          WeldForwardingAnnotationProcessor.replaceAnnotationProcessor(sce, manager);
                          log.info("Tomcat 6 detected, JSR-299 injection will be available in Servlets, Filters etc.");
                       }
                       catch (Exception e)
                       {
                          log.error("Unable to replace Tomcat AnnotationProcessor. JSR-299 injection will not be available in Servlets, Filters etc.", e);
                       }
                    }
              boolean jetty = true;
                    try
                    {
                       Reflections.classForName(JETTY_REQUIRED_CLASS_NAME);
                    }
                    catch (IllegalArgumentException e)
                    {
                       jetty = false;
                    }
              
                    if (jetty)
                    {
                       // Try pushing a Jetty Injector into the servlet context
                       try
                       {
                          Class<?> clazz = Reflections.classForName(JettyWeldInjector.class.getName());
                          Object injector = clazz.getConstructor(WeldManager.class).newInstance(manager);
                          sce.getServletContext().setAttribute(INJECTOR_ATTRIBUTE_NAME, injector);
                          log.info("Jetty detected, JSR-299 injection will be available in Servlets, Filters etc.");
                       }
                       catch (Exception e)
                       {
                          log.error("Unable to create JettyWeldInjector. JSR-299 injection will not be available in Servlets, Filters etc.", e);
                       }
                    }
              
                    if (!tomcat && !jetty) {
                       log.info("No supported servlet container detected, JSR-299 injection will NOT be available in Servlets, Filters etc.");
                    }
                                 
                        }
              
              
              


              • 4. Re: Should seam servlet event move to weld-servlet-init?
                Pete Muir Master

                Still, struggling to understand the change you want. Please create an issue and attach your changes in unified diff format - something that we all commonly can understand!

                • 5. Re: Should seam servlet event move to weld-servlet-init?
                  he youlin Novice
                  
                  I mean i want get ServletContextEvent weld event after weld container started and before validateBeans,so i can do some init work in weld extension.And I can wrap servletContext as a weld bean in this weld event's observe then i can use the servletContext bean in all weld extension of event's observe after 
                  container started.So we can do more init work of servlet container such as tomcat or jetty servlet inject or spring's init work.
                  
                  I don't know if it can make clear.Sorry for my poor english.
                  
                  


                  • 6. Re: Should seam servlet event move to weld-servlet-init?
                    Pete Muir Master

                    Ok, I understand now. Please file an issue in https://jira.jboss.org/jira/browse/WELDSERVLET with what you wrote above as the description, and we can look at it.