0 Replies Latest reply on Aug 28, 2010 4:09 AM by lam nguyen phuc

    JSFUnit with Apache Myfaces Orchestra

    lam nguyen phuc Newbie

      Over the last few days, I have tried to use JSFUnit to test a Orchestra-based web application. It worked fine when I tested pages which only used Conversation Manual Scope Bean. However, things went wrong when I tested pages associated with Conversation Access Scope Bean. The root cause I got was:

       

      Caused by: java.lang.IllegalArgumentException: Orchestra was unable to create an instance of bean with name 'AccessScopeManager'. Ensure that JSF variable resolution uses your dependency injection (DI) framework (eg Spring's DelegatingVariableResolver is in your faces-config.xml file) and the standard Orchestra configuration beans are defined (eg by using <import resource="classpath*:/META-INF/spring-orchestra-init.xml" />).
              at org.apache.myfaces.orchestra.conversation.AccessScopeManager.getInstance(AccessScopeManager.java:98)
              at org.apache.myfaces.orchestra.conversation.ConversationAccessLifetimeAspect.markAsAccessed(ConversationAccessLifetimeAspect.java:35)
              at org.apache.myfaces.orchestra.conversation.spring.SpringConversationScope.notifyAccessConversation(SpringConversationScope.java:197)
              at org.apache.myfaces.orchestra.conversation.spring.AbstractSpringOrchestraScope.getRealBean(AbstractSpringOrchestraScope.java:366)
              at org.apache.myfaces.orchestra.conversation.spring.ScopedBeanTargetSource.getTarget(ScopedBeanTargetSource.java:76)
              at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.getTarget(Cglib2AopProxy.java:657)
              at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:608)
              at vn.csp.duchoa.webmodule.model.ManageUnitTypeBackingBean$EnhancerByCGLIB$39e14763.getData(<generated>)
              ... 56 more
       
      
      
      

       

      After a couple of days trying to debug and searching for a workaround, I have found out a solution. I start this discussion to  share with other people who may come across this problem.

       

      The workaround is to follow the installation guide available at : http://myfaces.apache.org/orchestra/myfaces-orchestra-core/installation.html . However, instead of using

       

      org.apache.myfaces.orchestra.frameworkAdapter.basic.BasicFrameworkAdapterFilter
      

      , you should use

      org.apache.myfaces.orchestra.frameworkAdapter.jsf.JsfFrameworkAdapterFilter     
      

       

      This is because while JsfFrameworkAdapterFilter creates JsfFrameworkAdapter which use a VariableResolver instance to search for a required bean, BasicFrameworkAdapterFilter creates BasicFrameworkAdapter which only search for a particular bean in request or session scope. Moreover, when an Access Scope bean is accessed, Orchestra will mark the current Conversation accessed by calling this method :

       

       

      org.apache.myfaces.orchestra.conversation.ConversationAccessLifetimeAspect.markAsAccessed()
      

       

      This method in turn get the AccessScopeManager instance by calling

       

      org.apache.myfaces.orchestra.conversation.AccessScopeManager.getInstance()
      

       

      Take a look at the code inside method getInstance(), you can see that it calls FrameworkAdapter.getBean(String name) to get the AccessScopeManager. If JsfFrameworkAdapter is used, it can create a AccessScopeManager instance because AccessScopeManager bean is configured as a request scope bean in Orchestra's Spring configuration file. On the other hand, exception will be thrown if BasicFrameworkAdapter is used because BasicFrameworkAdapter instance can only get bean instances in the request or session scope.

       

      Here is a fragment of web.xml to enable you test Orchestra-based web application with JSFUnit:

       

       

      ...
      <filter>
              <filter-name>frameworkAdapterFilter</filter-name>
              <filter-class>org.apache.myfaces.orchestra.frameworkAdapter.jsf.JsfFrameworkAdapterFilter</filter-class>
      </filter>
      <filter>
              <filter-name>requestParameterFilter</filter-name>
              <filter-class>org.apache.myfaces.orchestra.requestParameterProvider.RequestParameterServletFilter</filter-class>
      </filter>
      
      <filter>
              <filter-name>JSFUnitFilter</filter-name>
              <filter-class>org.jboss.jsfunit.framework.JSFUnitFilter</filter-class>
      </filter>
      
      <filter-mapping>
              <filter-name>frameworkAdapterFilter</filter-name>
              <servlet-name>ServletRedirector</servlet-name>
              <dispatcher>REQUEST</dispatcher>
              <dispatcher>FORWARD</dispatcher>
      </filter-mapping>
      <filter-mapping>
              <filter-name>requestParameterFilter</filter-name>
              <servlet-name>ServletRedirector</servlet-name>
              <dispatcher>REQUEST</dispatcher>
              <dispatcher>FORWARD</dispatcher>
      </filter-mapping>
      
      <filter-mapping>
              <filter-name>JSFUnitFilter</filter-name>
              <servlet-name>ServletTestRunner</servlet-name>
          </filter-mapping>
          <filter-mapping>
              <filter-name>JSFUnitFilter</filter-name>
              <servlet-name>ServletRedirector</servlet-name>
      </filter-mapping>
      
      <servlet>
              <servlet-name>ServletRedirector</servlet-name>
              <servlet-class>org.apache.cactus.server.ServletTestRedirector</servlet-class>
      </servlet>
      
      <servlet>
              <servlet-name>ServletTestRunner</servlet-name>
              <servlet-class>org.apache.cactus.server.runner.ServletTestRunner</servlet-class>
      </servlet>
      
      <servlet-mapping>
              <servlet-name>ServletRedirector</servlet-name>
              <url-pattern>/ServletRedirector</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
              <servlet-name>ServletTestRunner</servlet-name>
              <url-pattern>/ServletTestRunner</url-pattern>
      </servlet-mapping>
      ...