8 Replies Latest reply on Mar 22, 2009 11:31 PM by Walter White

    Seam Components

    Walter White Novice

      Hi all,


      I am close to getting my application up and running on SEAM with RichFaces.  I am following an example from the Seam Project (hibernate).


      I am using the jetty plugin right now to do all of my testing as it is quicker than Tomcat.  The issue I suspect I'm having is none of my components are getting registered, I have a servlet filter which is supposed to capture all requests and log them to a database.  The database is not touched at all.  Secondly, any page that references a component does not work and returns a 404 Page Not Found Error.  I don't have much information in a log file and am wondering what I can do to increase the verbosity and locate the bug in my code or configuration.  I have log4j set to be in DEBUG mode and I do not see any exceptions anywhere.


      Another detail I should point out is, in Maven, I have broken up my application into smaller chunks and am packaging them as EJBs.  Should I package them as an EJB or just JAR since they're really not EJBs?


      Please let me know if you need more information.



      Thanks,
      Walter

        • 1. Re: Seam Components
          Arbi Sookazian Master

          recommend starting over with Tomcat or JBoss 4/5 AS and seam-gen your project skeleton (run 'seam setup' and then 'seam create-project' from cmd line) and revengr your entities as required (run 'seam generate-entities').


          This is the recommended approach for Seam newbies b/c it is fast and seam-gen will minimize your config errors in the xml files (config.xml, web.xml and faces-config.xml especially).

          • 2. Re: Seam Components
            Walter White Novice

            Hi,


            Thanks for your reply; however, I was lucky to come across this post:


            My Link


            What happened is, I was including Seam as a dependency along with the other components, Seam-ioc, Seam-mail, etc.  I also added empty seam.properties files to all my projetcs and now it scans my ejbs as expected.  It still does not yet work, but that is mostly due to my lack of understanding of EJB3 at this point.


            I'm fixing my mappings of Stateless/Stateful session beans, I'll post any further updates.



            Thanks,
            Walter

            • 3. Re: Seam Components
              Walter White Novice

              Hi all,


              I am much closer; however, I cannot get a hibernate session injected into my servlet filters:



              org.jboss.seam.RequiredException: @In attribute requires non-null value: authenticationFailureEventFilter.hibernateSession
              





              components.xml



              <persistence:hibernate-session-factory name="hibernateSessionFactory"/>
                   <persistence:managed-hibernate-session name="hibernateSession"
                        session-factory-jndi-name="${jdbc.database.jndiName}"
                        session-factory="#{hibernateSessionFactory}"
                        auto-create="true"/>
                   <transaction:hibernate-transaction session="#{hibernateSession}"/>
              



              HttpSessionFilter.java


              @Startup
              @Scope(ScopeType.APPLICATION)
              @Name("httpSessionFilter")
              @BypassInterceptors
              //@Filter(within = "org.jboss.seam.web.contextFilter")
              @Filter(within = "org.jboss.seam.web.ajax4jsfFilter")
              public class HttpSessionFilter extends AbstractFilter
              {
                   @Logger
                   protected Log log;
                   @In
                   protected HibernateEntityQuery<Session> sessionQuery;
                   @In
                   protected org.hibernate.Session hibernateSession;
              



              I have read a little bit online, but I'm not sure what else I may be missing.  The spelling appears to be correct, so I'm not sure what else I may be missing.



              Thanks,
              Walter

              • 4. Re: Seam Components
                Walter White Novice

                Hi,


                I forgot to post the stack trace with the error:


                Mar 15, 2009 9:47:42 AM com.sun.faces.config.ConfigureListener contextInitialized
                INFO: Initializing Mojarra (1.2_12-b01-FCS) for context ''
                09:47:44,078 DEBUG [Component] trying to inject with hierarchical context search: hibernateSession
                2009-03-15 09:47:44.079::WARN:  failed Seam Filter
                org.jboss.seam.RequiredException: @In attribute requires non-null value: authenticationFailureEventFilter.hibernateSession
                



                Please let me know what else to check.



                Thanks,
                Walter

                • 5. Re: Seam Components
                  Walter White Novice

                  Hi all,


                  I am getting much further now.  It seems the problem I am having is that I cannot inject a seam component into my servlet filter.  I updated my code to not use @In.  When the init() method of the servlet filter is called, I attempt to get the seam component, hibernateSession.  It is null.


                  Is there anyway I can get the hibernateSession to be initialized prior to the servlet filter?



                  Thanks,
                  Walter

                  • 6. Re: Seam Components
                    Walter White Novice

                    Hi all,


                    I think I figured it out ... In a nutshell, to get a Seam component into a Servlet Filter, you cannot use the @In annotation currently; however, you can use Component.getInstance(beanName) provided your Filter is properly configured:


                    @Startup
                    @Scope(APPLICATION)
                    @Name("httpSessionFilter")
                    @BypassInterceptors
                    @Filter(within = "org.jboss.seam.web.contextFilter")
                    public class HttpSessionFilter extends AbstractFilter
                    {
                    ...
                    



                    The @Filter annotation with the context filter gives you access to the context which then gives you the ability to get Seam components.  While Components.getInstance() is not pretty, it gets the job done.


                    Is there any way around this?


                    In the meantime, I have Seam working on Jetty 6x!!!



                    Walter

                    • 7. Re: Seam Components
                      Walter White Novice

                      Hi all,


                      I am currently having an issue persisting my HttpSession object in my HttpSessionFilter ServletFilter.  The HttpSessionFilter tracks how long a request takes to process and stores request information into the database.  At the beginning of the request, if the HttpSession has not yet been persisted to the database, I will store it.  At that point in time, the context is still active, but after I call chain.doFilter(...), the context has been removed, and I can no longer persist the new session history object.


                      Am I doing something wrong, or is the context not meant to be used this way?


                      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
                                                              throws IOException, ServletException
                           {
                                HttpServletRequest request = (HttpServletRequest)servletRequest;
                                HttpServletResponse response = (HttpServletResponse)servletResponse;
                      
                                hibernateSession = (Session)Component.getInstance("hibernateSession");
                      
                                // start recording the runtime
                                HttpSession cachedSession =
                                     (HttpSession)hibernateSession.createCriteria(HttpSession.class).add(Property.forName("sessionId").eq(request.getSession().getId()))
                                                                                                            .uniqueResult();
                      
                                // create the session if it doesn't already exist
                                if((cachedSession == null) || (cachedSession.getId() == null))
                                {
                                     log.debug("cached session is null, creating new session.");
                                     cachedSession = new HttpSession();
                                     cachedSession.setBrowserName(request.getHeader("User-Agent"));
                                     cachedSession.setSessionId(request.getSession().getId());
                                     cachedSession.setRemoteAddress(request.getRemoteAddr());
                      
                                     try
                                     {
                                          // ensure the user agent string is within limits
                                          final Length lengthAnnotation = HttpSession.class.getMethod("getBrowserName").getAnnotation(Length.class);
                      
                                          if(lengthAnnotation != null)
                                          {
                                               if(cachedSession.getBrowserName().length() > lengthAnnotation.max())
                                               {
                                                    // truncate the browser name
                                                    cachedSession.setBrowserName(cachedSession.getBrowserName().substring(0, lengthAnnotation.max() - 1));
                                                    log.debug("truncated browser name:" + cachedSession.getBrowserName());
                                               }
                                          }
                                     }
                                     catch(Exception e)
                                     {
                                          log.error("failed to truncate browser name", e);
                                     }
                      
                                     // save the session
                                     log.debug("about to persist cached session");
                                     hibernateSession.persist(cachedSession);
                                     log.debug("persisted cached session:" + cachedSession.getId());
                                }
                      
                                long startTime = System.nanoTime();
                      
                                // get the servlet response
                                chain.doFilter(request, response);
                      
                                long endTime = System.nanoTime();
                      
                                // convert this number to seconds
                                double runtime = (endTime - startTime) / 1000000000.00;
                      
                                // save the session history for this request
                                log.debug("about to persist http session history");
                                hibernateSession.persist(new HttpSessionHistory(cachedSession, request, runtime));
                           }
                      




                      Thanks,
                      Walter

                      • 8. Re: Seam Components
                        Walter White Novice

                        Hi all,


                        I fixed the problem by wrapping the second half the the filter in a ContextHttpServletRequest.  While it works, it doesn't seem to be a very elegant solution to this particular problem.


                        The session and session history is now persisted to the database as expected; however, I must use hibernateSession.flush() in order to actually have it be persisted.  I tried to use transaction demarcation for this method, but that didn't work.


                        The new problem I am concerned about now is no Active Event Context.  I do not get this exception anywhere in my code, it is only in Seam code:


                        2009-03-22 17:54:53.582::WARN:  /debug.xhtml
                        java.lang.IllegalStateException: No active event context
                             at org.jboss.seam.core.Manager.instance(Manager.java:368)
                             at org.jboss.seam.servlet.ContextualHttpServletRequest.run(ContextualHttpServletRequest.java:55)
                             at org.jboss.seam.web.ContextFilter.doFilter(ContextFilter.java:37)
                             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                             at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
                             at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
                             at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:390)
                             at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:517)
                             at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
                             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                             at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
                             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                             at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
                             at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                             at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
                             at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1139)
                             at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:378)
                             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:765)
                             at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417)
                             at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
                             at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
                             at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
                             at org.mortbay.jetty.Server.handle(Server.java:324)
                             at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:535)
                             at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:865)
                             at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:539)
                             at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
                             at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
                             at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
                             at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
                        



                        I have an error.xhtml page (I am also using .xhtml as my web extension and not .seam), but for some reason, it is using debug.xhtml?



                        Walter