10 Replies Latest reply on Jun 13, 2008 4:47 PM by gaboo.gael.livre-rare-book.com

    Create reusable self-contained modules

    henrikniehaus

      Hi all,


      I'm a seam greenhorn and have to evaluate the feasibility of creating reusable self-contained modules for web-applications. Think of a login box like the one of seamframework.org as an example of such a module.
      This module would provide the jsf/facelets ui and some seam-component, which does the authentication/authorisation.


      Our goal is, to have this module in a jar file, which can be deployed along with main application. Maybe in WEB-INF/lib.


      The main-application would then be just some kind of a composition of several modules. Maybe this could work with the facelet composition abilities.


      Is there a chance to realize something like this? How would you do it? I need a starting point to familiarize myself with the whole seam/module thing ;-)


      BR
      Henrik

        • 1. Re: Create reusable self-contained modules
          gerhard6

          Henrik


          Maybe you found already a solution for this.


          Nevertheless, let me add, that I was thinking about such an approach a few weeks ago, and I formulated the problem in my blog, and luckily yesterday, I had time to setup a solution, which seems to work, see here.


          Hope, it helps.


          Gerhard

          • 2. Re: Create reusable self-contained modules
            henrikniehaus

            Thank you, Gerhard


            I really found a solution on my own. Actually it is the same you mentioned on your blog. Just to mention it in this forum for other users: I implemented a custom ResourceResolver, which uses the ClassLoader to resolve and load resources. I think it is a very good solution because of the following points:



            • You can package all stuff of a component/module into one or two jar files

            • With the composition abilities of facelets you can put all modules together to one big application

            • If you don't like the facelets included in the jars, you can still place them in the WEB-INF/classes folder and overwrite them with custom ones.



            Best regards,
            Henrik

            • 3. Re: Create reusable self-contained modules
              gerhard6

              Henrik


              Good to hear that we are somehow on the same path.... :-)


              Having the result of being able to encapsulate seam-components as jars, and reusing them in war's, I'm right now playing around in eclipse, trying to get efficient as a developer:


              Having such a JAR and a WAR project opened, and changing things in JAR-files: Do we have an efficient redeployment of those things:


              1. for xhtml files, this works for me: Simply saving it ,wait a few seconds, and refresh the web page. Fine


              2. for Java files, I've some problems: I WANT to use the Incremental Hot Deployment (see Chap 2.7 in http://docs.jboss.com/seam/1.2.1.GA/reference/en/html/gettingstarted.html)
              This is implemented by having the WEB-INF/dev directory of the WAR project, and placing the re-deployed class files there.


              As an experiment, I manually copied a (new) class file of my JAR project into that directory. The effect was:


                 A) NOT restarting JBOSS: nothing happened (unclear)


                 B) after restarting JBOSS (not the desired way to do it),I got  the error, that Seam then sees/complains, that class file twice (once in the  WEB-INF/dev directory, and the second time in the deployed JAR.


              Seeing this, I conclude, that I would have to change the JAR-Project in Eclipse in a quite unusual way, to get the desired file placement (not deploying the JAR-class-files  as part of the JAR-project, but in the WEB-INF/dev directory instead).



              Henrik, are you still on the same path as I ? Any opinion on the things stated above? Anyone else ?


              Thanks, Gerhard




              • 4. Re: Create reusable self-contained modules
                gaboo.gael.livre-rare-book.com

                I've tried using the ResourceResolver from flexive, but I get :


                10:48:31,365 WARN  [lifecycle] executePhase(RENDER_RESPONSE 6,com.sun.faces.context.FacesContextImpl@14580e3) threw exception          
                javax.faces.FacesException: Error Initializing ResourceResolver[xxx.ClasspathResourceResolver]
                [...]
                java.lang.ClassCastException: xxx.ClasspathResourceResolver cannot be cast to com.sun.facelets.impl.ResourceResolver
                



                Do you have any idea ?


                It's a seam project, I've updated web.xml and included the extended DefaultResourceResolver. Sould the extended class be put somewhere special ?

                • 5. Re: Create reusable self-contained modules
                  gerhard6

                  Hello Gaël


                  You have compiled the ClasspathResourceResolver yourself ?


                  Not sure, perhaps you have more than one facelets-jar in your project/classpath.


                  hth, Gerhard

                  • 6. Re: Create reusable self-contained modules
                    gaboo.gael.livre-rare-book.com

                    You have compiled the ClasspathResourceResolver yourself ?


                    Yes. It's in my seam project.



                    Not sure, perhaps you have more than one facelets-jar in your project/classpath.


                    Yes, I have one in my seam project. But it was not found in there when deploying, I had to put it also in jboss/server/default/lib/


                    But it's the same one.

                    • 7. Re: Create reusable self-contained modules
                      gerhard6

                      I think, that having the same JAR twice IS the reason for your problem: Most likely JBoss loads the class file from BOTH locations, and therefore fails.


                      So, get rid of one of them.


                      Just looked at my example: I have the facelet JAR in  WEB-INF/lib, and NOT in jboss.../default/lib directory.


                      hth, Gerhard

                      • 8. Re: Create reusable self-contained modules
                        gaboo.gael.livre-rare-book.com

                        Ok, i've fixed this. But still no luck. I've tried with a brand new seam application generated with seam-gen. Only add the custom ResourceResolver and updated web.xml accordingly. Doesn't work.


                        I've seen that the wiki example in trunk (not the 2.0.X version) have a custom resource resolver. So I'm starting to thing that :


                        either it only works with seam trunk, aka future 2.1 version.
                        either there are some config, packaging issues that I'm not aware of and that are driving me nuts.


                        The structure and build.xml of my application has been initially generated by seam-gen. It's not exactly the same as the wiki example one for instance.


                        An information is that it deplots correctly, but fail when I first access the web site.


                        I've also removed the web.xml parameter and tried the code in facelets that triggers the ClassCastException manually : it runs ok. For information, here it is :



                        protected FaceletFactory createFaceletFactory(Compiler c) {
                        
                                // refresh period
                                long refreshPeriod = DEFAULT_REFRESH_PERIOD;
                                FacesContext ctx = FacesContext.getCurrentInstance();
                                String userPeriod = ctx.getExternalContext().getInitParameter(
                                        PARAM_REFRESH_PERIOD);
                                if (userPeriod != null && userPeriod.length() > 0) {
                                    refreshPeriod = Long.parseLong(userPeriod);
                                }
                        
                                // resource resolver
                                ResourceResolver resolver = new DefaultResourceResolver();
                                String resolverName = ctx.getExternalContext().getInitParameter(
                                        PARAM_RESOURCE_RESOLVER);
                                if (resolverName != null && resolverName.length() > 0) {
                                    try {
                                        // it fails here exactly :
                                        resolver = (ResourceResolver) ReflectionUtil.forName(resolverName)
                                                .newInstance();
                                    } catch (Exception e) {
                                        throw new FacesException("Error Initializing ResourceResolver["
                                                + resolverName + "]", e);
                                    }
                                }
                        
                                // Resource.getResourceUrl(ctx,"/")
                                return new DefaultFaceletFactory(c, resolver, refreshPeriod);
                            }




                        I'm trying all sort of thing, but still no luck. But it seams a packaging issue.


                        Here is the full stack trace in case it helps :



                        15:09:50,161 WARN  [lifecycle] executePhase(RENDER_RESPONSE 6,com.sun.faces.context.FacesContextImpl@28f1d6) threw exception           
                        javax.faces.FacesException: Error Initializing ResourceResolver[com.lrb.metabook.core.MetabookFaceletsResourceResolver]                
                                at com.sun.facelets.FaceletViewHandler.createFaceletFactory(FaceletViewHandler.java:244)                                       
                                at com.sun.facelets.FaceletViewHandler.initialize(FaceletViewHandler.java:162)                                                 
                                at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:537)                                                 
                                at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:108)                                         
                                at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:216)                                               
                                at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)                                           
                                at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)                                                         
                                at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)                                                        
                                at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)                                                              
                                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)                           
                                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)                                   
                                at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:654)                                       
                                at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:445)                               
                                at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379)                                    
                                at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:292)                                      
                                at org.tuckey.web.filters.urlrewrite.NormalRewrittenUrl.doRewrite(NormalRewrittenUrl.java:195)                                 
                                at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:159)                                               
                                at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:141)                                                     
                                at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:90)                                           
                                at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:406)                                      
                                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)                           
                                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)                                   
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)                                              
                                at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85)                                                        
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)                                              
                                at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)                                                        
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)                                              
                                at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)                                                          
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)                                              
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:73)                                              
                                at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)                                                       
                                at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)                                                                
                                at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60)                                                          
                                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.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:68)                                                  
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)                                              
                                at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)                                                             
                                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)                           
                                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)                                   
                                at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)                                          
                                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)                           
                                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)                                   
                                at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)                                         
                                at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)                                         
                                at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)                            
                                at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)                                      
                                at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)                                             
                                at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)                                               
                                at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)                                               
                                at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)                               
                                at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)                                           
                                at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)                                                 
                                at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)                                                  
                                at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)                            
                                at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)                                                     
                                at java.lang.Thread.run(Thread.java:619)                                                                                       
                        Caused by: java.lang.ClassCastException: com.lrb.metabook.core.MetabookFaceletsResourceResolver cannot be cast to com.sun.facelets.impl.ResourceResolver
                                at com.sun.facelets.FaceletViewHandler.createFaceletFactory(FaceletViewHandler.java:241)                                                        
                                ... 57 more                                                                                                                                     
                        15:09:50,170 ERROR [[Faces Servlet]] "Servlet.service()" pour la servlet Faces Servlet a lancé une exception                                            
                        java.lang.ClassCastException: com.lrb.metabook.core.MetabookFaceletsResourceResolver cannot be cast to com.sun.facelets.impl.ResourceResolver           
                                at com.sun.facelets.FaceletViewHandler.createFaceletFactory(FaceletViewHandler.java:241)                                                        
                                at com.sun.facelets.FaceletViewHandler.initialize(FaceletViewHandler.java:162)                                                                  
                                at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:537)                                                                  
                                at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:108)                                                          
                                at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:216)                                                                
                                at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:106)                                                            
                                at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)                                                                          
                                at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)                                                                         
                                at javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)                                                                               
                                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)                                            
                                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)                                                    
                                at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:654)                                                        
                                at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:445)                                                
                                at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379)                                                     
                                at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:292)                                                       
                                at org.tuckey.web.filters.urlrewrite.NormalRewrittenUrl.doRewrite(NormalRewrittenUrl.java:195)                                                  
                                at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:159)                                                                
                                at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:141)                                                                      
                                at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:90)                                                            
                                at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:406)                                                       
                                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)                                            
                                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)                                                    
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)                                                               
                                at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85)                                                                         
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)                                                               
                                at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)                                                                         
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)                                                               
                                at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)                                                                           
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)                                                               
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:73)                                                               
                                at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)                                                                        
                                at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)                                                                                 
                                at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60)                                                                           
                                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.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:68)                                                                   
                                at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)                                                               
                                at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)                                                                              
                                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)                                            
                                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)                                                    
                                at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)                                                           
                                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)                                            
                                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)                                                    
                                at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)                                                          
                                at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)                                                          
                                at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)                                             
                                at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)                                                       
                                at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)                                                              
                                at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)                                                                
                                at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)                                                                
                                at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)                                                
                                at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)                                                            
                                at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)                                                                  
                                at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)                                                                   
                                at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)                                             
                                at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)                                                                      
                                at java.lang.Thread.run(Thread.java:619


                        • 9. Re: Create reusable self-contained modules
                          gerhard6

                          Hmm


                          I'm using seam 2.0.2.GA.


                          One more thing, that could perhaps hurt is the way, things get deployed in eclipse/seam: there are 2 ways: one of them writes into WEB-INF/dev which uses the Incremental Deployment (http://docs.jboss.com/seam/1.2.1.GA/reference/en/html/gettingstarted.html) and therefore a separate classloader. I think that the action source folder is mapped to this place. Maybe you have your ResourceResolver Class in that, try to move it into the model source folder.


                          One more thing to try,I dont know, if you already did:
                          Dont use the eclipse-internal deployment, package your application (to a WAR, I assume), and try it with that. Perhaps that works...



                          • 10. Re: Create reusable self-contained modules
                            gaboo.gael.livre-rare-book.com

                            Gerhard,


                            Thanks for your help!


                            I've checked for what you've said. Not better.


                            I've been spending days on this issue and I guess I'll just forgive for now. I've tried repackaging my application in every way I could think of : standard jboss app with ear and classes in jar, without ear, like wiki example (all in a war), spliting files, checking for duplicate jars, etc.


                            I think I got a setup where it was working, but all the other parts of my application weren't (like persistence, seam components, etc). These xml all over the place look like magic to me and when you don't understand exactly how all this works it's hell :)


                            There must be something simple I'm missing and it would need someone really knowledgeable about this to look closely at it.


                            I'll just go on with something else maybe I'll have an 'eureka' some day !