13 Replies Latest reply: Dec 30, 2009 6:54 PM by Arbi Sookazian RSS

Web Beans in Tomcat

Pete Muir Master

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 Master

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

  • 2. Re: Web Beans in Tomcat
    Dan Allen Master

    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
    Berthold Scheuringer Newbie
    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 Allen Master

    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
    Berthold Scheuringer Newbie

    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
    Berthold Scheuringer Newbie

    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 Master

    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 Allen Master

    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 Allen Master

    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 Allen Master

    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
    Berthold Scheuringer Newbie

    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 Allen Master

    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
    Arbi Sookazian Master

    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