Monday, January 31, 2011

JSF 2.0 tutorial with Eclipse and Glassfish

WARNING - OUTDATED CONTENT!

There is a newer JSF 2.3 tutorial out with Eclipse / Maven / WildFly / H2.

Introduction

In this tutorial you will learn how to setup a JSF 2.0 (Mojarra) playground with Eclipse 3.6 SR1 (Helios) and Oracle Application Server v3 (Glassfish).

There are also another IDE's available next to Eclipse, e.g. Oracle Netbeans, IntelliJ IDEA, etcetera. The choice for Eclipse is made because it's highly configureable, customizeable, has lots of helpful wizards and .. it's free! True, it may eat memory and it may sometimes crash. Just make sure that your environment has enough RAM memory for Java EE development. I recommend at least 2GB of free RAM of which 1GB is reserved to Eclipse. Also at least a dual/quad core CPU around 2GHz is recommended to be able to work fluently. Also make sure that you install trusted Eclipse plugins the right and clean way, because the well-known Eclipse-instability is almost always caused by bad plugins.

There are also another application servers available next to Oracle Glassfish, e.g. JBoss Application Server, Apache Tomcat, etcetera. The choice for Glassfish is made because it ships as being a full fledged Java EE 6 application server already with JSF builtin and offers builtin support for lot of other handy Java EE aspects like JPA for database connectivity, EJB for business services, JSR303 for bean validation, CDI for dependency injection, etcetera. Also, in combination with the current Eclipse plugin, it allows for extremely fast development. Not only Glassfish starts up relatively quick, but it is able to hotdeploy code changes in a subsecond. It's certainly an improvement as compared to its predecesor, Glassfish v2. In the 3-year old JSF 1.2 tutorial, Apache Tomcat was been used. One of the reasons to prefer Tomcat over Glassfish v2 was the lack of a good Eclipse plugin for Glassfish back then in 2008.

Back to top

Preparing

Create a working directory where you install and store all related files. In this tutorial we'll use C:\Java as working directory. If you want to store it somewhere else, then you'll have to replace every occurence of "C:\Java" throughout the tutorial by the desired directory.

Back to top

Download and install Java SE 6 JDK

The Java SE 6 JDK contains both the runtime (JRE, java.exe) and the compiler (JDK, javac.exe) for the standard Java API.

You can skip this part if you already have downloaded/installed Java SE 6 JDK.

  1. Surf to the Java SE 6 download page.
  2. You'll see four big buttons next to each other, press the leftmost one, which says just 'Java'.
  3. Accept the License Agreement and choose the right file for your platform. For Windows x64 for example you will get the file jdk-6u23-windows-x64.exe (naming may differ per version), save it to disk.
  4. Install the JDK and JRE in C:\Java\jdk1.6.0_23 and C:\Java\jre1.6.0_23 respectively (or in their default paths, if you want).
Back to top

Download and install Java EE 6 Web Profile SDK

The Java EE 6 covers the enterprise Java API. This is basically an abstract API for which Glassfish is one of the concrete implementations. Actually, Glassfish is the reference implementation. The Java EE 6 Web Profile is a specified part of the huge Java EE 6 API which includes the minimum necessary API's required for Java web development: the Servlet 3.0 API, JSF 2.0 API, JPA 2.0 API and EJB 3.1 Lite. Note that Apache Tomcat 7.0 only includes Servlet 3.0 API.

You can also consider to pick the standard (full) profile. It's only too heavy-weight since it contains API components which are (possibly) not of your interest like EJB (full), JAX-WS, JAXB, JMS, JACC, JAX-RPC, JAXR, etcetera. It causes Glassfish to start slower as compared to the lightweight web profile, sometimes very noticeably slower. The web profile starts in only a few seconds. You can find an overview of differences halfway the download page of the Glassfish development site.

You can skip this part if you already have downloaded/installed Glassfish, even though you did it by their development site.

  1. Surf to the Java EE 6 download page.
  2. You'll see four big buttons next to each other, press the rightmost one, which says 'Java EE 6 Web Profile SDK'.
  3. Choose Platform/Language, accept the License Agreement and press the Continue button.
  4. In the section 'Available Files', click at the link below 'Java EE 6 Web Profile SDK Update 1', you will get the file java_ee_sdk-6u1-web-windows.exe (naming may differ per version), save it to disk.
  5. Install Glassfish in C:\Java\glassfishv3 and walk through the remnant of the wizard. Just with default settings is fine. You may possibly get a firewall warning whenever you go to the next step after setting the ports (the installer is just testing them). Just let the firewall allow access. Don't forget to remember the admin username and password for the case that you've changed them!


Note that you may possibly get the error 'This application needs version 1.6 or higher of the Java 2 Runtime Environment.' when executing the installer. In this case, your best bet is to try reinstalling the JRE (not the JDK!) which you can download from java.com. In the latest Java 1.6 releases, there's apparently a little difference in how the JDK/JRE installers configures the necessary registry keys and DLL's in Windows. Just reinstall JRE from java.com in the same folder. During auto-uninstalling the original JRE, you'll possibly get warnings that msvcr71.dll is missing, just ignore it and go ahead (it's may namely be exactly that file which was broken in the original JRE install!).

Back to top

Download and install Eclipse Helios 3.6 SR1

The Eclipse IDE is available in several tastes. As we're going to develop Java EE web applications, we need the Java EE variant. It contains among others the invaluable WTP (Web Tools Platform) which eases the development of Java EE web applications. The currently latest version is Eclipse Helios 3.6 SR1.

  1. Surf to the Eclipse download page.
  2. Click at the Eclipse IDE for Java EE Developers link.
  3. On the right hand menu, pick the platform version.
  4. Click the default mirror or pick a mirror and you will get the file eclipse-jee-helios-SR1-win32-x86_64.zip (naming may differ per version), save it to disk.
  5. Extract the zip and move the child directory \eclipse to C:\Java\eclipse.
Back to top

Run and configure Eclipse

After starting Eclipse for the first time, we would like to finetune Eclipse a bit so that we don't after all end in trouble and/or annoyances. Eclipse has enormously a lot of settings of which some default values should after all not have been the default values. Here I'll describe only the most useful/important ones.

  1. Run C:\Java\eclipse\eclipse.exe. You will be asked to select a workspace. Point it to C:\Java\workspace.
  2. On the welcome screen, click at the icon with the curved arrow at the right top: Go to the workbench.
  3. In the top menu, go to Window » Preferences. This is the preferences dialogue.
  4. You want world domination, so enter 'encoding' in the 'type filter text' input field on the left top. On every section, change the encoding from default (often cp1252 or ISO 8859-1) to UTF-8.
  5. In the Preferences dialogue, clear if necessary first the entered filter text, then go to General » Editors » Text Editors » Spelling and disable it. Really. It will save you from a big annoyment, because it also unnecessarily spellchecks XML documents like web.xml, faces-config.xml and on.
  6. In the Preferences dialogue, go to Web » JavaServer Faces Tools » Validation and in the section Type Assignment Problems set Method expression signature incompatibility to Warning or Ignore if you want to allow JSF action methods return void. I also recommend to set the Unary operation number (and boolean) coercion problems in the section Type Coercion Problems to Warning or Ignore, because it would unnecessarily give an error when you're using for example UIComponent#getValue() -which has Object type outcome- in EL but you treated it as number or boolean.
  7. In the Preferences dialogue, go to Web » HTML Files » Editor » Templates and click New. Enter name New Facelet Page, select context New HTML, enter description Creates a new Facelet page, copypaste the following snippet in the pattern field and click OK:
    <!DOCTYPE html>
    <html lang="en"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets">
        <h:head>
            <title>Insert title here</title>
        </h:head>
        <h:body>
            ${cursor}
        </h:body>
    </html>
    
  8. Here are some more screenshots of how I configured some other preferences (Text Editors, HTML Editor and Errors/Warnings), you may find it useful as well (indent using spaces, set line width and print margin, finetune errors/warnings, etc):
  9. Click OK to close the Preferences dialogue.
Back to top

Integrate Glassfish in Eclipse

We need to familarize Eclipse with any installed application servers so that Eclipse can seamlessly link their libraries in the build path (read: the compiletime classpath) of the project. This is mandatory in order to be able to import classes from the Java EE API in your project (you know, the applications server is namely the concrete Java EE implementation).

  1. At the bottom box click at the Servers tab to open the servers view. Rightclick at the box and choose New » Server. In the wizard, click the link 'Download additional server adapters'. Wait until it has finished gathering all available adapters. Finally choose 'Oracle Glassfish Server Tools' from the list and click Next. Accept the license terms and click Finish. In the end you need to restart Eclipse, do it.
  2. After restarting and going to workbench, open the servers view once again to add a new server. In the wizard, select GlassFish » GlassFish Server Open Source Edition 3 (Java EE 6) and click Next. In the next page, click at Browse, point to C:\Java\glassfishv3\glassfish and click Next. In the next page, change if necessary the admin ID (username) and password, which is the same as the ones specified during Glassfish installation. Finally click Finish. Now Glassfish is integrated in Eclipse.
  3. Doubleclick the Glassfish server entry in the Servers tab, you'll get the server configuration. You can there if necessary change the admin name/password and configure the degree of publishing (hotdeploying). You may possibly get a firewall warning when you open the server configuration for the first time, just let it allow access. Glassfish is able to publish extremely fast on just a Ctrl+S. In the Publishing section, set Automatically publish when resources change and set the interval to 0.
  4. Rightclick the Glassfish server entry in the Servers tab and choose Start. You can also start it by clicking at the green arrow at the toolbar of the box. Again, you may possibly get a firewall warning here as well, just let it allow access (this should be the last time now ;) ). Once it is started, go to http://localhost:8080 (where 8080 is the HTTP port as in Glassfish config). You should get the default Glassfish home page. Also checkout the admin console on http://localhost:4848 (where 4848 is the admin port as in Glassfish config).

    If you get a timeout or kind of an unknown host error message, then doublecheck it is started properly and you're using the right port number. In Eclipse you can find the Glassfish logs at the Console tab of the bottom dialogue box (you can doubleclick the tab to maximize it and bring it back). Glassfish actually shows two consoles, one of the JVM and one of the server.log logfile. The last one is of your interest. Click the blue monitor icon on the right top to switch between consoles.
  5. You can stop the server by rightclicking at the Glassfish server entry in the Servers tab and choose Stop. You can also stop it by clicking at the red square at the toolbar of the box.
Back to top

Prepare JSF web project in Eclipse

Now we can finally create a JSF web project in Eclipse.

  1. At the left box open the Project Explorer tab if not already opened. Rightclick at the box and choose New » Dynamic Web Project. In the wizard, give it the Project name Playground, verify if Target Runtime is set to 'GlassFish Server Open Source Edition 3 (Java EE 6)' and Dynamic Web Module version is set to '3.0' (this is actually the Servlet API version). Under Configuration select 'JavaServer Faces v2.0 project' and click Next.
  2. In the next page, you can configure the source folder and build folder (there where compiled classes will end up in). Just keep it default and click Next.
  3. In the next page, you may change the module settings to your taste. Personally I like to have URL's always in lowercase, so I change the default Context Root from Playground to playground. Also, check the checkbox Generate web.xml deployment descriptor to have Eclipse auto-generate the web.xml. Click Next.
  4. In the next page, you need to define JSF Capabilities. At JSF Implementation Library, select 'Disable Library Configuration'. Glassfish already ships with JSF 2.0 builtin, so we don't need to specify anything. At URL Mapping Patterns, select the default /faces/* and click Remove to remove it. Prefix patterns end up to be less maintainable. Better use postfix patterns like *.jsf or even *.xhtml (unless you have XHTML files which you'd like not to have JSF's FacesServlet to kick in). We'll pick *.xhtml here, a major advantage is that this is an easy way to avoid that the enduser can see the JSF source code whenever s/he (accidently) opens the page with *.xhtml in the URL while the FacesServlet is mapped on *.jsf.

    Click Add... to add a new pattern with the value *.xhtml. Finally click Finish.
  5. After creation of the web project, you should get a directory structure similar to the screenshot below.
  6. Due to a combination of constraints in the HTTP/HTML/EL specifications, empty HTML input fields are by default treated as empty String. The average (Java) web developer usually dislikes this (so do I). We can instruct JSF to interpret them as null. Open WebContent/WEB-INF/web.xml file, click if necessary the Source tab at the bottom of the editor, and add the following context parameter:
    <context-param>
        <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
        <param-value>true</param-value>
    </context-param>
    
    If necessary hit Ctrl+Shift+F to format the xml file nicely.
  7. Save and close the file.
Back to top

Create JSF hello world in Eclipse - The model

As a hello world project, we'll create a simple ajax-flavored form which treats the use case of "Register User". We first need to create a data model. That's a class which represents a real world entitiy, in this case the User. It holds all the information about the user. It should be written as a Javabean. A Javabean is a class which holds properties as private fields which are exposed by public getters and setters.

  1. Open the newly created Playground project, rightclick at Java Resources folder and choose New » Class. In the wizard, enter the package name com.example, enter the class name User, keep the other fields default and click Finish. The package and the class will be created and the editor box will show the class source.
  2. Let the class implement Serializable. This is not mandatory per se, but this is useful in order to let the HTTP session survive server restarts. Also, as we're going to use a JSF view scoped bean, which will be stored in the component tree (the `UIViewRoot`) in the HTTP session, the view scoped bean itself and all of its properties should be Serializable as well.
    package com.example;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
    }
    Note that when you add implements Serializable, Eclipse will show a warning that the class needs to have a serialVersionUID field. You can if necessary just let Eclipse include it with a default or autogenerated ID. Click the yellow bullet on the left hand side and choose it.
  3. Add five fields to the class (note that Date is to be imported as java.util.Date, not as java.sql.Date):
    
        private Long id;
        private String username;
        private String password;
        private String email;
        private Date birthdate;
     
    
  4. Let Eclipse auto-generate the necessary getters and setters. Rightclick somewhere in blank space of the source code inside the source editor, choose Source » Generate Getters and Setters, or hit Alt+Shift+S, then R. In the wizard, click Select All and then untick the serialVersionUID one, if necessary choose the insertion point (I like to have getters and setters at the whole bottom of the class, thus Last member) and the sorting (it defaults to getter/setter pairs, which is okay) and then click at OK. If necessary, hit Ctrl+Shift+F to format the code again so that methods get separated by a blank line. You can configure formatting preferences in Window » Preferences » Java » Code Style » Formatter.
  5. Save the class by choosing File » Save in the top menu or by pressing Ctrl+S.

Create JSF hello world in Eclipse - The controller

The backing bean is in turn the glue between the view (the JSF page) and the data model (the entity). The backing bean is linked to the view and all properties of the model are by the backing bean exposed in the view. The backing bean can contain action methods which are linked in the view. The backing bean is basically a mini-controller at its own (in the bigger picture of JSF, the FacesServlet is actually the real web MVC controller).

  1. Rightclick at com.example package and choose New » Class. In the wizard, enter the class name Register, keep the other fields default (if you rightclicked on the package to create a new class, the package name should already be com.example) and click Finish. The class will be created and the editor box will show the class source.
  2. First let the class implement Serializable. Then add a new line above the class declaration, enter @ManagedBean, press Ctrl+Space and ensure that you choose the javax.faces one to import. Do the same for @ViewScoped annotation as well. Note that we can also use @RequestScoped here as well since the bean doesn't do any significantly expensive operations during the construction such as obtaining some data from a database, but if it did and you declared it @RequestScoped, then the bean will be constructed and thus the DB will be hit on every ajax request, keep this in mind!
    package com.example;
    
    import java.io.Serializable;
    
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    
    @ManagedBean
    @ViewScoped
    public class Register implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
    }
  3. Add a property for the User model, along with a getter and (optionally) a setter, add a @PostConstruct method with which initializes a new User and finally add an action method which just adds a success message (in real world, we would save the newly registered user in the DB as well, but that's beyond the scope of this tutorial):
    
        private User user;
    
        @PostConstruct
        public void init() {
            user = new User();
        }
        
        public void submit() {
            FacesMessage message = new FacesMessage("Registration succesful!");
            FacesContext.getCurrentInstance().addMessage(null, message);
        }
        
        public User getUser() {
            return user;
        }
    
    
  4. Save the class.
Back to top

Create JSF hello world in Eclipse - The view

blah

  1. Rightclick at WebContent folder and choose New » XHTML page. In the wizard, enter the File name register, click Next (the .xhtml extension will be appended automatically anyway), select the template New Facelet Page (which we have definied in the preferences) and click Finish.

  2. Change the <title> to Register user and add the following ajax-flavored form to the body of the view:
    <h:form>
        <h:panelGrid columns="3">
            <h:outputLabel for="username">Username</h:outputLabel>
            <h:inputText id="username" value="#{register.user.username}" required="true">
                <f:ajax event="blur" render="usernameMessage" />
            </h:inputText>
            <h:message id="usernameMessage" for="username" />
    
            <h:outputLabel for="password">Password</h:outputLabel>
            <h:inputSecret id="password" value="#{register.user.password}" required="true" redisplay="true">
                <f:ajax event="blur" render="passwordMessage" />
            </h:inputSecret>
            <h:message id="passwordMessage" for="password" />
    
            <h:outputLabel for="email">Email</h:outputLabel>
            <h:inputText id="email" value="#{register.user.email}" required="true">
                <f:ajax event="blur" render="emailMessage" />
            </h:inputText>
            <h:message id="emailMessage" for="email" />
    
            <h:outputLabel for="birthdate">Birthdate (yyyy-MM-dd)</h:outputLabel>
            <h:inputText id="birthdate" value="#{register.user.birthdate}">
                <f:convertDateTime pattern="yyyy-MM-dd" />
                <f:ajax event="blur" render="birthdateMessage" />
            </h:inputText>
            <h:message id="birthdateMessage" for="birthdate" />
    
            <h:panelGroup />
            <h:commandButton value="Register" action="#{register.submit}">
                <f:ajax execute="@form" render="@form" />
            </h:commandButton>
            <h:messages globalOnly="true" layout="table" />
        </h:panelGrid>
    </h:form>
    You see, it creates a form with a 3-column table (however, a tableless form with a flood of CSS would semantically have been more correct, but that's beyond the scope of this tutorial, we teach JSF, not CSS). The 1st column contains the labels for input fields, the 2nd column contains the input fields and the submit button, the 3rd column contains the messages. The <f:ajax> tags in the input fields will submit (and validate!) only the current field and trigger a re-render of the associated message field when the JavaScript/HTML DOM blur event is triggered (when the field loses focus, i.e. when you tab out the field or click somewhere else on the page). The <f:ajax> tag in the command button will do a pure ajax submit instead of a normal submit. The globalOnly="true" in the messages field will only display messages whose client ID is null (as we've created in the managed bean's submit() method).
  3. Save the view.
Back to top

Run JSF web project in Glassfish

Now it's time to deploy the project to Glassfish and run it!

  1. Rightclick the Glassfish server entry in the Servers tab and choose Add and Remove Projects. In the wizard, select the Playground project under Available Projects and click Add to add it to Configured Projects. Click Finish.
  2. Rightclick the Glassfish server entry in the Servers tab and choose Start. You can also start it by clicking at the green arrow at the toolbar of the box. Glassfish is started successfully if the server.log in the Console tab (click the blue monitor icon on the right top to switch between consoles if necessary) displays at least the following line:
    INFO: Playground was successfully deployed in 3,770 milliseconds.
    
    Note that it may take longer or shorter, depending on whether the server has already started for the first time before or not.
  3. Once it is started, go to http://localhost:8080/playground/register.xhtml in your favourite webbrowser. Note that the .xhtml extension must match the URL pattern of the FacesServlet mapping as we have definied in step 4 of chapter Prepare JSF web project in Eclipse. Such a request URL will then trigger the FacesServlet and it will create the FacesContext and do all the JSF works.

    If you get a timeout or kind of an unknown host error message, then doublecheck if Glassfish is started properly and if the port is correct. If you get an internal server error, then an exception was been thrown and is available in the server log. Also try to interpret and understand the exception message and the trace, if necessary with help of Google, and then fix the code accordingly.
  4. Play around it in your browser! Tab through the fields, enter values, remove values, press the submit button, etcetera. You'll note that it's running smoothly thanks to all the new JSF 2.0 ajax works.
Back to top

Extra! Finetuning validation

You'll probably have noticed that the default validation error messages are scary and you would probably also like to add a bit more strong password and email validation. Now, you can finetune the validation messages in several ways.

  1. Those j_idt6:username, j_idt6:password, etc are actually client ID's of the input elements (that is, the generated id of the HTML input element which you can see when you do rightclick and View Source of the opened page in the webbrowser). The j_idt6 part (which can differ) is controllable by giving the <h:form> a fixed id.
    <h:form id="form">
    
    Edit it accordingly in the register.xhtml, save it and refresh the page (no server restart is required! Glassfish hotdeploys extremely fast, you don't need to wait for anything, just refresh the page in browser). Trigger the validation and you'll see form:username, form:password, etc instead.
  2. That's already less scary. However, we can make the labels more human friendly by defining them in the label attribute of the input components.
    <h:inputText id="username" label="Username" ... >
    ...
    <h:inputSecret id="password" label="Password" ... >
    ...
    <h:inputText id="email" label="Email" ... >
    ...
    <h:inputText id="birthdate" label="Birthdate" ... >
    Edit accordingly, save source, refresh page in browser, play around it. No pain!
  3. Better, but still too "mechanic". However, there's a way to replace the entire default required and conversion message in the view side by defining them as requiredMessage and converterMessage accordingly.
    <h:inputText id="username" requiredMessage="Please enter username" ... >
    ...
    <h:inputSecret id="password" requiredMessage="Please enter password" ... >
    ...
    <h:inputText id="email" requiredMessage="Please enter email" ... >
    ...
    <h:inputText id="birthdate" converterMessage="Please enter date in yyyy-MM-dd format" ... >
    Rinse and repeat.

    There are other ways as well, for example defining them as <message-bundle> in the faces-config.xml, but that's beyond the scope of this tutorial.
  4. We can also do the validation straight in the model instead of the view. This can be more useful if the model is a JPA entity. Glassfish ships with builtin bean validation (also known as JSR 303) which is anticipated seamlessly by JSF 2.0. It ships with several validation constraint annotations such as @NotNull.

    First remove the required and requiredMessage attributes from the three input fields username, password and email. Then add the @NotNull annotation on exactly those properties of the model (note that this only works when you've added the javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL context parameter as described in step 6 of chapter Prepare JSF web project in Eclipse, otherwise you need the Hibernate validation specific @NotEmpty annotation instead!).
    
        private Long id;
      
        @NotNull
        private String username;
      
        @NotNull
        private String password;
      
        @NotNull
        private String email;
      
        private Date birthdate;
    
    
    Save and refresh browser (no, still no server restart needed here as well!)
  5. Again, the messages are too generic: "may not be null". We can however customize them straight in the model by the message field of the annotation.
    
        private Long id;
        
        @NotNull(message = "Please enter username")
        private String username;
        
        @NotNull(message = "Please enter password")
        private String password;
        
        @NotNull(message = "Please enter email")
        private String email;
        
        private Date birthdate;
    
    
    Save, refresh, play.

    Now we're back at the same state as with view-level validation finetuning.

    Which one you should be using in your projects really depends on the requirements. For example, if you want to be able to run this on a random Tomcat machine or non-Java EE 6-container (JSF 2.0 is by itself backwards compatible with Java EE 5 / Servlet 2.5), then forget bean validation.
  6. We can even use regex to validate the strengthness of the password and correctness of the email. For this the JSR 303 @Pattern annotation is useful. We want the password to be at least 8 chars in length, contain at least one digit, at least one lowercase alphabet letter and at least one uppercase alphabet letter. We also want the email to be syntactically valid with regard to the @ and the .. We shouldn't care about the actual characters in the email address.
    
        private Long id;
        
        @NotNull(message = "Please enter username")
        private String username;
        
        @NotNull(message = "Please enter password")
        @Pattern(regexp = ".*(?=.{8,})(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).*", message = "Password is not strong enough")
        private String password;
        
        @NotNull(message = "Please enter email")
        @Pattern(regexp = "([^.@]+)(\\.[^.@]+)*@([^.@]+\\.)+([^.@]+)", message = "Email is not in valid format")
        private String email;
        
        private Date birthdate;
    
    
    Rinse and repeat.
Back to top

And now?

Play with it! Head if necessary to Communication in JSF 2.0 article to learn about some tips and tricks.

Here are the most important JSF 2.0 related links to be bookmarked and read thoroughly:

  • JSF 2.0 specification (pick the 1st download link), it explains why JSF is there, how it works and what it all provides.
  • JSF 2.0 API documentation, it contains detailed javadocs of the JSF API classes, it explains where the classes are for, how to use them and what all fields/methods do.
  • JSF 2.0 tag documentation, it shows which JSF tags are all available, what they all do and which attributes they supports.
  • Java EE 6 tutorial, chapter 4 and on contains Sun's Oracle's own JSF 2.0 tutorial.
  • If you want to get a book, I highly recommend the JSF 2.0: The Complete Reference, one of its authors, Ed Burns, is the lead of the JSF specification. If you want to get a step further with Glassfish, then Java EE 6 platform with GlassFish 3 is also an excellent choice.
  • Another excellent online resource is the Mkyong.com JSF 2.0 Tutorials. It contains lot of high quality JSF 2.0 examples (although there are unfortunately a bit too much advertisements, it's sometimes demotivating). There are other sites as well, but please don't even take a look at Roseindia.net.

Finally you can check the Favorites section at the right column of this blog site for more interesting links (of which the majority of the older ones are still targeted on JSF 1.2, the future articles will cover JSF 2.0 anyway).

Back to top

Copyright - None of this article may be taken over without explicit authorisation.

(C) January 2011, BalusC

58 comments:

Gimby said...

Really, really nice article. Perhaps I'll make the effort to do the setup part for JBoss 6 (with the JBoss-Tools plugin) :)

Excellent that you can now put images in your blog by the way; I was waiting for such a feature! I actually had to dig it up in the manual :/

Brian said...

love your articles. this one is excellent as usual. one quick question regarding JSF 2.0 and Ajax. Currently we have a JSF 2.0 running on Weblogic 10.3.3. application server. however when we try to use an Ajax functions like:



it fails with the following exception:

Tag Library supports namespace: http://java.sun.com/jsf/core, but no tag was defined for name: ajax
at com.sun.facelets.compiler.CompilationManager.pushTag(CompilationManager.java:193).....

Any ideas on what's causing this issue? Is it a Weblogic issue or something else?

BalusC said...

@Brian: look like JSF 1.x libs are still somewhere in classpath.

Unknown said...

Thanks for the lovely post it did worked perfectly the screen shots were very helpful..
there is an small typo for the url

it should mention register.xhtml instead of test.xhtml as mentioned in the blog

http://localhost:8080/playground/register.xhtml

I am looking to migrate the app which I am working on jsf 1.2 as having lots of issue with using tomahawk..

once again thanks for the lovely post

BalusC said...

@Ameya: Thanks for pointing the mistake! I've immediately rectified it.

Antonio Garcia said...

Another resource http://www.coreservlets.com/JSF-Tutorial/jsf2/

gabriel! said...

BalusC I can't find any decent tutorial on how to deal with files in web applications using JAVA EE 6.

Here's the situation. I upload a file using JSF's primefaces Library. Since EJBs spec prohibits accessing files I store that Image in the database. But that's just not what I want. I want to store the image in a file so I can use graphicImage to display that statically.

How can I achieve this? People has suggested using ftp servers etc. But I could not get this working. Can you help me out?

Unknown said...

great article!

Unknown said...

Hi BalusC,
I really appreciate your wide knowledge of java and JSF.
I'm quiet desperate now, thats why I'm contacting you this way. I'm trying to programmatically insert Composite Component to JSF 2 page. I finnaly somehow managed to insert Composite Component into jsf page. But now I can't nest any component in it (add as child) It just don't get rendered.
You can see code I already worked out at http://stackoverflow.com/questions/5370184/how-to-programmatically-or-dynamically-create-a-composite-component-in-jsf-2

Thank you very much BalusC.

Unknown said...

I have never seen an article like this before for JSF. Thank you very much for your great effort and also nice explanation.

Unknown said...

Thank you very much !!!!!!!

Unknown said...

This is a seriously awesome tutorial! Thanks for taking the time to put it together.

David said...

thanks for this really helpful tutorial

Vaish said...

Thanks BalusC for this post! I admire your zeal to share knowledge.

Luiz Cláudio said...

That is simply great!!
It's a really very interesting post!
BalusC, could you recommend me a book in which i can find a complete case study. I mean, a book in which the author constructs an application from the scratch, using jsf, hibernate (or another jpa implementation), facelets, prime faces, iReports (or jasper)...

I'm asking you cause i see you are really experient in it.

Thank you for sharing knowledge!!

P.S. sorry if i got a mistake when writing, cause i am a brazilian student :)

Anonymous said...

Thanks BalusC, i'm a great fan of your work (here and on StackOverFlow), =)

Zmitro Lapcionak said...

hi. thanks for the tutorial! i successed to create the application, but when i go the mentioned url, i got the exception

PWC1406: Servlet.service() for servlet facesServlet threw exception
com.sun.faces.context.FacesFileNotFoundException

Can you help me, where to search the solution?

Zmitro Lapcionak said...

sorry for silly comment above. I misplaced the *.xhtml file: not under WebContent, but under WEB-INF. so faces factory couldn't find the faces file.

MaryT said...

Is this tutorial available with directions for the MAC OS?

justweird said...

thanks.. :)
just a suggestion.. alot of ppl would like to thank you for ur tutorial and the comments section are full of it.. why not add "thanks" or "like" link with a counter just like facebook.. so that the comment will be clean and only contains discussion abt the topic.

GDP said...

Hi i have one doubt.
I have one jsp page with 2 textboxes and link as anchor a href. while clicking that link a JSF page should be opened in popup loaded with that 2 text box values in jsp and some operation have to be done..pls suggest ur ideas

ifti said...

wow i was looking for such stuff. thanks for sharing.

Code Turner said...

+1 -- Excellent tutorial!

Javier Latorre said...

BalusC. I can´t forget all the times when your codes save my life, Thanks for help me to keep my work! :D

Bill said...

Great tutorial. I tried several others before yours and all had major stumbling blocks. I got through yours first time. Thanks!

Made A Difference For That One said...

Great Tutorial! I got only one error: "/register.xhtml Not Found in ExternalContext as a Resource" but it was because I misspelled and wrote (R)egister instead of (r)egister. I am very new to Java and JSF but this tutorial gave me hope. Thanks, thanks, thanks!

Kinjal Desai said...

Thanks for simply superb tutorial. I was able to run the sample web app using Eclipse Indigo + Apache tomcat 7.0.

However I am facing issues with bean validation. (Extra validation).

- I have configured step-6 properly. (javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL)

- Also, as I am not using glassfish, I have included all ExtVal (bean validation for Myfaces, IMO) jars properly in my project.

- I am able to execute the app properly, but validation messages are not appeared as defined in @NotNull.

- I am getting...
"javax.faces.component._ExternalSpecifications isBeanValidationAvailable
INFO: MyFaces Bean Validation support disabled"
as last line in tomcat console.

kindly let me know what I am doing wrong.

rb_bp said...

Hi BalusC--

Do you use (or can you reccomend) a plugin for Eclipse that will allow one to do visual-based editing of a JSF page? I am looking at using Trinidad components and have tried the Oracle Enterprise Pack for Eclipse but it is not truly a WYSIWYG editor. Also it only supports JSF 1.2 and not 2.x.

David said...

Very very nice post

As a jsf newbie this really helped

thanks

Ganto said...

Great Post.

Very detailed step by step guide with good explainations!

animeworld said...

Very nice! Thank you a lot! =)

Asif Raza said...

Very nice, thanks

Unknown said...

Great. Your tutorials are always helping me. simple and useful, thank you for helping people code better.

sanjeev sinha said...
This comment has been removed by the author.
Unknown said...

I am getting exception..

javax.faces.component._ExternalSpecifications isBeanValidationAvailable
INFO: MyFaces Bean Validation support disabled"
as last line in tomcat console.

pls suggest how to trace it..

genex said...

was looking for this detailed tutorial. especially with that section wise MVC headlined descriptions.

very well written. Am also following your answers in stackoverflow. out there you just rock

Alixandre said...

Great tutorial.
Details, explanations are the best possible.
Tks, man!

Unknown said...

@BalusC: The ajax request is sent to the server on "blur",

f:ajax event="blur" render="usernameMessage"

What is usernameMessage on the server?

Unknown said...

Truly a very cogent explanation of the MVC design paradigm for JSF.

I thought the comment on Roseindia was a bit rough... I like to read their posts for a laugh or when I am getting fed up with such things as:-
which doesn't actually work and cost me three days of frustration. When I re-coded it as "2" everything worked fine, buttons rendered, ajax stopped going off by itself etc.
Best Regs

Tim

Unknown said...

The bit that got missed out was:
...

Good eh?

Unknown said...

OK.... html tags are rendering in the page. Lets try \

Unknown said...

I give. The essence was:-
p:panelGrid columns="#{bean.list.size()}+1"

BalusC said...

@Tim: please use "Preview" button :) You can use &lt; instead of < to start HTML/XML tags.

Unknown said...

@BalusC

Your contribution to the JSF is really appreciated.Great Work.

Look like One small typo there,URL should contain Uppercase 'P' because project name mentioned as "Playground" instead "playground" at the top.

BalusC said...

@Sudheer. You're welcome. As to the URL, please see point 3 of "Prepare JSF web project in Eclipse" how to make it lowercase.

Anonymous said...

Great Article.

Like Glassfish integration with Eclipse, is it possible to integrate Weblogic server seamlessly with Eclipse?

John Muñoz said...

Hi, BalusC I've a question, in a JEE5 app what is the best way to call an ejb directly by a @EJB or create a singleton that access the Enterprise Java Bean, this in terms of performance, thanks in advance

Dj Manu de Hanoi said...

Hi Balus,
I Highly recommend using Tomee (previously openEJB) instead of Glassfish as a test server.
Startup time (each time I want to test a change in java code ) on tomee for my app is 10 sec versus 30 or more sec for glassfish

Unknown said...

I followed the directions and can access the page but after i fill out the form and hit submit nothing happens. Also i do not get any messages next to blank fields. What am i doing wrong?

Unknown said...

Great tutorial!

Subrahmanya V said...

Finally got cracking with JSF 2, thanks to your post. I was able to run this on Tomcat without any problems whatsoever. Many thanks for this wonderful post.

Unknown said...

Hi, nice blog really good info.
I got a question, i'm a kind of new securing web applications, and i'm trying to handle users sessions, so my question is:
Should i handle users sessions with @sessionSocped Managed Beans? or there is another way to handle this sessions?

Thx,


Mike

Unknown said...

hello,

when i execute this tutorial i get this message :


HTTP Status 404 - Not Found

--------------------------------------------------------------------------------

type Status report

messageNot Found

descriptionThe requested resource is not available

Unknown said...

Hi BalusC. Thank you very much for all your efforts.
I did exactly as you mentioned in your tutorial except that Servlet api for me is 2.5 (3.0 is not in the list), but I get the below error. Could you please help me with that?
INFO: javax.el.PropertyNotFoundException: /register.xhtml @14,86 value="#{register.user.username}": Target Unreachable, identifier 'register' resolved to null

Unknown said...

I changed JSF 2.1 to JSF 2.0 and it worked fine.Is it really the issue?

Unknown said...
This comment has been removed by the author.
blog4scs said...

Thanks for your tutorial. I followed the same steps as mentioned in your tutorial except that I used Tomcat 7.0.55 and added JSF 2.0 (Mojarra 2.0.3-FCS). When I try to run the application I am getting the following error. Not sure what I am missing.

IDE : Eclipse Juno Service Release 2
HTTP error : HTTP Status 500 - null source
URL : http://localhost:8080/Playground/register.xhtml
Exception
javax.servlet.ServletException: null source
javax.faces.webapp.FacesServlet.service(FacesServlet.java:321)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

Root cause
java.lang.IllegalArgumentException: null source
java.util.EventObject.(EventObject.java:56)
javax.faces.event.SystemEvent.(SystemEvent.java:67)
javax.faces.event.ComponentSystemEvent.(ComponentSystemEvent.java:69)
javax.faces.event.PostRestoreStateEvent.(PostRestoreStateEvent.java:69)
com.sun.faces.lifecycle.RestoreViewPhase.deliverPostRestoreStateEvent(RestoreViewPhase.java:256)
com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:245)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:107)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

Loubna said...

thanks for this really helpful tutorial