13 Replies Latest reply on Dec 30, 2009 6:54 PM by asookazian

    Web Beans in Tomcat

    pmuir

      I've completed adding basic support for Tomcat. I would love any feedback or bugs - you can report bugs  in the Tomcat component of the WBX JIRA.




      A couple of open issues for the release of this



      • I would like to support Servlet injection, which involves a @PostConstruct style callback from Tomcat when it creates a Servlet instance

      • Currently we support binding the Manager to java:comp/env/app/Manager as I can't see how you can ask Tomcat to bind it to java:app/Manager



      Any Tomcat experts who can contribute this? :-)

        • 1. Re: Web Beans in Tomcat
          gavin.king

          Great, I know this is something that a lot of users requested.

          • 2. Re: Web Beans in Tomcat
            dan.j.allen

            What's more, Jetty is supported now too! To top that off, you can run the servlet-numberguess example from Maven using either embedded Jetty or embedded Tomcat (Web Beans SVN).


            cd servlet-numberguess
            mvn
            mvn war:inplace jetty:run



            or


            cd servlet-numberguess
            mvn
            mvn war:inplace tomcat:run



            Enjoy!


            Disclaimer: I still believe strongly that a servlet environment is not sufficient for the development of an enterprise application. But it is a great way to start to learn about Web Beans (parts of which work splendidly outside of Java EE).

            • 3. Re: Web Beans in Tomcat
              scheb
              Hi all,

              I currently try to set up a small example app of JSF 2.0 RI and WebBeans on Tomcat 6.0.18. Therefore I followed the instructions
              at the WebBeans docs to set up WebBeans for Tomcat (chapter 16.3 and 16.3.1) namely


              1) used following libs (maven2)

              `<dependency>
                 <groupId>org.jboss.webbeans</groupId>
                 <artifactId>jsr299-api</artifactId>
                 <scope>compile</scope>
                 <version>1.0.0-SNAPSHOT</version>
              </dependency>

              <dependency>
                 <groupId>org.jboss.webbeans.servlet</groupId>
                 <artifactId>webbeans-servlet</artifactId>
                 <version>1.0.0.CR1</version>
              </dependency>`



              2) added following lines to web.xml

               
              `<listener>
                    <listener-class>org.jboss.webbeans.environment.servlet.Listener</listener-class>
                </listener>

                  <resource-env-ref>
                      <resource-env-ref-name>
                          app/Manager
                      </resource-env-ref-name>
                      <resource-env-ref-type>
                          javax.inject.manager.Manager
                      </resource-env-ref-type>
                  </resource-env-ref>`

              3)added following lines to context.xml of Tomcat(6.0.18)

               
              `<Listener className="org.jboss.webbeans.environment.tomcat.WebBeansLifecycleListener"/>

                <Resource name="app/Manager"
                            auth="Container"
                            type="javax.inject.manager.Manager"
                            factory="org.jboss.webbeans.resources.ManagerObjectFactory"/>`

              4) finally I added the webbeans-tomcat-support.jar to the lib folder at $TOMCAT_HOME

              The sample app works quite fine except conversation scoped beans - if I want to acces such beans (second time - post access - first access works) then
              I get following exception:

              `javax.context.ContextNotActiveException: No active contexts for scope type javax.context.ConversationScoped
                   org.jboss.webbeans.ManagerImpl.getContext(ManagerImpl.java:739)
                   org.jboss.webbeans.bean.proxy.ClientProxyMethodHandler.getProxiedInstance(ClientProxyMethodHandler.java:116)
                   org.jboss.webbeans.bean.proxy.ClientProxyMethodHandler.invoke(ClientProxyMethodHandler.java:96)
                   at.irian.demo.model.GenericModel_$$_javassist_8.getAllItems(GenericModel_$$_javassist_8.java)
                   sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                   java.lang.reflect.Method.invoke(Method.java:597)
                   javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
                   javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
                   com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
                   org.apache.el.parser.AstValue.getValue(AstValue.java:118)
                   org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
                   com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:108)
                   javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:181)
                   javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:167)
                   javax.faces.component.UIData.getValue(UIData.java:551)
                   javax.faces.component.UIData.getDataModel(UIData.java:1214)
                   javax.faces.component.UIData.setRowIndex(UIData.java:444)
                   javax.faces.component.UIData.visitTree(UIData.java:1150)
                   javax.faces.component.UIComponent.visitTree(UIComponent.java:1453)
                   javax.faces.component.UIForm.visitTree(UIForm.java:328)
                   javax.faces.component.UIComponent.visitTree(UIComponent.java:1453)
                   com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:326)
                   com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:183)
                   com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:131)
                   com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:292)
                   com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:155)
                   com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:199)
                   com.sun.faces.lifecycle.Phase.doPhase(Phase.java:103)
                   com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:110)
                   com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
                   javax.faces.webapp.FacesServlet.service(FacesServlet.java:310)`

              Does anyone have a clue what the problem could be here?



              • 4. Re: Web Beans in Tomcat
                dan.j.allen

                Yes, currently if you have <f:view> in your template using JSF 2.0, the conversation does not propagate properly. I still haven't gotten around to reporting the issue yet. Try to remove <f:view> (you don't need it anyway).

                • 5. Re: Web Beans in Tomcat
                  scheb

                  Thanks for your quick reply,


                  unfortunately I have no

                  <f:view>

                  tag in place - so this could not be the problem in my case -
                  do you have any other idea what I am doing wrong here (or can you give me a hint where I should look in the
                  source ...) ?

                  • 6. Re: Web Beans in Tomcat
                    scheb

                    Berthold Scheuringer wrote on May 06, 2009 15:15:


                    Thanks for your quick reply,

                    unfortunately I have no
                    <f:view>

                    tag in place - so this could not be the problem in my case -
                    do you have any other idea what I am doing wrong here (or can you give me a hint where I should look in the
                    source ...) ?


                    Update on my post:


                    I stepped a little bit into the WebBeans code and found out that the conversation propagation works as expected - BUT: the problem which I encountered is
                    that the conversation gets restored AFTER the RestoreView phase but in my app I have an EL expression directly on the view which resolves to a conversation
                    scoped bean - therefore I need the conversation to be restored BEFORE the RestoreView phase.


                    Could be that I have overseen smthg but could someone clarify WHEN the conversation should be restored ?

                    • 7. Re: Web Beans in Tomcat
                      gavin.king

                      I stepped a little bit into the WebBeans code and found out that the conversation propagation works as expected - BUT: the problem which I encountered is that the conversation gets restored AFTER the RestoreView phase

                      This has always been the behavior in Seam, and is the behavior that is defined in the 299 spec. The conversation id is embedded in the view, so it's not available until after the view has been restored.

                      • 8. Re: Web Beans in Tomcat
                        dan.j.allen

                        This is a new problem in JSF 2. Apparently, JSF 2 is walking the tree in the Restore View phase, whereas JSF 1 does not. The timing causes a problem if you have a value expression bound to a conversation-scoped bean. You would get the same problem in Seam too, for the reason Gavin explained. The conversation has always been restored at the end of the restore view phase.


                        Here's my simple test:


                        DataList.java


                        public
                        @Named
                        @ConversationScoped
                        class DataList implements Serializable {
                        
                             private List<Data> data;
                             private DataModel dataModel;
                        
                             @PostConstruct
                             public void onCreate() {
                                  data = new ArrayList<Data>();
                                  data.add(new Data("one"));
                                  data.add(new Data("two"));
                             }
                        
                             public List<Data> getData() {
                                  return data;
                             }
                        
                             public DataModel getDataModel() {
                                  if (dataModel == null) {
                                       dataModel = new ListDataModel(data);
                                  }
                        
                                  return dataModel;
                             }
                        
                             public void act() {
                                  System.out.println(dataModel.getRowData());
                             }
                        }




                        Data.java


                        public class Data {
                        
                             private String value;
                        
                             public Data() {
                             }
                        
                             public Data(String value) {
                                  this.value = value;
                             }
                        
                             public String getValue() {
                                  return value;
                             }
                        
                             @Override
                             public String toString() {
                                  return "Data" + hashCode() + "[ value = " + value + " ]";
                             }
                        }



                        dataList.xhtml


                              <h:form>
                                 <h:dataTable var="_data" value="#{dataList.dataModel}">
                                    <h:column>
                                       <f:facet name="header">Value</f:facet>
                                       <h:commandLink action="#{dataList.act}" value="#{_data.value}"/>
                                    </h:column>
                                 </h:dataTable>
                              </h:form>



                        Works in JSF 1. Doesn't work in JSF 2.

                        • 9. Re: Web Beans in Tomcat
                          dan.j.allen

                          Btw, this has nothing to do with Tomcat. This issue should be logged in JIRA (or in the JSF 2 issue tracker if we decide that is the issue) and we should discuss in a different thread.

                          • 10. Re: Web Beans in Tomcat
                            dan.j.allen

                            For JSF 2, we should listen for JSF events rather than use a phase listener to get more robust conversation control. So this does tie into my original comment about <f:view>. Conversations currently have problems with JSF 2.

                            • 11. Re: Web Beans in Tomcat
                              scheb

                              Yes, the impl does exactly what it should do concerning the spec and as you said thats currently not sufficient for JSF 2.0.
                              This topic therefore needs some more discussion (not in that thread - has nothing to do with Tomcat) - so please
                              let me/us know where the topic will go to - to be able to follow it up...


                              Thanks for the clarification!

                              • 12. Re: Web Beans in Tomcat
                                dan.j.allen

                                I'll start a new thread in this forum. This might be something we need a hook for in JSF. Here is the issue report https://jira.jboss.org/jira/browse/WBRI-258.

                                • 13. Re: Web Beans in Tomcat
                                  asookazian

                                  Dan Allen wrote on Apr 30, 2009 20:34:


                                  Disclaimer: I still believe strongly that a servlet environment is not sufficient for the development of an enterprise application. But it is a great way to start to learn about Web Beans (parts of which work splendidly outside of Java EE).


                                  I would like to know exactly what APIs we'd be missing out on if we chose the Weld/Tomcat route.  I'm guessing anything that requires an EJB container so EJB 3.1 components are out of the questions with Weld/Tomcat.


                                  What else?


                                  I think this would be a good migration path for current Spring 2.x apps running on Tomcat prod envmts.  It's easier to adopt new technologies/APIs on your existing app server (servlet container in this case) than to be forced to migrate to an EE6 certified app server like JBoss 6 or Glassfish v3.  Also, integration with EE6 and Spring 2.x/3 may be easier if using the existing servlet container.


                                  Also, if I'm currently using JBoss 4.2.2.GA, can I deploy JSF2/Weld/JPA2 apps in that app server?  If yes, is there a detailed tutorial knowing that JBoss 4.x ships with JSF 1.x libs out-of-the-box in this path: %JBOSS_HOME%\server\default\deploy\jboss-web.deployer\jsf-libs



                                  Apache Tomcat version 6.0 implements the Servlet 2.5 and JavaServer Pages 2.1 specifications from the Java Community Process

                                  http://tomcat.apache.org/tomcat-6.0-doc/index.html


                                  So I'm guessing if I use Tomcat 6.0 with Weld 1.0, JPA 2.0, and JSF 2.0 then I'll miss out on Servlet 3.0 as well, correct?


                                  What version of Tomcat (which is what jbossweb is based on, correct?) is packaged in JBoss 6?


                                  C:\java\jboss-6.0.0.M1\server\default\deploy\jbossweb.sar