Friday, January 7, 2011

Setup Eclipse JEE6 Primefaces and Glassfish - Part I

This is the first of a 2 part series on setting up a web application using eclipse, glassfish, JEE6 and Primefaces.  The second  article covers testing with Arquillian and JPA configuration.

My current employer is using Glassfish application server with Grails development framework.  I am really impressed with the terse nature of Grails, maybe more so with Groovy.  Unfortunately with Grails GSP there tends to be a fair amount of javascript in the pages for AJAX.  My fear is that the javascript ends up containing some business logic or sequencing/coordination rules for the use of the business rules.  I've used JSF in the past to remove much of the javascript issues and JSF makes a great framework for AJAX style web applications.  Knowing that JEE6 comes with JSF/Facelets as standard view technology, CDI for dependency injection and JSR330 for validation, it seems like a good transition away from Grails and to JSF.

I am going to build on a series of steps from Nik Carlson on JBoss blogs but want to tailor it more to Glassfish and running from eclipse.  Nik's posts are at http://in.relation.to/Bloggers/AHitchhikersGuideToJavaEE6ApplicationSetupPartI.  Check them out, they are awesome!

Let's start with a download of eclipse helios IDE for JEE Developers from http://www.eclipse.org/downloads/.
Download the zip (32-bit even if tou are on 64bit OS for JBoss tools XUL runner incompatibility with 64-bit).  Unpack the zip to c:\ so you'll end up with c:\eclispe.  Also install a 32 bit JDK to c:\, my current is C:\jdk1.6.0_23.  Modify the c:\eclipse\eclipse.ini and add the line <code>-vm
C:\jdk1.6.0_23\bin\javaw.exe</code> per http://wiki.eclipse.org/Eclipse.ini.  This will run eclipse under a jdk instead of a jre which will help out maven.

Let's install maven while we're at it.  Download release 2.2.1 from http://maven.apache.org/download.html and unpack it to c:\.  Now you should have C:\apache-maven-2.2.1.  Setup local environment variable for MAVEN-HOME and point it to C:\apache-maven-2.2.1.   Add a path entry for %MAVEN_HOME%\bin.  Verify maven setup by running mvn -v from a command prompt.  You should get output like:

Apache Maven 2.2.1 (r801777; 2009-08-06 15:16:01-0400)
Java version: 1.6.0_23
Java home: C:\jdk1.6.0_23\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows"

While we're at it, let's install Glassfish v3 from http://dlc.sun.com.edgesuite.net/glassfish/3.1/promoted/.  Scroll to the bottom of the list and select the "latest" installer (windows is  latest-glassfish-windows.exe ). Run the installer and follow the directions.

Now let's start eclipse and install some plugins....
  3) Glassfish integration via Servers tab, add new server, Download additional server adapters, Oracle Glassfish Server Tools.


Now we can finally start our project.  From eclipse, select new maven project.  Select the create simple project to skip the archetype selection.  Enter com.examples for the groupid on the next page, enter primetest for the artifact, select war packaging, and enter Primefaces JSF for the name and description.  Then click finish.

Edit the project properties and add CDI in the CDI Settings.  Also, convert the project to faceted form and change the java version to 1.6 and add Dynamic Web Module version 3.0.  Update the configuration (addition configuration available at the bottom of the dialog) and change the webapp directory to the maven standard src/main/webapp and click the create web.xml.  Now select the runtime tab and select your glassfish server.  Click ok.  Then right click the project, maven, update project configuration.

Now let's add a couple of files that will get JSF and CDI up and running.  Add two files to your web-inf (faces-config.xml and beans.xml).  

faces-config.xml:
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
              version="2.0"/>

beans.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
      http://java.sun.com/xml/ns/javaee 
      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd" />

Lastly, let's add a JSF page.  Create greetings.xhtml in the webapp directory:


<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://java.sun.com/jsf/html"
 xmlns:ui="http://java.sun.com/jsf/facelets">
 <h:head>
  <title>
   Greetings
  </title>
 </h:head>

 <h:body>
  <h:outputText value="Hello world"/>
 </h:body>
</html>

Now target the the project to glassfish and start up the server.  Then goto http://localhost:8080/primetest/greetings.jsf and you should get the classic hello world.  While that's really special, let's spruce it up some by adding a backing bean.

Create a com.examples.greeting package in the src/java folder.  Add a GreetingBean and add this code:


package com.examples.greeting;

import javax.enterprise.inject.Model;

@Model
public class GreetingBean 
{
 public String getGreeting()
 {
  return "Hello world";
 }
}

Now edit the greetings.xhtml and change the static Hello World to use the bean.  Remove the Hello World text and enter #{ and hit ctrl-space.  Now it looks up available beans!  Sweet.  Select the greetingBean and hit .  Now the available methods are shown!  Select greeting.  Save the file and notice the glassfish console redeploys automatically.  Now refresh the page (http://localhost:8080/primetest/greetings.jsf) and see Hello World again.  It's a little tough to tell if it worked, so let's change the bean to return "Hello World from bean". Save the bean and refresh the browser.  Cool!

Let's add a little primefaces button on the page just to show we can.  Start by adding primefaces dependency.  Open the pom and and:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>

<repositories>
<repository>
<id>prime-repo</id>
<name>Prime Technology Maven Repository</name>
<url>http://repository.prime.com.tr</url>
<layout>default</layout>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>2.2.RC2</version>
</dependency>
</dependencies>

Save the file and select run as/maven package.  This will build the snapshot war file in the project's target directory.  Go find the primefaces.jar in the web-inf/lib and extract the tlds from it's META-INF and put into your web-inf.  We'll now add primefaces tags to the jboss pallete.  First, stop your glassfish server and remove your project from it.  Then open the greetings.xhtml and add jsf capabilities via the dialog.  Then use the pallette import to add primefaces i and primefaces p tag libraries.  

Now let's add a form to our page.  You can use the pallete to select f:form or enter it by hand.  Then select the primefaces p:button and add it to the form.  Set it's id to myButton and value to   Now the page should look like:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<title>Greetings</title>
</h:head>

<h:body>
<h:form>
<p:button id="myButton" value="My Button">
</p:button>
<h:outputText value="#{greetingBean.greeting}" />
</h:form>
</h:body>
</html>

Let's add the project back to the Glassfish server and start  it up.  Refresh the browser and see the new button.  Nice.

A few troubleshooting issues:
JSF Capabilities will try to install when you open the first xhtml.  If the app is already deployed the install fails. It's best to undeploy, open an xhml, install jsf capabilities, then redeploy the web app.

Without sonatype m2 extras, the maven depenendencies (primefaces in this case) won't be deployed to glassfish.

The jdk settings in eclipse kept giving me fits (claiming annotations required jdk 1.5 while eclipse was reporting 1.6).  Install the jdk compiler plugin in the pom fixed that issue.

Here's a zipped project based on what we've covered so far. primetest.zip

In the next installment we'll hook up arquillian for testing and add some more server functionality.

Also see:




6 comments:

  1. Exactly what I was looking for. I am surprised that this is probably only article with these details.

    I am a newbie to java with .NET experience of over decade and I am finding navigating Java bit tough.

    Couldn't get this part though - "Update the configuration (addition configuration available at the bottom of the dialog) and change the webapp directory to the maven standard src/main/webapp and click the create web.xml. " This has confused me.

    ReplyDelete
  2. When I add Java 1.6 and then set the dynamic web app version to 3.0, a "further configuration" link displays in the bottom of the facets dialog. Click the link and then a dialog with context root and content directory input fields is displayed.

    Change the context root to whatever you want to put in the browser to goto your webapp, i.e. chamge to myapp and the url will be http://localhost:8080/myapp.

    Change the content directory to src/main/webapp just to keep maven happy ( src/main/webapp is the maven default directory for webapp contents). There is a way to override the default web directory but I think you're better off doing things the way maven defaults them when possible.

    Lastly, there is a link to create the web.xml which will put a basic web.xml file in the content directory.

    ReplyDelete
  3. Thanks Scott.

    I think I am getting a hang of Eclipse and Java development.

    I managed through - but now I am having this error - "[#|2011-06-15T16:44:39.392+0530|SEVERE|glassfish3.1|javax.enterprise.system.tools.admin.org.glassfish.deployment.admin|_ThreadID=98;_ThreadName=admin-thread-pool-4848(5);|Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.IllegalArgumentException: java.lang.ClassNotFoundException: org.apache.myfaces.webapp.StartupServletContextListener|#]
    "

    I am not sure what I have done wrong. Any help would be appreciated.

    Manish

    ReplyDelete
  4. Make sure that you do not have jsf.jar or jsf-impl.jar included as compile in your project pom. The jsf libraries are provided when you deploy to a JEE6 container like glassfish3. You should only need a stubbed faces-config.xml and web.xml in your web-inf directory.

    ReplyDelete
  5. Hi, I'm not sure why You have installed Glassfish and then JBoss. Both are server applications, so We cannot use them together? Could You explain that?
    Thanks,
    Robert

    ReplyDelete
  6. Good question. The JBoss tools plugins for eclipse add some nice project editing and deployment features to eclipse that makes it easier to develop JEE and JSF applications. So it's not really installing the JBoss app server, it's the JBoss JEE/JSF development tools.

    ReplyDelete