Serious Java Web application development requires a lot of different applications. In addition to a JDK, an IDE and an application server you may need a Web application framework, a build system and some form of version control. Unsurprisingly, getting set up for development can be quite the task.
In this post we’ll take a look at setting up a Web application project from start to finish. The software we will use is:
We are building a Web application, so the product of building our project will be a WAR file. The Glassfish application server extracts a WAR file and runs the application inside it. The WAR file also contains a deployment descriptor, web.xml that describes how the application server should run the WAR.
The structure of a WAR file looks like this (source):
Project Setup with Maven Archetypes
Now that we know what we are building, it is time to start setting up the project. The directory/file structure of the project we are creating is very different from the structure of the WAR file. Our build tool, Maven, makes the ‘translation’ between the project structure and the WAR structure. It takes care of compiling and packaging up the files in the project into a valid WAR file that is ready for deployment.
We don’t have to start completely from scratch with the project. Maven can download pre-made, barebones projects called archetypes. Archetypes are nothing more than a bunch of files and folders that are packaged up and given a name.
There are currently 588 archetypes, 21 of which contain “jsf” in their name. Most of these archetypes are quite heavyweight: they come with pretty big pom.xml files. Instead of using these, we will start off with a very basic non-jsf archetype, and add only the things we really need.
First we will download the archetype maven-archetype-webapp with the mvn archetype:generate command. Be be sure to choose a fitting groupId and artifactId:
>mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>>
...
[INFO] Generating project in Interactive mode
Define value for property 'groupId': : mygroup.com
Define value for property 'artifactId': : myprojectname
Define value for property 'version': 1.0-SNAPSHOT: :
Define value for property 'package': mygroup.com: :
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
This creates a very simple Mavenized Web application project in a directory named myprojectname. The contents of this folder are:
Note
Usually, archetypes contain a pom.xml file, meaning they are Maven projects. But this does not have to be the case. In theory, an archetype can be any set of files and folders.
The default pom.xml file is very simple, containing only one dependency. The packaging type is set to war, which is what we need.
Our project will use JSF 2.0 web framework, and run on the Glassfish application server. JSF is part of the standard Java EE platform, which means it’s built-in to any compliant Java EE application server, such as Oracle’s WebLogic, GlassFish Open Source Edition, or JBoss AS. But it can also be used as a standalone library in servlet containers such as Tomcat and Jetty.
In order to be able use JSF (the javax.faces package) in our source code we must add a dependency for it in the pom.xml. Add this dependency for the entire Java EE 6 API (including JSF and CDI):
>>javax>>javaee-api>>6.0>>provided>>
The provided scope means that Maven assumes the dependency is provided by the application server at run-time. Maven will only add the JAR to the classpath for compilation and testing phases, but it will not be included in the WAR file. This is what we want, because Glassfish 3 contains a full Java EE implementation including JSF 2.0.
Configuring the Deployment Descriptor
A deployment descriptor describes how a Web application should be deployed. In the past, using a web.xml file in the WEB-INF directory was required. However, with the new features in the Servlet 3.0 specification in Java EE 6 it has become possible to use annotations instead of XML configuration files such as web.xml. It doesn’t mean the web.xml is now obsolete, but its size can be reduced. Information specified in the deployment descriptor takes precedence over the information specified through Annotations.
Part of the deployment descriptor are servlet mappings that describe which URLs are passed to the Faces Servlet. Some application servers (including GlassFish) automatically provide a servlet mapping for the /faces/*, *.faces, and *.jsf patterns. The *.jsf pattern means that a request to http://localhost/myprojectname/index.jsf is passed to the Faces Servlet. By default, the Faces Servlet then looks for a file but with a .jsp
Discard the outdated web.xml that came with the archetype, and replace it with this web.xml:
This instructs the application server to pass .xhtml requests to the Faces Servlet, and to let the Faces Servlet look for .xhtml files on the filesystem.
Adding a Bean
A bean is a Java class that is managed by the JSF framework, and can be referenced from JSF pages using the bean name. It is a historical accident that there are two separate mechanisms, CDI beans and JSF managed beans, for beans that can be used in JSF pages. The consensus for Java EE 6 seems to be CDI beans, so we will use that method.
In previous JSF versions, each bean had to be declared in a faces-config.xml file. Thankfully we now have annotations, which makes this file obsolete in most cases. Create a new source file at /src/main/java/com/mygroup/Hello.java.
The @Named annotation means the class is a CDI bean. One thing we need to do now is tell the server that this project is a module containing CDI beans. To do this, we add an empty file called beans.xml to the project at /src/main/webapp/WEB-INF/beans.xml.
Note
Make sure you have created the beans.xml file, or the project will not work. It may seem silly that an empty file is so important, but there are convincing reasons for this behavior. They are described here.
Adding a JSF Page
We have defined in the web.xml file that our views use the .xhtml extension. So we remove the /src/main/webapp/index.jsp file that came with the archetype, and create a new file /src/main/webapp/index.xhtml.
This builds the project into a WAR file at /target/myprojectname.war.
Next, we start up a Glassfish 3 server with the asadmin start-domain command.
asadmin start-domain --verbose domain1
Now copy the WAR file to the autodeploy directory of your domain directory, e.g. glassfish/domains/domain1/autodeploy. You will see some output from the asadmin process, which can help identify any problems with the project. Let's assume that things didn't blow up in your face and the deployment was succesful, and you see something like this:
Now open a browser and open the page, e.g. at http://localhost:8080/myprojectname/index.xhtml. You should see "HelloBean says: Hello World".
Importing Into Eclipse
Now that we have a working JSF/Maven project, it is time to import the project into Eclipse.
Note
Although many guides on the internet (wrongly) recommend it, you should not use the mvn eclipse:eclipse command to create the Eclipse project. This plugin can only generate WTP projects for very old Eclipse versions (WTP 2.0 is the maximum). Instead, use the m2eclipse plugin as described in this section.
Set Java version in POM to 1.6
It is a good idea to tie the project to a specific JDK version, to ensure the build stays the same when a newer JDK version is used. We do this by adding some parameters for the maven-compiler-plugin to our pom. Since we are developing for Java EE 6, we will specify version 1.6. Change the section to this:
For JSF development you need the Java EE version of Eclipse, for this guide Eclipse Indigo SR2 was used. After installing Eclipse we need to add three plugins through Help -> Eclipse Marketplace.
Maven Integration for Eclipse (a.k.a. m2eclipse): This plugin adds basic Maven support to Eclipse. Obviously.
Maven Integration for Eclipse WTP (a.k.a. m2e-wtp): This plugin integrates m2eclipse with the Web Tools Project, which handles Web application specific stuff in Eclipse.
Import the Project
Go to File -> Import, and choose Existing Maven Projects. Browse to the directory where the pom.xml is located, and click Finish. The project should now be imported, and initialized.
If we look at the Project Facets (under Project -> Properties) we see that the Java version has been correctly set to 1.6, and the Dynamic Web Module is set to support Servlet 3.0.
Installing Glassfish Support
Eclipse does not come with pre-installed Glassfish server support, but fortunately this can be added with a few clicks.
Open the Servers view through Window -> Show View -> Others.
Right-click in the Servers view and select New -> Server.
Click "Download additional server adapters" in the top-right and install the "Oracle Glassfish Server Tools" module.
Deploying to Glassfish
Create a new Glassfish server instance through the Servers view. We choose the latest available Glassfish edition, in my case it was Glassfish 3.1.2. Then we are prompted for the installation directory of the server. We can either select the path of an existing Glassfish installation, or choose an empty directory and click "Install Server" to make Eclipse download a fresh installation for us.
Now we can add a project to the Glassfish server by right-clicking it and choosing Add and Remove...:
Start the server, and your project will be served by Glassfish!
Add Project to SVN
As a final step we can upload the project to an SVN repository, so we can work on it with others and keep a history of the code. A detailed description of the process can be found in another post on this blog. Be sure to the add target directory to svn:ignore by rightclicking it and selecting Team -> Add to svn ignore...
In order for other developers to immediately have a working project, we will need to upload all other project files, including .project, .classpath and the .settings directory. Of course the other developers will also need to have the same plugins installed.
Exactly what I was looking for. Now to add Spring3 and Hibernate4 to this… One question I have has to deal with ProjectFacets.png. Mine had JavaServer Faces 2.0 checked where yours does not. I also attempted to change it to 2.1 and eclipse won’t allow it. Any ideas?
testing this on a uptodate ubuntu 12.04 with java 1.6 i get:
mvn package
[INFO] Scanning for projects…
[INFO] ————————————————————————
[INFO] Building myprojectname Maven Webapp
[INFO] task-segment: [package]
[INFO] ————————————————————————
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 1 source file to /home/julius/jsftest/myprojectname/target/classes
[INFO] ————————————————————————
[ERROR] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Compilation failure
/home/julius/jsftest/myprojectname/src/main/java/com/mygroup/Hello.java:[5,1] annotations are not supported in -source 1.3
(use -source 5 or higher to enable annotations)
@Named
[INFO] ————————————————————————
[INFO] For more information, run Maven with the -e switch
[INFO] ————————————————————————
[INFO] Total time: 2 seconds
[INFO] Finished at: Sun Aug 05 10:42:28 CEST 2012
[INFO] Final Memory: 10M/89M
Emmanuel I had the same issue than julius, then, from the blog of mkyong: http://www.mkyong.com/jsf2/jsf-2-0-hello-world-example/ i add this between ... and work! org.apache.maven.plugins maven-compiler-plugin 2.3.1 1.6... –Nov 06, 12:36 AM
Alfredo Archilla Hi, THere seems to be quite a lot of information regarding the "how to listen to a WiFi" signal out there with the use of,... –Oct 25, 3:56 PM
DCode Would you be able to upload to paste bin, I'm easing my way into python (out of functional demand *smile*). It appears to be indentation... –Oct 13, 12:06 AM
This was the best guide ever! Many thanks, you saved me a lot of work! =)
Glad you found it useful
Exactly what I was looking for. Now to add Spring3 and Hibernate4 to this… One question I have has to deal with ProjectFacets.png. Mine had JavaServer Faces 2.0 checked where yours does not. I also attempted to change it to 2.1 and eclipse won’t allow it. Any ideas?
testing this on a uptodate ubuntu 12.04 with java 1.6 i get:
mvn package
[INFO] Scanning for projects…
[INFO] ————————————————————————
[INFO] Building myprojectname Maven Webapp
[INFO] task-segment: [package]
[INFO] ————————————————————————
[INFO] [resources:resources {execution: default-resources}]
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 1 source file to /home/julius/jsftest/myprojectname/target/classes
[INFO] ————————————————————————
[ERROR] BUILD FAILURE
[INFO] ————————————————————————
[INFO] Compilation failure
/home/julius/jsftest/myprojectname/src/main/java/com/mygroup/Hello.java:[5,1] annotations are not supported in -source 1.3
(use -source 5 or higher to enable annotations)
@Named
[INFO] ————————————————————————
[INFO] For more information, run Maven with the -e switch
[INFO] ————————————————————————
[INFO] Total time: 2 seconds
[INFO] Finished at: Sun Aug 05 10:42:28 CEST 2012
[INFO] Final Memory: 10M/89M
Excelente tutorial,muy buena explicación, no se mecaniza , entendible. Muchas gracias.
I had the same issue than julius, then, from the blog of mkyong:
http://www.mkyong.com/jsf2/jsf-2-0-hello-world-example/
i add this between … and work!
org.apache.maven.plugins
maven-compiler-plugin
2.3.1
1.6
1.6