JSF 2, Maven, and Tomcat 7
Introduction
As I worked my way through the Java EE 6 tutorial I needed to learn how to use JSF 2 with Tomcat 7 and Maven. The examples that come with the Java EE 6 tutorial provided by Oracle are NetBeans projects and use the GlassFish 3 server (which has built in support for JSF 2). Since my development environment is Maven and Tomcat, I wanted to translate the JSF 2 examples in the Java EE 6 tutorial to my environment. This work went pretty smoothly except for one big GOTHCA caused by a little advertised bug in the latest version of Oracle's reference implementation of JSF 2.
Example Application
I used the Guess Number project from the Developing a Simple Facelets Application section of the tutorial to create a similar Maven project that can be run with Tomcat 7. The Guess Number example code is copyrighted by Oracle with a license that allows redistribution (see http://developer.sun.com/berkeley_license.html). You can download a zipped archive of the Maven project here (created using Eclipse 3.6).
After downloading the example application, you can import it into Eclipse. If you don't use Eclipse, you can unzip the download and import the Maven project into any Maven aware Java IDE.
To build the application open a terminal (command) window and navigate to the project's root folder. Then at the command line run mvn -e clean package. To run the application copy the guessnumber.war file from the target folder to Tomcat 7's webapps folder. Startup Tomcat and then navigate to http://localhost:8080/guessnumber to view the application. If there are problems with the application read the console.out and localhost log files in Tomcat's logs folder.
Tomcat 7 and Maven
Tomcat 7 does not provide out-of-the-box support for JSF 2. So in the example application's pom.xml are these nodes:
<repositories>
<repository>
<id>java-net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2</url>
<layout>default</layout>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.0.4-b09</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.0.4-b09</version>
</dependency>
</dependencies>
The above nodes in the pom.xml tell Maven to use the java.net Maven 2 repository. There are two JSF 2 artifacts needed for a basic JSF application and these are available in the java.net repository. You can visit the web site for Oracle's reference implementation for JSF 2 for more information.
I initially used the latest version number for the JSF 2 artifacts, but the Guess Number application would error when being deployed by Tomcat 7. It took me quite a bit of research and time to figure out the problem. It appears that there is a bug in the latest version (as of March 2011) of Oracle's JSF 2 reference implementation that prevents Tomcat 7 from successfully deploying a JSF application. See this Jira bug report for more information.
To solve the JSF 2.1 - Tomcat 7 problem I just needed to change the version number for the JSF artifacts to the version before JSF 2.1. After that change, Tomcat deployed the Guess Number application just fine.
Summary
If you want to use the JSF examples from the Java EE 6 tutorial that Oracle has published online, but prefer to use Tomcat and Maven then this article and the example application may be helpful.
References
- The Java EE 6 Tutorial, http://download.oracle.com/javaee/6/tutorial/doc/bnaph.html
- Oracle Mojarra JavaServer Faces, http://javaserverfaces.java.net/
- Apache Tomcat, http://tomcat.apache.org/
many thanks for your superfast answer. Sorry for having overlooked your link to your guessnumber.zip ...
Today I fetched your Eclipse 3.6 sample project guessnumber.zip and made my E. Helios import it. Using exactly your configuration PLUS adding "http:localhost:8080/manager/html" plugin into your pom.xml your example worked immediately! - Thank you very much, for your help! -
But one annoyance may persist with Tomcat 7.0.11 ; Once your deploy your Maven project with mvn tomcat:deploy it may or may not work to redeploy via mvn tomcat:redeploy. Even using rm -rf guessnumber* within tomcat/webapps won't work in any case. Worst case occurring way to often: only restarting my winserv tomcat service as admin allows is to redeploy the Maven 2 - JSF 2 project.
Many on the web recommend to switch to Glassfish 3 at that point; Tomcat 7.0.11 isn't even a semi-professional solution for deploying a Maven 2 - JSF 2 project.
Now my question comes in: would you advice to switch to Glassfish 3 or do you know any trick to overcome the just described Tomcat 7 - Maven 2 - JSF 2 - (re)deployment issue?
Thank you again in advance, Yours, Micha.
I've used GlassFish on other personal projects and think it's very good. If you have the option of using GlassFish Version 3 then I think that would be better as it supports JSF 2, CDI, and all the other JEE 6 features out of the box.
Where I work I don't have the luxury of switching to GlassFish for various reasons.