JBossWiki : StaticAnalysis
Wiki Home: StaticAnalysis [EN]
[Permalink]
[Recent Changes]
[History]
[RSS Feed][RDF Feed][Atom Feed][Print]

Your trail: StaticAnalysis
It's better to always "fail fast" during a build, than to possibly fail during runtime.

JSFUnit provides a set of unit tests for static analysis of JSF applications:
org.jboss.jsfunit.analysis.AbstractFacesConfigTestCase and org.jboss.jsfunit.analysis.AbstractTldTestCase . These classes have been checked into the Subversion repository, but they are not released yet.

Extending org.jboss.jsfunit.analysis.AbstractViewTestCase

%%(color:green)
public class ViewTestCase extends org.jboss.jsfunit.analysis.AbstractViewTestCase {

	private static Set absoluteViewPaths = new HashSet<String>() {{
		add("C:/work/project/src/home.xhtml");
	}};
	
	private static Set recursiveViewPaths = new HashSet<String>() {{
		add("C:/work/project/src/views");
	}};
	
	public MyViewTestCase() {

		super(absoluteViewPaths, recursiveViewPaths, 
				"C:/work/project/src/faces-config.xml");
	}

}
%%

Do any of your facelets templates or well formed JSPs reference nonexistent managed beans?

<h:commandButton value="Home" action="#{missingBean.myAction}" />
%%(color:red)junit.framework.AssertionFailedError: C:/work/workspace/jsf-unit/src/views/home.xhtml has an EL expression '#{missingBean.myAction}' which references a managed bean 'missingBean', but no managed bean by this name can be found.%%

<h:commandButton value="Home" actionListener="#{missingBean.myActionListener}" />
%%(color:red)junit.framework.AssertionFailedError: C:/work/workspace/jsf-unit/src/views/home.xhtml has an EL expression '#{missingBean.myActionListener}' which references a managed bean 'missingBean', but no managed bean by this name can be found.%%

<h:commandButton value="Home">
	<f:actionListener binding="#{missingBean.myOtherActionListener}" />
</h:commandButton>		
%%(color:red)junit.framework.AssertionFailedError: C:/work/workspace/jsf-unit/src/views/home.xhtml has an EL expression '#{missingBean.myOtherActionListener}' which references a managed bean 'missingBean', but no managed bean by this name can be found.%%

Do any of your templates or JSPs have EL expressions for nonexistent managed bean actions or action listeners?

<h:commandButton value="Home" action="#{managedBean.myAction}" />
%%(color:red)junit.framework.AssertionFailedError: C:/work/workspace/jsf-unit/src/views/home.xhtml contains EL #{managedBean.myAction}, but managed bean managedBean->org.jboss.jsfunit.demo.ManagedBean does not have a myAction method.%%

<h:commandButton value="Home" actionListener="#{managedBean.myActionListener}" />
%%(color:red)junit.framework.AssertionFailedError: C:/work/workspace/jsf-unit/src/views/home.xhtml contains EL #{managedBean.myActionListener}, but managed bean managedBean->org.jboss.jsfunit.demo.ManagedBean does not have a myActionListener method.%%

<h:commandButton value="Home">
	<f:actionListener binding="#{managedBean.myOtherMissingActionListener}" />
</h:commandButton>
%%(color:red)junit.framework.AssertionFailedError: C:/work/workspace/jsf-unit/src/views/home.xhtml contains EL #{managedBean.myOtherMissingActionListener}, but managed bean managedBean->org.jboss.jsfunit.demo.ManagedBean does not have a myOtherMissingActionListener method.%%

Extending org.jboss.jsfunit.analysis.AbstractFacesConfigTestCase

%%(color:green)
   public class FacesConfigTestCase extends AbstractFacesConfigTestCase {

	private static Set<String> paths = new HashSet() {{
		add("C:/work/workspace/jsf-unit/src/faces-config.xml");
	}};
	
	public FacesConfigTestCase() {
		super(paths);
	}
   }
%%

Are all of your session and application scoped beans Serializable?

    <managed-bean>
      <description>
	package com.foo.demo;
	public class ShoppingCart { }      	
      </description>
      <managed-bean-name>shoppingCart</managed-bean-name> 
      <managed-bean-class>
      	com.foo.demo.ShoppingCart
      </managed-bean-class>
      <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
%%(color:red)junit.framework.AssertionFailedError: Managed bean 'shoppingCart' is in session scope, so it needs to implement interface java.io.Serializable%%

Invalid Managed Bean Scope?

    <managed-bean>
      <managed-bean-name>shoppingCart</managed-bean-name> 
      <managed-bean-class>
      	com.foo.demo.ShoppingCart
      </managed-bean-class>
      <managed-bean-scope>reqest</managed-bean-scope>
    </managed-bean>	
%%(color:red)junit.framework.AssertionFailedError: Managed bean 'shoppingCart' in C:/work/workspace/jsf-unit/src/faces-config.xml has an invalid scope 'reqest' %%

Missing Managed Bean Class?

    <managed-bean>
      <managed-bean-name>shoppingCart</managed-bean-name> 
      <managed-bean-class>
      	com.foo.demo.ShopingCart
      </managed-bean-class>
      <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>	
%%(color:red) junit.framework.AssertionFailedError: Could not load class com.foo.demo.ShopingCart? for element managed-bean-class %%

Faces Config Class Inheritance?

    <converter>
	<description>com.foo.demo.~CurrencyConverter is a POJO</description>
	<converter-id>currencyConverter</converter-id>
        <converter-class>com.foo.demo.~CurrencyConverter</converter-class>
    </converter>
%%(color:red) junit.framework.AssertionFailedError: In C:/work/workspace/jsf-unit/src/faces-config.xml', com.foo.demo.CurrencyConverter for element converter-class should be a javax.faces.convert.Converter%%

This works for the following elements as well:

	action-listener
	navigation-handler
	variable-resolver
	property-resolver
	view-handler
	state-manager
	faces-context-factory
	application-factory
	lifecycle-factory
	render-kit-factory
	component-class
	converter-class
	validator-class
	render-kit-class
	renderer-class
	phase-listener
	converter-for-class

Missing Setter Methods?

    <managed-bean>
      <managed-bean-name>shoppingCart</managed-bean-name> 
      <managed-bean-class>
      	com.foo.demo.~ShoppingCart
      </managed-bean-class>
      <managed-bean-scope>request</managed-bean-scope>
      <managed-property>
      	<description>javax.faces.el.~MethodNotFoundException</description>
      	<property-name>tax</property-name>
		<value>5</value>
      </managed-property>
    </managed-bean>
%%(color:red) junit.framework.AssertionFailedError: The managed bean 'shoppingCart' has a managed property called 'tax', but com.foo.demo.ShoppingCart has no method setTax(?)%%

Duplicate Managed Bean Names?

    <managed-bean>
      <managed-bean-name>shoppingCart</managed-bean-name> 
      <managed-bean-class>
      	com.foo.demo.ShoppingCart
      </managed-bean-class>
      <managed-bean-scope>application</managed-bean-scope>
    </managed-bean>
    
    <managed-bean>
      <managed-bean-name>shoppingCart</managed-bean-name> 
      <managed-bean-class>
      	com.foo.demo.duplicate.ShoppingCart
      </managed-bean-class>
      <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
%%(color:red) junit.framework.AssertionFailedError: The managed bean 'shoppingCart' in
'C:/work/workspace/jsf-unit/src/faces-config.xml' is duplicated. Look for a managed bean w/ the same name in 'C:/work/workspace/jsf-unit/src/faces-config.xml'%%

Extending org.jboss.jsfunit.analysis.AbstractTldTestCase

%%(color:green)
   public class TldTestCase extends AbstractTldTestCase {

	private static Set<String> paths = new HashSet() {{
		add("C:/work/workspace/jsf-unit/src/demo.tld");
	}};
	
	public TldTestCase() {
		super(paths);
	}
   }
%%

Correct Tag Attribute Types?

    <tag>
        <name>checkoutTag</name>
        <tag-class>com.foo.demo.CheckoutTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>itemCount</name>
            <required>true</required>
            <rtexprvalue>false</rtexprvalue>
            <type>java.lang.Integer</type>
        </attribute>
    </tag>
%%(color:red) junit.framework.AssertionFailedError: Tag 'checkoutTag' in TLD 'demo' is a javax.faces.webapp.UIComponentTag. Becuase it is a JSF 1.1 tag, each tag attribute must be of type java.lang.String, however attribute 'itemCount' is of type java.lang.Integer. See JSF Spec 1.2 section 9.3.1.1 for more information.%%

Unique Tag Names?

    <tag>
        <name>checkoutTag</name>
        <tag-class>com.foo.demo.CheckoutTag</tag-class>
        <body-content>empty</body-content>
    </tag>

    <tag>
        <name>checkoutTag</name>
        <tag-class>com.foo.demo.duplicate.CheckoutTag</tag-class>
        <body-content>empty</body-content>
    </tag>
%%(color:red) junit.framework.AssertionFailedError: Tag 'checkoutTag' occurs in tag library 'demo' more than once %%

Correct Tag Inheritance?

    <tag>
        <name>checkoutTag</name>
        <!-- Just a POJO -->
        <tag-class>com.foo.demo.CheckoutTag</tag-class>
        <body-content>empty</body-content>
    </tag>
%%(color:red) junit.framework.AssertionFailedError: class com.foo.demo.CheckoutTag configured in demo needs to be a javax.faces.webapp.UIComponentTag or a javax.faces.webapp.UIComponentTagBase%%

Unique Tag Attributes?

    <tag>
        <name>checkoutTag</name>
        <tag-class>com.foo.demo.CheckoutTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>itemCount</name>
            <required>true</required>
            <rtexprvalue>false</rtexprvalue>
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <name>itemCount</name>
            <required>true</required>
            <rtexprvalue>false</rtexprvalue>
            <type>java.lang.String</type>
        </attribute>        
    </tag>
%%(color:red) junit.framework.AssertionFailedError: Attribute itemCount in demo:checkoutTag is duplicated. %%

Dependencies

AbstractFacesConfigTestCase has a runtime dependency on the JSF 1.2 API (even if you are using JSF 1.1), such as myfaces-api-1.2.0.jar
AbstractTldTestCase has a runtime dependency on maven-taglib-checker, clogging and jsp-api-2.1.jar

Referenced by:
JSFUnitDocumentation


Other languages:

Log in to make links between pages

The page last changed on Wed Oct 31 22:27:47 EDT 2007 by dennisbyrne