JSF 2.1 project using Eclipse and Maven 2

I’ve used Maven in my previous job and although it’s not perfect, it can be useful. So, I was reading around on Experts Exchange the other day for un-answered RichFaces questions to refresh my knowledge after not having done any work for 2 months now (not sure whether that’s good or bad ;-)) and saw one question that I thought I’d answer. I created a basic Maven project in Eclipse and added the necessary gubbins for RichFaces, but the thing refused to deploy to Tomcat… I then decided to scrap that project and go for the latest stuff, which was a lot further on than what I’ve used before. It turns out that JSF has moved on from 1.2 to 2.1!

So here is my guide to getting a JSF 2.1 project with Maven running in Eclipse. As I add more things to my project like Spring, Hibernate and perhaps RichFaces I shall edit this post and add link(s) to the new posts at the end.

If you haven’t already got Eclipse and the Maven plugin that goes in Eclipse, now would be a good time to get and install them. Also install Tomcat and add a tomcat server in Eclipse.

Ok, start by creating a new Maven project.

JSF 2.1 project using Eclipse and Maven 2 Image 1

Select “Create a simple project (skip archetype selection)” as we don’t want all the extra stuff that an archetype would add.

Choose the location of the project. I’ve chosen to put the project in my default workspace.

JSF 2.1 project using Eclipse and Maven 2 Image 2

Set the Group Id, Artifact Id, Name and change the Packaging type to war.

JSF 2.1 project using Eclipse and Maven 2 Image 3

What you should now have is the following project structure:

JSF 2.1 project using Eclipse and Maven 2 Image 4

This project that we’ve just created will not deploy to tomcat though as it’s not set as a “Dynamic Web Module” facet… And to top it off, Eclipse doesn’t show the project facets until we make a change to the .project file…

So, open the .project file. There should be two build commands and two natures: org.eclipse.jdt.core.javabuilder, org.maven.ide.eclipse.maven2Builder and org.eclipse.jdt.core.javanature, org.maven.ide.eclipse.maven2Nature. Replace the following lines of code shown in the following image with:

	<buildSpec>
		<buildCommand>
			<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.wst.common.project.facet.core.builder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.jdt.core.javabuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.wst.validation.validationbuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.maven.ide.eclipse.maven2Builder</name>
			<arguments>
			</arguments>
		</buildCommand>
	</buildSpec>
	<natures>
		<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
		<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
		<nature>org.eclipse.jdt.core.javanature</nature>
		<nature>org.maven.ide.eclipse.maven2Nature</nature>
		<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
		<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
	</natures>

JSF 2.1 project using Eclipse and Maven 2 Image 5

Save the file and now when you right click on the project and select properties you should have a Project Facets option.

First of all though go to the Java Compiler option, tick “Use default compliance settings” and change “Compiler compliance level” to 1.6 (unless you specifically need a lower Java level?!)

JSF 2.1 project using Eclipse and Maven 2 Image 6

Click apply. It will pop up a dialog box asking to build using the new level straight away. Click yes.

Go to the Java Build Path option and select the “Order and Export” tab. Tick the “Maven Dependencies” box.

JSF 2.1 project using Eclipse and Maven 2 Image 7

Go to the Project Facets option. Tick Dynamic Web Module and make sure the version is 2.4+. Tick Java and make sure the version is 6.0+.

JSF 2.1 project using Eclipse and Maven 2 Image 8

Click ok and it will add those requirements to the project. The project structure will now look like the following:

JSF 2.1 project using Eclipse and Maven 2 Image 9

Delete the folder webapp which is under src/main. All web content needs to go in the WebContent folder instead.

Open file web.xml and select everything. Paste the following code over the top.

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>jsf2testproject</display-name>
	
	<welcome-file-list>
		<welcome-file>index.xhtml</welcome-file>
	</welcome-file-list>
	
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.xhtml</url-pattern>
	</servlet-mapping>

	<context-param>
		<param-name>javax.faces.PROJECT_STAGE</param-name>
		<param-value>Development</param-value>
	</context-param>
</web-app>

Open the file pom.xml and select the pom.xml tab. Below the name insert the following:

	<repositories>
		<repository>
			<id>maven2-repository.dev.java.net</id>
			<name>Java.net Repository for Maven</name>
			<url>http://download.java.net/maven/2</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

	<dependencies>
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-api</artifactId>
			<version>2.1.0-b03</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-impl</artifactId>
			<version>2.1.0-b03</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
		</dependency>
	</dependencies>

Create a folder structure in src/main/java that matches the Group Id that was entered when creating the project. E.g. in this example the folder structure will be src/main/java/uk/co/vsf. I’ve created an additional folder called presentation that I’ve placed a file in called HelloPB.java. In that file is the following:

package uk.co.vsf.presentation;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class HelloPB
{
	private String name = "";

	public String getName()
	{
		return name;
	}

	public void setName(final String name)
	{
		this.name = name;
	}

	/**
	 * Say hello + name that was entered.
	 * 
	 * @return
	 */
	public String getHello()
	{
		if ( name == null || name.length() < 1 )
		{
			return null;
		}
		return "Hello " + name;
	}
}

In the folder WebContent, create a new file index.xhtml. Put the following in to that file:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html">

<h:head>
	<title>JSF Demo</title>
</h:head>
<h:body>
	<h:outputScript name="jsf.js" library="javax.faces" target="body">
	</h:outputScript>
	<h1>JSF 2 Demo</h1>
	<h:form>

		<h:inputText id="name" value="#{helloPB.name}">
			<f:ajax render="helloTextOutput" />
		</h:inputText>

		<h:commandButton value="Say Hi via Ajax">
			<f:ajax execute="name" render="helloTextOutput" />
		</h:commandButton>
		<h:outputText id="helloTextOutput" value="#{helloPB.hello}" />
	</h:form>

</h:body>
</html>

That was the last new file we need, but the project will still not work correctly as when deployed it will not contain the jars that we added in the pom.xml file. If you navigate to where the jar files should be in the deployed app, as seen in the image, you’ll notice they haven’t been included. If we deploy it right now, this is the error message that will appear in the log:

SEVERE: Error loading WebappClassLoader
  context: /jsf2testproject
  delegate: false
  repositories:
    /WEB-INF/classes/
----------> Parent Classloader:
org.apache.catalina.loader.StandardClassLoader@1b90b39
 javax.faces.webapp.FacesServlet
java.lang.ClassNotFoundException: javax.faces.webapp.FacesServlet

We will now need to alter a few files so that the jar files are deployed with the application.

So now open the file org.eclipse.wst.common.component which is in the .settings folder. Delete the lines:

<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/java" />
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/resources" />

Replace them with:

<dependent-module deploy-path="/WEB-INF/lib">
    <dependency-type>uses</dependency-type>
</dependent-module>

Open .classpath and replace the line: <classpathentry exported=”true” kind=”con” path=”org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER”/> with:

<classpathentry exported="true" kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER">
	<attributes>
		<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
	</attributes>
</classpathentry>

Now when you deploy the application and navigate to the webpage which in my case is http://localhost:8080/jsf2testproject you should see the following:

JSF 2.1 project using Eclipse and Maven 2 Image 10

So there we have it; a project that is setup ready for use. There may well be an easier way to configure the project, but this is the way that’s worked for me and there are no extra files that I don’t need.

Related Posts

None yet

Rough guide to Checkstyle (CS)

Why use CS?

This was my first question when one of my former colleagues decided that our project needed CS. His answer to me was something along the lines of, if everyone codes using CS then there will be more consistency and better code will be produced. Now at first I thought that that response was BS. But after using it for 3 months, I wouldn’t like to go back! It does make code more consistent (when combined with auto formatting) and in it provides many pointers on producing better code.

 

How to set up CS

Go to the Eclipse CS website and click on the “Download & Installation” button. Follow the instructions for adding in the CS plug-in to Eclipse. Once you’ve restarted Eclipse there will at first be no differences. CS by default is not enabled on a project as it will add many warnings when enabled.

Now, the best case is that you have a brand new project and no code, but chances are you have an established project and you’d like to see what CS looks like to decide whether to use it from now on. If you have the latter, you’re going to find that once you apply CS to your project, you’ll likely have hundreds (if not thousands) or warnings. Don’t be put off though. This is quite normal. We got round this by agreeing with every member of the team that if they edit a file, clean up the CS warnings and eventually you’ll find only a few hundred warnings left.

To enable CS, right click on your project, select properties and the properties box will pop up. Now, you might well notice two CS place holders, not sure why, but always use the top one. In the Main tab, tick “Checkstyle active for this project.” You have two options here, use the Sun default styles or create your own.

 
Use Sun Styles

Drop down “Simple – use the following check configuration for all files” and select the Sun style you’d like to see. Click ok, accept the rebuild of the project. You should notice that there are now lots of CS warnings.

 
Use Own Styles

Select the Local Check Configurations tab, click New, select you’re preferred type, I use Project Relative Configuration, give it a name, in location, type “/{name of project}/{src or other}/{name of file}” so in my case “/testproject/src/testcs.” You will probably get a pop up dialogue saying “The selected configuration file does not exist. Should an empty configuration file be created?”, press yes. Click ok. Select the Main tab again. Drop down “Simple – use the following check configuration for all files” and select the new file you just created. Agree to the project being rebuilt. You should now have a file in the src folder and if you open that file, you’ll notice its an XML file. You should also have realised that CS has not reported anything. That’s because we haven’t told it what we’re interested in.

Right click on the project again. Select properties. Select Checkstyle. Select the Local Check Configurations tab. Double click on your CS file. Now for every (and there are loads..) option on the left hand side, double click on the option, read it, see whether you’d like that style checked for and if so alter it if needed and then click ok, otherwise cancel. You should notice that in the “Configured modules for group “X”” you should see the ones you’ve chosen to be checked. E.g.

When done, click ok and click ok again on the properties window. Accept the rebuild of the project.

 

What does it look like when CS is applied?

Well that depends on whether you’ve chosen you’re own styles or selected the Sun styles. I would go for my own styles I have certain preferences that Sun thinks are wrong, like opening curly braces on a new line!

Here is what Sun CS styles look like on my very simple class:

As you can see, it’s complaining about a lot of things I wouldn’t agree with. So here is an image of my own style in use:

Please note that both images show custom check style warning colourings. Please see Configuring Eclipse Preferences

A lot better! The errors that are present are that the main method should be commented (fair) and that both int arrays should be declared final (fair). So I’d have to clean those up.

In case you’re interested, that CS rules file is available from here. It should have an MD5 sum of bc6869b2d2ab5143b5fc6c4cfd6d0edb.

 

How do I configure CS to work with auto formatting?

Click Window → Preferences, which will open the preferences window. Drop down Java → Code Style and select Clean Up. Create a new profile, E.g. mines called Victoria and this will pop up a new window where you can edit all the settings. Tick Format source code, Remove trailing whitespace, Correct indentation and Organise imports as a bare minimum. You can then go through all the tabs and apply anything else you’d like applied. When done click ok.

Next select Java → Code Syle → Formatter and again create a new profile and edit the settings when the window appears.

Next select Java → Editor → Save Actions and tick Perform the selected actions on save, tick Format source code and click apply.

In theory, all you need to do now is go to a java file, edit it very slightly, like insert a space and click save. The formatter will then kick in and remove half of the CS warnings as formatted code should adhere to the CS styles.