Developing Great Software

Sunday, August 14, 2011

Apache Wicket Interfaces & Methods To Master – An Introduction

The Apache Wicket Web framework is the best thing that’s ever happened to Java based Web development. That’s a bold statement and obviously my opinion but there appears to be a growing consensus in that area as more Java developers are exposed to this fabulous framework (I’ll address my concern of what I perceive as a very poor attempt to promote Wicket in a later blurb or two or future article).

One of the joys of working with Wicket is, of course, that developing with Wicket means developing with Java, HTML, CSS and Javascript. By some, though, this is seen as one of Wicket’s greatest weaknesses and those who shun this pure or clean approach the loudest tend to be those who prefer to work with visual, development-time components that are common to various other frameworks such as JSF. Their argument, however, tends to fall upon deaf ears by those of us who have ever worked on either a corporate or commercial Web project of even medium size and complexity.

Perhaps the biggest single hurdle that budding Wicket developers face is mastering the various Java interfaces, classes and methods that are required to pull everything together in a Wicket application. Most Web applications have to deal with memory, sessions, security (restricting access to resources to authenticated and authorized users), file (resource) contribution, AJAX behaviors and request handlers, code reuse, etc. These are very common concerns every Web developer addresses yet the implementation of some of these concerns aren't well documented or have little if no example code to demonstrate how to address them using Wicket.

As a result, a Wicket ‘newbie’ is typically left dumbfounded when first contemplating addressing these concerns for the first time in their own Wicket applications. This is unfortunate and unnecessary because all these issues are addressed by Wicket’s numerous interfaces and mentods that it exposes. The problem is that numerous important interfaces and methods are either not well documented or they lack valuable example code which would serve to provide a context for their use.

In the articles to come I will attempt to unravel, explore and promote the use of some of these interfaces and methods and provide numerous examples of their use. To begin I’ll start with the various ways that a Wicket developer can employ Javascript and Ajax on their pages. I'll discuss the basics such as how a component can contribute Javascript to a page, how to handle callbacks to the component listeners and how to render Javascript that is called by Wicket's Ajax library before and after it calls the Ajax request's component listener.

I’ll be using NetbBeans 7 throughout the articles to develop the code because in my opinion no other IDE provides the level of support for Wicket development that NetBeans and its Wicket plugin does. If you haven’t already, download and install NetBeans 7 and then install the latest release of the Wicket plugin; both can be found by visiting http://netbeans.org/. If you would like to learn about the numerous productivity enhancing features provided by the latest release of the Wicket plugin and how to install it please read my article at http://jeff-schwartz.blogspot.com/2011/04/netbeans-7-wicket-plugin.html.

UPDATED 8/14/2011
This and all future related articles on Wicket will now appear at my new blog site The Wicket Evangelist.

Saturday, May 7, 2011

Bugs In NetBeans 7.0 GlassFish 3.1 Integration

I’m running the EE version of NetBeans 7 on Windows Vista (32 bit) and frequently I get the following notification error when deploying to GlassFish 3.1:

2011-05-07 08h04_54

Seems there is some conflict with the native file system but not having researched the error I could be totally wrong. The worst thing about this is that it causes deployments to GlassFish 3.1 to fail and I often have to restart the server to continue testing. Sort of puts a crimp in the edit & refresh cycle that I’ve come to expect.

I’ve also experienced another bug which occurs upon opening NetBeans 7 with a project using GlassFish 3.1. NetBeans will prompt me, alerting me that the application’s server configuration is wrong. When I then go to Tools | Servers GlassFish 3.1 isn’t listed and I have to add it again to the list of registered servers, though because it is already installed on my development machine I don’t have to reinstall it. This seems to temporarily correct the problem until the next time I open NetBeans 7 with a GlassFish 3.1 project.

Hopefully, these bugs will be quickly addressed in a point release.

Thursday, April 28, 2011

The NetBeans 7 Wicket Plugin

Geertjan Wielenga has released an updated version of the Wicket Plugin for NetBeans 7.  For us Wicket fanatics this is indeed great news. The plugin adds some really nice enhancements and productivity features to the NetBeans platform and, when taken in total, in my opinion makes NetBeans the undisputed best platform for Wicket development.

If you haven’t done so already I urge you to download this plugin from the NetBeans plugin portal and install it into NetBeans 7. For those of you not familiar with installing plugins from the NetBeans portal, here are the steps you should follow:

Installing The Wicket Plugin

1. Go to http://plugins.netbeans.org/plugin/3586/wicket-1-4-support and click the Download button to download the zip file to your computer. Once it is downloaded extract all the files. On Windows you can extract the files by right clicking the file with your mouse and selecting Extract All.

2. Start up NetBeans if it isn’t already and select Tools | Plugins from the main menu. This will open the Plugin window.

3. Select the Downloaded tab and then select the Add Plugins button.

4. Navigate to the folder where you the extracted files reside, select all 3 files and then select the Open button.

2011-04-28 19h44_53

5. Select the Install button and NetBeans will install the plugin modules after which you will be prompted to restart NetBeans. Please, restart NetBeans.

Create A Wicket Project

Lets explore some of the productivity enhancing features that the Wicket plugin provides. We’ll start first by creating a new Wicket project.

1. From the main menu select File | New Project. Then, select Java Web from the Categories panel and select Web Application from the Projects panel and then select Next.

2. Enter any name you like for the Project Name and select Next.

3. Select Apache Tomcat 7.0.11 for the Server (if you prefer, you can also select GlassFish 3.1) and Java EE 6 Web for the Java EE Version and select Next.

4. In the Frameworks step you can see that there is an option to select Wicket as the framework you want to use in your application. This is the 1st and most obvious contribution that the Wicket plugin provides, easy integration of Wicket into a NetBeans Java Web project. When you select Wicket the Plugin provides you with numerous configuration options such as the name of the Wicket filter and the URL pattern, for instance. For our run through we are going to accept all the defaults.

2011-04-28 20h01_37

5. Select Wicket and then select Finish. NetBeans will now generate a starter Wicket application.

Fully expand the newly created project in the Projects panel.

2011-04-28 20h13_02

As you can see from the above, the Wicket plugin created a complete Wicket starter project, libraries and all. It also created numerous Wicket components: BasePage, FooterPanel, HeaderPanel and HomePage as well as the required Application.java class. The plugin also configured web.xml according to the configuration parameters that we chose in the Frameworks step.

Run The New Wicket Application

Now, from the main menu select Run | Run Main Project to run the newly created application. As you can see from the rendered page in the browser, the starter project, though trivial, is rather nice - it has a header section, a middle section for content and a footer section, too.

 

2011-04-28 20h21_38

You will, of course, want to modify the starter project to match your own application’s requirement but because the starter project uses Wicket Markup Inheritance you will be able to do this rather easily.

The Starter Project

Lets explore the components that the plugin generated for us.

Open the BasePage component by double clicking on either BasePage.html or BasePage.java. When you click on either, both files will open. This behavior is contributed by the Wicket plugin and I find it extremely convenient.

Now, lets look at BasePage’s markup and java implementation.

<!DOCTYPE html> 
<html xmlns:wicket="http://wicket.apache.org"> 
    <head> 
        <meta charset="UTF-8"> 
        <meta name="description" content="Put your description here!" /> 
    <wicket:head> 
        <wicket:link> 
            <link rel="stylesheet" type="text/css" href="style.css"/> 
        </wicket:link> 
    </wicket:head> 
</head> 
<body> 
    <header wicket:id="headerpanel" />
    <section class="content_container"> 
        <wicket:child/> 
    </section> 
    <footer wicket:id="footerpanel" /> 
</body> 
</html>
package com.myapp.wicket;           

import org.apache.wicket.markup.html.WebPage;

/** 
 *
 * @author Jeff
 * @version 
 */

public abstract class BasePage extends WebPage {

    public BasePage() { 
        super(); 
        add(new HeaderPanel("headerpanel", "Welcome To Wicket")); 
        add(new FooterPanel("footerpanel", "Powered by Wicket and the NetBeans Wicket Plugin"));
    } 

}

BasePage.html’s header contributes style.css, which is a packaged resource that resides in the same package as the BasePage component. By using wicket:head and wicket:link tags, Wicket will be able to resolve the reference to style.css and include it in the rendered page.

In the body of the page there are place holders for the header and footer panels. There’s also a wicket:child tag declared which will allow any page that inherits from BasePage to contribute its content to the page. This is what Wicket calls ‘Markup Inheritance’. I’ll show you how this is used when we look at the HomePage component later in the article.

BasePage.java’s implementation is what you would expect to find considering the markup we just explored. BasePage derives from WebPage and after calling into its super class BasePage’s contrcutor adds the HeaderPanel and FooterPanel components to the page. The constructors for both of these components allows you to add the text that will be displayed for each as their second parameters.

Now, lets look at HomePage’s markup and java implementation.

<!DOCTYPE html> 
<html xmlns:wicket="http://wicket.apache.org"> 
    <head> 
        <meta charset="UTF-8"> 
    <wicket:head> 
        <title>Wicket Example</title> 
    </wicket:head> 
</head> 
<body> 
    <wicket:extend> 
       <h1 wicket:id="message">This gets replaced</h1>
    </wicket:extend> 
</body> 
</html>
package com.myapp.wicket;           

import org.apache.wicket.markup.html.basic.Label;

public class HomePage extends BasePage {

    public HomePage() {
        add(new Label("message", "Hello, World!"));
    }

}

Again, there are no surprises here but one item needs to be elaborated on. HomePage derives from BasePage and as I had mentioned, HomePage uses Markup Inheritance to contribute its markup to the page. It will attach its markup to the h1 tag which is sandwiched between the opening and closing wicket:extend tags. This is how Wicket Markup Inheritance works and it is a very powerful technique to use when you want to compose pages that have the same layout and appearance.

I’ll let you explore HeaderPanel and FooterPanel on your own though these also will be what you would expect as both implementations are derived from Panel.

Now lets explore some of the other productivity enhancements that the Wicket plugin provides.

Creating A New Page And A New Panel

To create a new Page, right click the package which currently contains our project’s components and select New | Wicket Page. Enter any name for the Page and select Finish. Two files, one html and one Java, will open in the browser.

Creating a new Panel is much like creating a new Page. Right click the package which currently contains our project’s components and select New | Wicket Panel. Enter any name for the Panel and select Finish. Two files, one html and one Java, will open in the browser.

Exploring Components With Navigator

The plugin adds what I call ‘Wicket Sense’ (my term for a lack of a better one) to the NetBeans Navigator. To see this in action, in the editor select the BasePage.html file and if it isn’t already, open the Navigator and select Wicket Tags from its list of views.

As you can see, the Navigator displays all the elements that include wicket:id attributes in their tags. Now switch editor views to BasePage.java and again, notice how the Navigator has identified all the Wicket components in the Java code.

Your will really appreciate Navigator’s Wicket Sense when you are dealing with large Java and markup files.

Jump To Implementation

Another nice feature that the plugin adds is the ability to jump to the Java implementation from within the markup file. In HomePage.html, hold down the control key and hover the mouse over the ‘message’ wicket:id value. An underline will appear and if you now click on ‘message’ the editor will switch views to the Java implementation, opening the file if it isn’t currently open in the editor.

The plugin doesn’t currently support jumping to the markup page from the implementation file but maybe a future release of the plugin will provide this feature.

Much Thanks And Appreciation

Geertjan deserves our thanks and he earns our appreciation for all the effort he has put into this plugin. In my opinion, the plugin empowers NetBeans to provide a level of support for Wicket development that no other IDE can currently match.

Geertjan, great job and thank you!

Well, that’s it for now but remember, busy hands are happy hands, so get going and explore this fabulous plugin and all its great features. Happy coding!

Wicket, Web Services, NetBeans And GlassFish

A reader recently emailed me and wanted to know about implementing a Wicket application within a Web Service environment.

I have not come across any reference where Wicket has been implemented
within a web service environment. None of the books I have read on
Wicket have addressed this area to my knowledge. I am wondering if you
have any insight as to how this would work.

The reader is expressing a very common misconception that a lot of developers have and that misconception is that you somehow have to integrate your Web Services into your Web application. Part of my response to the reader was:

“How you expose your web services has nothing to do with Wicket meaning you don't integrate your web services with wicket.”

Additionally, I went on to say:

“All you need is to create web services on glassfish (it has built in support for web services and Netbeans tooling makes this just so simple). If a client, whether your Wicket application or a paid subscriber for instance, needs to consume your web services it will consume the wsdl files produced when you created the web services.”

What I was trying to express to the reader is that Wicket is just a Web framework and not a Web Services provider. Wicket writes HTML to the browser and that’s about it. Wicket Web applications, however, can consume Web services, either those on the same server the Web application is running on or located on different servers. But Wicket itself doesn’t provide any means to consuming Web services - for that you use Java API for XML Web Services (JAX-WS).

I promised the reader that if I had the time I would write an article demonstrating how this is done which is the purpose of this article. So lets get started.

The remainder of this article assumes you have installed NetBeans 7 as well as the NetBeans Wicket plugin. If you haven’t, please do so now.

NetBeans, GlassFish v3.1 and JAX-WS

NetBeans 7 comes bundled with GlassFish v3.1 and GlassFish comes with Metro 2.1 as its SOAP Web Services provider. Metro 2.1 implements the JAX-WS specification. The synergy between Web Services, NetBeans and GlassFish is provided by the tooling built into NetBeans, which makes authoring and deploying your Web Services on GlassFish very easy, as we shall see later in this article.

When you create a Web Service you first have to decide how you want to package it (what type of application you will use to host your Web Service). You have 2 options:

1. JavaEE EJB Module project – this option should be used if your Web Services require access to EE containers. Web Services in this context are generated as Stateless SessionBeans. If your Web Service needs access to your database, for instance, you can achieve this using the @PersistenceContext annotation within your Web Service which will allow you to access your database via JPA.

2. Package in Web container – this option should be used if your Web Service doesn’t require access to other EE containers.

In this article I won’t actually cover accessing a database because I want to keep it simple but I will use a JavaEE EJB Module project and you can, if you chose, explore this later on your own by creating a Web Service method to access your own database.

Create A Web Service Project

1. If you haven’t already, fire up NetBeans and select File | New Project which will open the New Project window.

2. Select Java EE from the Categories panel and select EJB Module from the Projects panel and select Next.

3. Enter any valid project name you like in the Project Name text box. I am naming mine ‘EJBWebServicesAndWicketTutorial’. Select Next.

4. Select GlassFish Server 3.1 from the Server drop down list and make sure that Java EE 6 is selected in the Java EE Version drop down list. Select Finish to generate the project.

Create A Web Service

1. Right click the project node for the EJB project in the Projects window and select New | Web Service. This will open the New Web Service window.

2. Enter CalculatorWebService for the Web Service Name. Make sure that the Create Web Service from Scratch option is selected. Note that because our project is an EJB the Implement Web Service as Stateless Session Bean option is automatically selected for us and cannot be changed. Enter WebServices as the Package name and select Finish. NetBeans will generate your Web Service Java class in the WebServices package.

3. I will use a simple method for our Web Service that returns the sum of two integers. Replace the content of CalculatorWebService.java with the following:

package WebServices;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.ejb.Stateless;

/**
 *
 * @author Jeff
 */
@WebService(serviceName = "CalculatorWebService")
@Stateless()
public class CalculatorWebService {

    /**
     * Web service operation
     * @param i int
     * @param j int
     * @return  the sum of i + j as int
     */
    @WebMethod(operationName = "add")
    public int add(@WebParam(name = "i") final int i, 
    @WebParam(name = "j") final int j) {
        return i + j;
    }
}

From the above code you can see that the CalculatorWebService class is decorated with both @WebService and @Stateless attributes which is what you would expect. Also note that the add method is decorated with the @WebMethod attribute and that each of its parameters, i and j, are decorated with the @WebParam attribute.

I didn’t hand-code this though I could have. NetBeans can generate a Web method with all the correct attributes for you. If you select Design View and click the Add Operation button, NetBeans will present you with its Add Operation window that allows you to add a new Web Service method with all the proper attributes. I’ll leave this as an exercise that you can explore later on your own.

Testing The CalculatorWebService add Method

NetBeans tooling makes testing Web Services a snap so lets do that now to insure that our add service works as expected:

1. In the Project panel right click the Web Services node (not the WebServices package) and select Test Web Service which will open your browser and display the following

2011-04-28 10h23_51

2. Click the WSDL File link and save the URL somewhere (like Windows NotePad, for instance) and then page back to the above. We will use the URL in our Web Services client application, which we will build later on in the article.

3. Enter 4 in the first input field and enter 5 in the second input field and then click add. Your browser will then display the following

2011-04-28 10h30_27

As you can see from the above, the method correctly calculated and returned the sum of our two numbers. If you scroll down the browser page you can see the packaging for both the SOAP request and the SOAP response. Repeat this a few time with different sets of numbers.

We now have a working Web Service that can be consumed by any client that can consume a Web Service. Note how the Web Service we just built has no connection at all with Wicket – our project doesn’t even include the Wicket framework. Remember, Web Services provide a service whereas Wicket applications render HTML to the browser.

Now we know that our method works so lets create a Wicket application that will consume the Web Service. I’ll keep this simple and I assume that you have already installed the latest release of the Wicket plugin for NetBeans 7.

Create a Wicket Application

1. In NetBeans select File | New Project and select Java Web from the Categories panel and Web Application from the Projects panel. Enter any name you like for the Project Name, select Set As Main Project and select Next.

2. For Server select GlassFish Server 3.1 and for Java EE Version select Java EE 6 Web and select Next.

3. For Frameworks select Wicket and select Finish. NetBeans along with the Wicket plugin will generate a Wicket starter application project that includes the Wicket libraries. Also generated by the Wicket plugin are Wicket components for HomePage, BasePage, HeaderPanel, FooterPanel as well as the required Application.java and configuration files.

Now that we have a Wicket application we will use NetBeans to easily configure it to consume the Web Service we created previously.

Consuming Our Web Service

1. In the Projects panel right click the Web applications project node and select New | Web Service Client. This will open the New Web Service Client window.

2. Select WSDL URL and enter the URL that you saved previously when you tested the Web Service.

3. Enter a package name and make sure that JAX-WS Style is the selected option for Client Style. Select Finish. NetBeans will generate a Web Service Reference for us in the Web Service References folder.

Our Web application is now configured to consume the Web Service we previously created. Notice that in the above we configured our Web application using the URL that points to the Web Service’s WSDL. We could have used a project reference instead but I used the URL to emphasize that you can consume any Web Service running on any server, yours or some other, as long as you have access to its WSDL URL.

Now lets actually use the Web Service in our Wicket application.

1. In the Projects panel double click on the HomePage.html file. Notice how NetBeans opens it as well as the HomePage.java file. This behavior, among others such as generating a starter project, is a contribution of the NetBeans Wicket plugin.

2. Replace all the content in HomePage.html with the following:

<!DOCTYPE html> 
<html xmlns:wicket="http://wicket.apache.org"> 
    <head> 
        <meta charset="UTF-8"> 
    <wicket:head> 
        <title>Wicket Example</title> 
    </wicket:head> 
</head> 
<body> 
    <wicket:extend> 
       <h1 wicket:id="message">This gets replaced</h1>
       <form wicket:id="form" >
           <div wicket:id="feedbackpanel" />
           <input type="text" wicket:id="input1" /> + <input type="text" wicket:id="input2" /> = <span wicket:id="result" /><br/>
           <input type="submit" />
       </form>
    </wicket:extend> 
</body> 
</html>

From the above you can see that our markup is quite simple - we create a simple form with two text fields and a submit button.

Now, lets consume the add Web Service method.

1. Select the HomePage.java file and from the Projects panel and fully expand the Web Service References folder. Drag and drop the add method anywhere into the HomePage.java file and NetBeans will generate the call to our Web Service method for us. Rather than implement the rest of the code yourself you can replace the code in HomePage.java with the following

/*
 * HomePage.java
 *
 * Created on April 28, 2011, 6:30 AM
 */

package com.myapp.wicket;           

import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;

public class HomePage extends BasePage {
    
    private int input1 = 0;
    private int input2 = 0;
    private int result = 0;

    public int getInput1() {
        return input1;
    }

    public void setInput1(int input1) {
        this.input1 = input1;
    }

    public int getInput2() {
        return input2;
    }

    public void setInput2(int input2) {
        this.input2 = input2;
    }

    public int getResult() {
        return result;
    }

    public void setResult(int result) {
        this.result = result;
    }
    
    public HomePage() {
        add(new Label("message", "Enter 2 ints!"));

        Form<HomePage> form = new Form<HomePage>("form", new CompoundPropertyModel<HomePage>(HomePage.this)){

            @Override
            protected void onSubmit() {
                super.onSubmit();
                // Call the add web service method to calculate the result
                result = add(input1, input2);
            }
            
        };
        
        form.add(new FeedbackPanel("feedbackpanel"));
        form.add(new TextField<String>("input1"));
        form.add(new TextField<String>("input2"));
        form.add(new Label("result"));
        add(form);
    }

    private static int add(int i, int j) {
        webservices.CalculatorWebService_Service service = new webservices.CalculatorWebService_Service();
        webservices.CalculatorWebService port = service.getCalculatorWebServicePort();
        return port.add(i, j);
    }

}

In our java implementation we add the two text  fields to the form and the the form to the page. We override the form’s onSubmit method in which we call our Web Service method and assign its return value to result. When Wicket renders the page the page will display the result. Lets try it. Run the Web application and you should see the following

2011-04-28 11h32_22

Enter a valid numeric/integer value for both input fields and select Submit. The page will render with the result.

2011-04-28 11h34_05

Here is the result I get when I enter 10 and 14. The result, 24, is rendered back to the page. If you enter a non numeric value you will get an error message.

What We’ve Learned

As the examples here have demonstrated, an application that publishes Web Services is totally disconnected from any application that consumes its services. In our case, the consumer is a Wicket application. Wicket renders HTML and in our case it renders the result of calling our Web Service.

Our Web Service implementation knows nothing about any client application that may use its services. The client application consumes the Web Service via the WSDL.

In addition, NetBeans and its GlassFish tooling really makes both publishing and consuming Web Services ridiculously easy and the NetBeans Wicket plugin, with its ability to create a starter project as well as Wicket Pages and Panels is a great productivity booster.

I hope you have enjoyed this little walk-through of publishing and consuming Web Services with NetBeans, GlassFish, Wicket and the NetBeans Wicket plugin. Please feel free to leave a comment or a question.

Friday, April 22, 2011

Proposed Changes To The Netbeans Wicket Plugin’s Generated Starter Project

Currently, BasePage adds its markup to HomePage’s markup which is a subclass & that isn't a good practice. Just 1 file needs to be added, BasePage.html & it should include markup for the header panel. Then BasePage.java should be modified to add the header panel component to that.

I recommend that BasePage.html be implemented as follows:

<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
    <head>
        <meta charset="UTF-8">
        <meta name="description" content="Put your description here!" />
    <wicket:head>
        <wicket:link>
            <link rel="stylesheet" type="text/css" href="style.css"/>
        </wicket:link>
    </wicket:head>
</head>
<body>
<section class="container" wicket:id="headerpanel">
</section>
<section class="content_container">
    <wicket:child/>
</section>
<footer>
    <span>Put your footer here</span>
</footer>
</body>
</html>

and that BasePage.java be implemented as:

import org.apache.wicket.markup.html.WebPage;

public abstract class BasePage extends WebPage {

    public BasePage() {
        super();
        add(new HeaderPanel("headerpanel"));
    }
   
}

and that HomePage.html be implemented as:

<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
    <head>
        <meta charset="UTF-8">
    <wicket:head>
        <title>Title goes here!</title>
    </wicket:head>
</head>
<body>
<wicket:extend>
    <!-- Page specific markup goes here -->
</wicket:extend>
</body>
</html>

and that HomePage.java be implemented as:


package com.buzzwords.wicket;

import org.apache.wicket.markup.html.link.Link;

public class HomePage extends BasePage {
   
    public HomePage() {

    }
}

Now BasePage remains blissfully ignorant of HomePage and its markup hierarchy.

My example is using the new html5 doctype and character encoding specifications as well as some html5 tag candy.

Thursday, March 31, 2011

Java EE6 & Wicket - Article #6 – A Wrap Up

Welcome to the 6th in a series of detailed articles on Java EE6 & Wicket. If you haven’t already, please read the following previous articles before continuing.

  1. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html
  2. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html
  3. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html
  4. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html
  5. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-4-adding-jpa.html

In this, the 6th and final article in this series, we will examine the code, focusing on the integration we provided for consuming the EJB in our HomePage. I will also discuss some best practices that I’ve used here, especially pertaining to Wicket components and project structure.

Consuming EJB In Wicket

In article #3 we added the JavaEE Inject jars to the GuestBook project. JavaEE Inject is a Wicket module that provides integration through Java EE 6 resource injection and supports three annotations:

  1. @EJB
  2. @PersistenceUnit
  3. @Resource

With JavaEE Inject any Wicket application running in a Java EE6 container can consume the above 3 types of JavaEE resources. Before an application can use them, however, its WebApplication class method init must be overridden to add the JavaEEComponentInjector into Wicket’s request cycle. The code is simple as shown below:

@Override
    protected void init() {
        super.init();
        addComponentInstantiationListener(new JavaEEComponentInjector(this));
    }

What we are doing in the above code is calling Wicket’s Application class method addComponentInstantiationListener with a reference to a JavaEEComponentInjecter object which the JavaEE Inject module provides. addComponentInstantiationListener adds the JavaEEComponentInjector object to its lists of component instantiation listeners that it maintains.

With the JavaEEComponentInjector now maintained whenever a Wicket component is instantiated, JavaEEComponentInjector will scan the component for one of the above three annotations and injects their associated resources into the component.

There is one limitation, though, imposed by JavaEE Inject and that is it can only inject resources into a component that is a subclass of WicketPage. This  has implications on the modularity of our code in that we can’t directly reference EJB methods, for instance, directly in classes that aren’t derived from WebPage. Or can we? Well, we can and I will show you how we did it in GuestBook.

Techniques For Using JavaEE Inject Resources Outside Of WebPages

GuestBook uses an instance of a DataView to display the list of names of its visitors. A DataView requires a pseudo model of type IDataProvider<T> dataProvider to provide the data that it displays and GuestDataProvider serves that purpose. GuestDataProvider uses methods from our session bean to access the data in the guest table but it, like HomePage, is declared in its own file so how can it access the session bean and call into its methods?

The solution was to create the following interface that GuestDataProvider implements:

public interface IEjbDataProvider<T> extends IDataProvider<T> {
    AbstractFacade<T>  getFacade();
}

GuestDataProvider is declared as abstract because it doesn’t actually implement getFacade which is defined as returning an instance to AbstractFacade. Instead, GuestFacade relies on its subclasses to provide the method’s implementation.

In the HomePage constructor we create an instance of a GuestDataProvider and override its getFacade method by returning the reference to our session bean.

public class HomePage extends BasePage {

    @EJB(name = "GuestFacade")
    private GuestFacade guestFacade;

    public HomePage() {
        super();

        add(new FeedbackPanel("feedback"));

        /*
         * A loadable and detachable model whose sole purpose is to always
         * return a new Guest object when its load method is called.
         */
        LoadableDetachableModel<Guest> newGuestLoadableDetachableModel = new LoadableDetachableModel<Guest>() {

            @Override
            protected Guest load() {
                return new Guest();
            }
        };

        /*
         * The guestForm uses a nested model. The outer model is a compound property
         * model and the inner model is a light weight loadable and detachable model.
         */
        Form<Guest> guestForm = new Form<Guest>("guestform", new CompoundPropertyModel<Guest>(newGuestLoadableDetachableModel)) {

            @Override
            protected void onSubmit() {
                Guest guest = getModelObject();
                guestFacade.create(guest);
                setModelObject(new Guest());
                guest = new Guest();
            }
        };

        /*
         * Add the custom NameTextField compent for
         * first and last name to the form, nesting each
         * in a FormComponentFeedbackBorder for displaying
         * data entry errors.
         */
        guestForm
                .add(new FormComponentFeedbackBorder("firstNameBorder")
                .add(new NameTextField("firstName")));
        guestForm
                .add(new FormComponentFeedbackBorder("lastNameBorder")
                .add(new NameTextField("lastName")));
        add(guestForm);

        GuestDataProvider gdp = new GuestDataProvider() {

            @Override
            public AbstractFacade<Guest> getFacade() {
                return guestFacade;
            }
        };

        /*
         * When dealing with potentially large lists of data it is
         * better to use a DataView whose constructor takes a data
         * provider as its second parameter.
         */
        DataView<Guest> guestListView = new DataView<Guest>("namelist", gdp) {

            @Override
            protected void populateItem(Item<Guest> item) {
                Guest guest = item.getModelObject();
                item.add(new Label("name", guest.toString()));
            }

        };

        add(guestListView);

    }
}

This demonstrates that though JavaEE Inject places restrictions on where we can inject resources there are simple patterns that we can employ to overcome them.

Wicket Models Put To Best Use

HomePage also uses loadable/detachable models for both the form and the list of visitor names it displays. When Wicket completes its request cycle the components containing them will not contribute any model data to the serialization of the page.

Though I won’t go into detail here, understanding and mastering Wicket models is a critical component of your Wicket education. If you don’t know the difference between static and dynamic models or you aren’t familiar with loadable/detachable models you can read my article here to get up to speed on this subject.

Components

Now, lets talk a bit about Wicket components and some ideas that I’d like to share with you.

Whenever I develop a Web application I like to encapsulate business rules so that they can be reused. Presentation components are a prime target for encapsulating business rules, especially if they are used more than once on a page or on more than one page. Business rules encompass issues like requiring the user to enter a value for an input field, min and max values, etc.

Some frameworks make extending their presentation components more difficult than one would imagine. On the other hand, this is one area where Wicket shines – Wicket’s components are strikingly easy to extend and to imbed business rules in.

In article #1 we expressed the business rules for GuestBook as follows:

  • Limit the number of characters our visitors can key in for their first and last names to a maximum of 45 characters each.
  • Both first and last name are required.

GuestBook uses NameTextField, a subclass of TextField, to encapsulate and enforce its business rules.

public class NameTextField extends TextField<String>{

    /**
     *
     * @param id
     * @param model
     */
    public NameTextField(String id, IModel<String> model) {
        super(id,model);
        setRequired(true);
    }

    /**
     *
     * @param id
     */
    public NameTextField(String id) {
        this(id,null);
    }

    @Override
    protected void onComponentTag(ComponentTag tag) {
        tag.put("maxlength", "45");
        tag.put("size", "55");
        super.onComponentTag(tag);
    }


}

Since both first name and last name must enforce the same requirements on the user it makes sense to encapsulate the logic in one place. In the above code we set the component’s required flag to true and we override the onComponentTag method to output the ‘maxlength’ and ‘size’ attributes for the input tag.

This is a prime example of applying the ‘Don’t Repeat Yourself’ (DRY) principle in action and Wicket, to its credit, makes this an incredibly easy process.

Now a word or two on structuring your code.

Project Structure

One of the things I really hate is dealing with a project which just dumps everything into a single package whose name provides absolutely no insight as to the purpose of the code contained in it. Bad! Bad! Bad!

In GuestBook, package names provide useful insight as to the purpose of the code they contain. The packages also serve to layer the project’s structure by areas of concern, namely entities, session beans and Wicket which it further sub groups into components and data providers.

Some Final Thoughts

Well that just about wraps things up for this series but before we say goodbye I’d like to extend my thanks to all the developers and contributors who have made Java, Wicket and its infrastructure of contributed libraries and NetBeans the productive resources they are for us.

I hope you have enjoyed reading this series and following along with me as much as I have enjoyed sharing my time with you.

Please feel free to leave your comments for any of the articles in this series and I will try to find the time to respond to them all.

May all your days coding be happy and productive ones.

Wednesday, March 30, 2011

Java EE6 & Wicket - Article #5–Building Out The Guest Book Web Application Using NetBeans

Welcome to the 5th in a series of detailed articles on Java EE6 & Wicket. If you haven’t already, please read the following previous articles before continuing.
  1. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html
  2. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html
  3. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html
  4. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html
  5. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-4-adding-jpa.html

In this, the 5th article in this series, we will complete the implementation of the GuestBook Web application. So lets get started.

Modifying The Generated Markup And Code

If you haven’t already, fire up NetBeans because we are going to make a few changes to the generated code so that our GuestBook’s home page will look like the image in article #1. In order to do that we will compose the HomePage using Wicket Markup Inheritance.

Our HomePage displays a Wicket logo which you can download here. Place the logo  in the com.myapp.wicket package.

Next, we need to make a few changes to the generated code. Create a new HTML file in the com.myapp.wicket package and name it BasePage.

  1. Right click on the com.myapp.wicket package, select New | Other to open the New File window
  2. Select Web in the Categories panel and then select HTML in the File Types panel and click the Next button.2011-03-30 08h45_57
  3. Enter BasePage for the HTML File Name and click the Finish button. NetBeans will generate the BasePage.html file and open it in the editor.

Replace the generated markup with the following markup and save the file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
<meta name="description" content="A guest list of the rich and famous written in Java and Wicket">
</head>
<body>
<div wicket:id="headerpanel"></div>
<wicket:child/>
</body>
</html>

Replace all the code in com.myapp.wicket.BasePage.java with the following code and save the file:

package com.myapp.wicket;           

import org.apache.wicket.markup.html.WebPage;

/**
*
* @author Jeff
* @version
*/

public class BasePage extends WebPage {

/**
* Construct.
* @param model
*/
public BasePage() {
super();
add(new HeaderPanel("headerpanel"));
}
}

Replace the HTML markup in com.myapp.wicket.HeaderPanel.htm with the following markup and save the file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:wicket="http://wicket.apache.org">
<head><title></title></head>
<body>
<wicket:panel>
<wicket:link>
<img src="Apache_Wicket_logo.png" style="float:left;"/>
</wicket:link>
<h1 style="margin-left: 180px; color: #E9601A; font-style: italic; font-size: 1.5em; font-family: sans-serif; font-weight: bold; line-height: 59px; white-space: nowrap">
<span wicket:id="headerpanneltext">Java EE6 And Wicket EJB Tutorial</span>
</h1>
<hr style="color: #E9601A; background-color: #E9601A; height: 1px;"/>
</wicket:panel>
</body>
</html>

Replace the Java code in com.myapp.wicket.HeaderPanel.java with the following code and save the file:

package com.myapp.wicket;           

import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;

/**
*
* @author Jeff
* @version
*/

public class HeaderPanel extends Panel {

public HeaderPanel(String id)
{
super(id);
add(new Label("headerpanneltext", "Java EE6 And Wicket EJB Tutorial"));
}

}

Replace all the HTML markup in com.myapp.wicket.HomePage.html with the following markup and save the file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
<wicket:head>
<title>Guests</title>
<wicket:link>
<link rel="stylesheet" type="text/css" href="style.css"/>
</wicket:link>
</wicket:head>
</head>
<body>
<wicket:extend>
<div>
<div style="margin-top: 20px; padding-left: 15px;">
<h2 style="color:#333333; white-space: nowrap;">Please Sign Our Guest List</h2>
<div wicket:id="feedback"></div>
<form wicket:id="guestform">
<label>First Name:
<span wicket:id="firstNameBorder">
<input wicket:id="firstName" type="text"/>
</span>
</label>
<br/>
<label>Last Name:
<span wicket:id="lastNameBorder">
<input wicket:id="lastName" type="text"/>
</span>
</label>
<br/>
<input type="submit"/><input type="reset"/>
</form>
</div>
<hr style="background-color: #E9601A; color: #E9601A; height: 1px; margin-top: 20px;"/>
<div style="margin-top: 20px; padding-left: 15px;">
<h2 style="color:#333333; white-space: nowrap;">Visitors Who Have Signed Our Guest List</h2>
<div wicket:id="namelist" style="white-space: nowrap;">
<span wicket:id="name" style="font-size: 1.2em; color: #333333;">name</span>
</div>
</div>
</div>
</wicket:extend>
</body>
</html>

Replace all the Java code in com.myapp.wicket.HomePage.java with the following code and save the file:

package com.myapp.wicket;

import com.myapp.wicket.components.NameTextField;
import com.myapp.wicket.dataproviders.GuestDataProvider;
import com.myapp.entities.Guest;
import com.myapp.sessionbeans.AbstractFacade;
import com.myapp.sessionbeans.GuestFacade;
import javax.ejb.EJB;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.validation.FormComponentFeedbackBorder;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.LoadableDetachableModel;

public class HomePage extends BasePage {

@EJB(name = "GuestFacade")
private GuestFacade guestFacade;

public HomePage() {
super();

add(new FeedbackPanel("feedback"));

/*
* A loadable and detachable model whose sole purpose is to always
* return a new Guest object when its load method is called.
*/
LoadableDetachableModel<Guest> newGuestLoadableDetachableModel = new LoadableDetachableModel<Guest>() {

@Override
protected Guest load() {
return new Guest();
}
};

/*
* The guestForm uses a nested model. The outer model is a compound property
* model and the inner model is a light weight loadable and detachable model.
*/
Form<Guest> guestForm = new Form<Guest>("guestform", new CompoundPropertyModel<Guest>(newGuestLoadableDetachableModel)) {

@Override
protected void onSubmit() {
Guest guest = getModelObject();
guestFacade.create(guest);
setModelObject(new Guest());
guest = new Guest();
}
};

/*
* Add the custom NameTextField compent for
* first and last name to the form, nesting each
* in a FormComponentFeedbackBorder for displaying
* data entry errors.
*/
guestForm
.add(new FormComponentFeedbackBorder("firstNameBorder")
.add(new NameTextField("firstName")));
guestForm
.add(new FormComponentFeedbackBorder("lastNameBorder")
.add(new NameTextField("lastName")));
add(guestForm);

GuestDataProvider gdp = new GuestDataProvider() {

@Override
public AbstractFacade<Guest> getFacade() {
return guestFacade;
}
};

/*
* When dealing with potentially large lists of data it is
* better to use a DataView whose constructor takes a data
* provider as its second parameter.
*/
DataView<Guest> guestListView = new DataView<Guest>("namelist", gdp) {

@Override
protected void populateItem(Item<Guest> item) {
Guest guest = item.getModelObject();
item.add(new Label("name", guest.toString()));
}

};

add(guestListView);

}
}

Replace the content of com.myapp.wicket.style.css with the following content and save the file:

body {
white-space: nowrap;
}

.feedbackPanelERROR {
color: red !important;
list-style: circle;
font-weight: bold;
}

.feedbackPanelINFO {
color: green;
list-style: circle;
font-weight: bold;
}

We need to create a properties file in which we will declare the warning messages that Wicket will use when validating the input form on the HomePage.

  1. Right click on the com.myapp.wicket package in the Projects panel and select New | Other to open the New File Window.
  2. Select Other from Categories and select Properties File from File Types and click the Next button.
  3. Enter HomePage for the File Name and click the Finish button. NetBeans will open the properties file in the eiditor.

Add the following content to the the com.myapp.wicket.HomePage.properties file and save the file:

firstName.Required=First Name Is Required. 
    
lastName.Required=Last Name Is Required.

Next, we will add a custom TextField component to the project.

  1. Right click on Source Packages in the Projects panel and select New | Other to open the New File window.
  2. Select Java from Categories and Java Class from File Types and click the Next button.
  3. Enter NameTextField for the Class Name and enter com.myapp.wicket.components for the Package name and click the Finish button. NetBeans will open the NameTextField.java file in the editor.

Replace all the Java code in the NameTextField.java file with the following and save the file:

package com.myapp.wicket.components;

import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.IModel;

/**
* A domain specific extension of a Wicket TextField
* that sets the required flag and adds the maxlength=45
* and size=55 attributes to be rendered.
*
* Demonstrates how you can easily extend Wicket
* components to provide domain specific requirement.
*
* @author Jeff
*/
public class NameTextField extends TextField<String>{

/**
*
* @param id
* @param model
*/
public NameTextField(String id, IModel<String> model) {
super(id,model);
setRequired(true);
}

/**
*
* @param id
*/
public NameTextField(String id) {
this(id,null);
}

@Override
protected void onComponentTag(ComponentTag tag) {
tag.put("maxlength", "45");
tag.put("size", "55");
super.onComponentTag(tag);
}


}

Next, we will add an interface to the project.

  1. Right click on Source Packages in the Projects panel and select New | Other to open the New File window.
  2. Select Java from Categories and select Java Interface from File Types and click the Next button.
  3. Enter IEjbDataProvider.java for the Class Name and enter com.myapp.wicket.dataproviders for the Package name and click the Finish button. NetBeans will open the IEjbDataProvider.java file in the editor.

Replace all the Java code in the IEjbDataProvider.java file with the following and save the file:

package com.myapp.wicket.dataproviders;

import com.myapp.sessionbeans.AbstractFacade;
import org.apache.wicket.markup.repeater.data.IDataProvider;

/**
* Extended interface definition of IDataProvider<T> that provides type safe access to session beans.
* Provides the ability to access a session bean in any object.
*
* Use Case: Need to access session in objects other than a Wicket WebPage.
*
* Background - The JavaEEComponentInjector enables Java EE 5 resource injection in Wicket Pages but
* often we need to access to session beans from other objects such as DataProviders and Models. This
* interface supports such a use cases.
*
* Usage
* public class HomePage extends BasePage {
* @EJB(name = "GuestFacade")
* private GuestFacade guestFacade;
* private Guest guest;
*
* public HomePage() {
* super();
* guest = new Guest();
* GuestDataProvider gdp = new GuestDataProvider() {
*
* @Override
* public AbstractFacade<Guest> getFacade() {
* return guestFacade;
* }
* };
*
*
* @param <T>
* @author Jeff
*/
public interface IEjbDataProvider<T> extends IDataProvider<T> {
AbstractFacade<T> getFacade();
}

Next, we will add a Java class to the project.

  1. Right click on com.myapp.wicket.dataproviders in the Projects panel and select New | Other to open the New File window.
  2. Select Java from Categories and select Java Class from File Types and the click the Next button.
  3. Enter GuestDataProvider for Class Name and click the Finish button.

Replace all the Java code in the GuestDataProvider.java file with the following and save the file:

package com.myapp.wicket.dataproviders;

import com.myapp.entities.Guest;
import java.util.Iterator;
import java.util.List;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;

abstract public class GuestDataProvider implements IEjbDataProvider<Guest>{

@Override
public Iterator<? extends Guest> iterator(int first, int count) {
int[] range = {first, count};
List<Guest> guests = getFacade().findRange(range);
return getFacade().findRange(range).iterator();
}

@Override
public IModel<Guest> model(final Guest object) {

final Integer id = object.getId();

LoadableDetachableModel<Guest> ldm = new LoadableDetachableModel<Guest>(object) {
@Override
protected Guest load() {
return getFacade().find(id);
}
};

return ldm;
}

@Override
public int size() {
return getFacade().count();
}

@Override
public void detach() {}

}

The last change we must make is to com.myapp.wicket.Application.java file. Replace all the code in Application.java with the following code and save the file:

package com.myapp.wicket;           

import org.apache.wicket.protocol.http.WebApplication;
import org.wicketstuff.javaee.injection.JavaEEComponentInjector;
/**
*
* @author Jeff
* @version
*/

public class Application extends WebApplication {

public Application() {
}

@Override
protected void init() {
super.init();
addComponentInstantiationListener(new JavaEEComponentInjector(this));
}

@Override
public Class getHomePage() {
return HomePage.class;
}
}

With all these changes in place you should now be able to run the project in your browser.

In the next and last article we will examine the code, focusing on the integration we provided for consuming the EJB in our HomePage. I will also discuss some best practices that I’ve used here, especially pertaining to Wicket components and models. If you don’t know the difference between static and dynamic models or you aren’t familiar with loadable/detachable models you can read my article here to get up to speed on this subject. Stay tuned!

Tuesday, March 29, 2011

Put Your Wicket Applications On A Diet

Wicket, at the end of each request cycle, serializes the active page into a byte array and stores it for the next request. The entire object graph of the page including all components and their associated models are included in the generated byte stream. This could possibly, depending on the size of the graph, place stress on server resources.

So how can we reduce our page footprint and put our applications on a diet? By mastering Wicket models, that’s how. As it turns out, understanding static, dynamic and loadable/detachable models is key if you want to reduce the memory footprint of your Wicket applications.

To begin out discussion of Wicket’s models let’s first look at the IModel interface.

IModel

All Wicket models implement the IModel interface which is defined as follows:

public interface IModel<T> extends IDetachable
{
	/**
	 * Gets the model object.
	 * 
	 * @return The model object
	 */
	T getObject();

	/**
	 * Sets the model object.
	 * 
	 * @param object
	 *            The model object
	 */
	void setObject(final T object);
}

The IModel interface defines 2 methods:

  • getObject is called by Wicket when rendering the component.
  • setObject is called by Wicket when it has to update the component such as after all form components have validated (see Wicket request life cycle and form validation).

IDetachable 

In addition to defining the getObject and setObject methods, IModel also extends the IDetachable interface which is defined as follows:

public interface IDetachable extends IClusterable
{
	/**
	 * Detaches model after use. This is generally used to null out transient references that can be
	 * re-attached later.
	 */
	void detach();
}

The IDetachable interface  defines only 1 method:

  • detach is called by Wicket at the end of a request’s lifecycle.

IModel and IDetachable form the foundation of Wicket’s model API which allows for both static and dynamic model implementations. The 4 primary model implementations that Wicket provides are:

  1. Model – the simplest of all Wicket models. It can be used as both a static and as a dynamic model.
  2. PropertyModel – a dynamic model.
  3. CompoundPropertyModel – a dynamic model that also provides field binding.
  4. LoadableDetachableModel – a dynamic model that detaches the value it wraps at the end of a request’s lifecycle.

Static And Dynamic Models

Here’s an example of using Model as a static model:

Person person = Person.getPerson();

add(new Label("firstName", new Model<String>(person.getFirstName())));

add(new Label("lastName", new Model<String>(person.getLastName())));

 

And here’s an example of using Model as a dynamic model:

Person person = Person.getPerson();

add(new Label("firstName", new Model<String>(){

@Override 
public String getObject() { 
return Person.getPerson().getFirstName(); 
} 

}));

add(new Label("lastName", new Model<String>(){

@Override 
public String getObject() { 
return Person.getPerson().getLastName(); 
}

}));

In the above code for both static and dynamic models we are adding 2 Label components to the page. The Label component constructor takes as a second parameter a reference to a Model object.

In our static example above notice how each of the models directly wraps its value. Each of the models holds a reference to a String and in Java strings are immutable; even if the Person object’s firstName and lastName field values change and if the page were refreshed the values displayed in the two label components will always show the values they were created with. This is the reason these types of models are called static.

In our dynamic example above notice how instead of using Wicket’s basic Model class we subclass Model and override its getObject method (see IModel) to return the appropriate value. Whenever Wicket needs to render the above components it will call its model’s getObject methods to obtain the values to be rendered; now, if the Person object’s firstName and lastName field values change and if the page were refreshed the values displayed in the two label components will reflect those changes. This is the reason these types of models are called dynamic.

So let me reiterate here by giving you a concise definition of static and dynamic models:

  • A static model is any model that directly wraps a value.
  • A dynamic model is any model that does not directly wrap a value but instead overrides the getObject method to retrieve the value when Wicket renders the component.

In the above and for the remainder of this article I use the word ‘value’ to denote either a primitive or a reference value.

Some Models Are Heavier Than Others

What makes Wicket a stateful framework is the serialization of its components at the end of each request’s life cycle. However, this doesn’t come without a price which is the amount of memory that can be consumed by serializing the values that component models wrap. While a page with 2 Labels might seem trivial, scale that out to thousands or tens of thousands of users concurrently hitting this page and it isn’t so trivial anymore.

So how can we manage the memory footprint of our pages to significantly reduce the load that our models have on memory? The answer is by using LoadableDetachableModels. At the beginning of this article I introduced the IDetachable interface and this little nugget is the key to Wicket’s LoadableDetachableModel.

Lets consider a slightly more involved use case that involves a form that uses a CompoundPropertyModel:

Form<Person> form = new Form<Person>("form", new CompoundPropertyModel<Person>(Person.getPerson()));

form.add(new TextField<String>("firstName"));

form.add(new TextField<String>("lastName"));

add(form);

In this example we are creating a form with a CompoundPropertyModel of type Person. When this page is serialized the Person instance that the CompoundPropertyModel wraps will be serialized. That is, unless we take steps to prevent it from serializing Person.

This use case thus presents us with a unique challenge; how can we use a CompoundPropertyModel without incurring the load on memory caused by serializing the Person instance? The answer lies in Wicket’s LoadableDetachableModel and Wicket’s ability to use nested models.

LoadableDetachableModel Take The Weight Off

LoadableDetachableModel is a model that loads and detaches the value it wraps by storing the reference to the value in a temporary, transient reference which it sets when its getObject method is called by calling the abstract method ‘load’ and which it sets to null when the method ‘detach’ is called.

LoadableDetachableModel ldm = new LoadableDetachableModel<Person>() {

    @Override 
    protected Person load() { 
        return Person.getPerson(); 
    }

};

As you can see from the above example we override the load method to return an instance of Person. In a real application we could query a database.

Using  LoadableDetachableModel allows us to attach a reference to Person on each request and detach it at the end of the request cycle thereby eliminating the need to serialize the Person object.

[*** In addition, another added benefit you get from using a detachable model is when you are dealing with objects that for one reason or another can’t be serialized. In those cases you can just wrap them in a detachable model thereby eliminating the need to serialize them. ***]

Now we know we can use LoadableDetachableModel when we want to dynamically load and discard the values wrapped by our models. But how can we use them and still take advantage of the binding features that the CompoundPropertyModel provides? Nesting models is the answer.

Nesting Models

Form<Person> form = new Form<Person>("form", new CompoundPropertyModel<Person>(ldm));

form.add(new TextField<String>("firstName"));

form.add(new TextField<String>("lastName"));

add(form);

Notice in the above example that we are passing our LoadableDetachableModel instance, ldm, as a parameter to the CompoundPropertyModel’s constructor. By nesting a LoadableDetachableModel in a CompoundPropertyModel we get the benefit of both models. That’s like having your cake and eating it, too!

In my opinion nested models are one of the coolest features that Wicket provides - they reduce the load on memory that Wicket’s stateful nature would have had we not been able to eliminate serializing the values wrapped by its models.

So, the next time someone tells you that scaling out a Wicket application is difficult because it serializes its pages just don’t believe it; Wicket makes it incredibly easy by using nested models.

Well that concludes my little discussion of Wicket models and I hope you have enjoyed it. Remember, having a solid understanding of models is a must if you seriously want to be a master Wicket programmer.

Java EE6 & Wicket - Article #4 - Adding JPA Persistence And EJB Support

Welcome to the 4th in a series of detailed articles on Java EE6 & Wicket. If you haven’t already, please read the following previous articles before continuing.

  1. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html
  2. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html
  3. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html
  4. http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html

Data Access

The GuestBook Web application we are building must access the data from the guest table in the guestbook database which we created together in the 2nd article. The goal of this article is to provide access to the database using JPA and Enterprise Java Bean (EJB).

NetBeans built in tooling supports creating Entity beans from an existing database table. We will use this feature to generate an Entity bean from the guest table.

NetBenas built in tooling also supports creating an EJB. We will use this feature to create a stateless session bean with JPA access functionality which is commonly referred to as a facade and in the next article we will inject an instance of this facade into our Wicket pages that will allow them to access the guestbook database.

One of the new features of EE6 EJB is, unlike EE5, it doesn’t require we implement interfaces when access is local (meaning from the same container).

First, we will generate our Entity bean from the guest table and then we will create the EJB to provide access to the database. So lets get started.

Create A New Entity Class From A Database Table

In the Projects panel right click on the Source Packages item and select New | Other which will open the New File window. In the Categories list select Persistence and in File Type select Entity Classes from Database and then click the Next button.

  1. Expand the Data Source dropdown and select New Data Source to open the Create Data Source window. Enter guestbook for the JNDI Name and from the Database Connection dropdown list select the database connection which we created in the previous article and click OK.

    2011-03-29 08h24_36

  2. If prompted for the password enter the password you created when you installed MySQL and click OK.

  3. From the list of Available Tables select the guest table and then click the Add button to add it to the Selected Table list and click the Next button.

    2011-03-29 08h29_15

  4. Enter com.myapp.entities for the Package name and click the Next button.

    2011-03-29 09h46_00

  5. Select java.util.List for the Collection Type and then click the Finish button.

The result of the above steps is NetBeans created Guest.java POJO with JPA annotations and placed it in the com.myapp.entities package. NetBeans also created the JPA configuration file persistence.xml. If you fully expand the project node in the Projects panel you will see the following:

2011-03-29 09h48_16

If you open the Guest.java file you will see that it contains standard JPA annotations, getters and setters and numerous named queries. While you have the file open we will apply a change to its ‘toString’ method which we will use when be  build at the application:

  • If it isn’t already, open Guest.java and replace the ‘toString’ method (it is located at the bottom of the file) with the following:
    • @Override
      public String toString() {
          return firstName + " " + lastName;
      }

We will make use of this method i

Create The EJB

  1. In the Projects panel right click on Source Packages and select New | Other to open the New File window.

  2. From Categories select Persistence and from File Types select Session Beans For Entity Classes and click the Next button.

  3. Select com.myapp.entities.Guest from Available Entity Classes and click the Add button to add it to the list of Selected Entity Classes and then click the Next button.

  4. Enter com.myapp.sessionbeans for the Package and click the Finish button. Notice how we didn’t create any interfaces in this last step.

    2011-03-29 09h54_26

The result of the above steps is NetBeans created 2 classes in the com.myapp.sessionbeans package, AbstractFacade.java and  GuestFacade.java.

2011-03-29 10h41_36

  • AbstractFacade.java is an abstract class that implements generalized functionality.
  • GuestFacade.java, a subclass of AbstractFacade.java, provides Guest.java type specific behavior and is annotated with @Stateless marking it as a stateless session bean.

One more thing to do and then we are done. Fully expand Server Resources in the Projects panel and open the sun-resources.xml file. If you set up your MySQL installation to require a password then make sure the Password’s property tag in this file has your correct password. If it doesn’t add your password and save the file. I’ve modified mine as follows:

<property name="Password" value="admin"/>

In the next article we will build out the Wicket parts of GuestBook and use the features provided by the JavaEE Inject Library which we added to our project in the 3rd article to inject the GuestFacade.java session bean into our Wicket pages. Stay tuned!

Monday, March 28, 2011

Java EE6 & Wicket - Article #3 – Generating The Guest Book Web Application Using NetBeans And Deploying It To GlassFish

Welcome to the 3rd in a series of detailed articles on Java EE6 & Wicket. If you haven’t already, please read the following previous articles before continuing.

  1. Java EE6 & Wicket
  2. Java EE6 & Wicket - Article #1 - Requirements, Architecture & Resources
  3. Java EE6 & Wicket - Article #2 – Creating A Backing Datastore And Schema Using MySQL

In this, my 3rd article in this series, we will discuss and demonstrate the generation of the initial GuestBook Web application using the popular NetBeans IDE and the Wicket plugin so please, if you haven’t already, install these two on your development machine before continuing with the rest of this article.

Simple Deployment With Java EE6 And The EJB 3.1 Specification

EE5 frequently required the use of an Enterprise Application Archive for deploying EE Web application. This usually meant having to use multiple projects to deploy even the simplest of EE applications. One of the new features of EE6, sometimes called EAR-less applications,  addresses this issue and makes deploying EE6 applications much simpler. Rather than going into the details here, you can read the article Java EE6: EJB3.1 Is a Compelling Evolution, which provides an excellent review of this new feature as well as EE6 in general. The GuestBook Web application that we are now going to create will use this new feature.

OK, lets get started.

Generating The GuestBook Web Application

If you haven’t already, fire up NetBeans.

  1. From the main menu select File | New Project which will open the New Project window.

  2. Select Java Web in the Categories panel and Web Application from the Projects panel and click the Next button.

  3. Enter GuestBook for the project name and click the Next button.

    2011-03-28 08h40_21
  4. If they aren’t already, select GlassFish Server 3 as the server and Java EE 6 Web as the Java EE version and then click the Next button.

    2011-03-28 08h46_44
  5. The Wicket plugin added Wicket to the list of frameworks that you can use in Web applications. In the Frameworks panel select Wicket as the framework to use in our application and then click the Finish button.

    2011-03-28 08h55_28

When we clicked the Finish button NetBeans generated our GuestBook application for us and displays it in the Project panel. If you fully expand the GuestBook node in the Projects panel you will see the following:

2011-03-28 09h54_44

Notice the Wicket jars that are listed under the Libraries node in the above image. These jars were contributed by the Wicket plugin when the project was generated. The plugin also contributed a number of files in our com.myapp.wicket package. In essence, the Wicket plugin generated a basic Wicket application for us that we can run right out of the box, so lets do that now.

Run the application by clicking on the Run Main Project icon located on the main tool bar. Your browser should open, if it isn’t already, and a new page will open and display the application’s output as in the following image:

2011-03-28 10h03_15

That’s pretty cool considering the minimal effort that was required on our part to get this application up and running at this point.

If you look at the NetBeans Output window you should see a GlassFish Server 3 tab. If you click on this tab you should see that our application has been deployed onto the GlassFish server for us. Also, you should see the following output from Wicket telling us that it is running in development mode.:

2011-03-28 10h26_31

Lets ignore the application that the Wicket plugin generated for us for the time being because we now want to turn our attention to adding EJB support to the project. First, though, a little background.

Wicket’s Single Purpose

Wicket has been designed to solve only one specific problem which is to enable component-oriented, programmatic manipulation of markup. In fact, its creators say as much and you can read their own words in their Wicket’s Vision statement here.

As such, Wicket doesn’t provide out-of-the-box support for EJB. Wicket does have, though, many libraries that have been contributed to the project and which provide a lot of the extras that we often need. One of these libraries is the JavaEE Inject Library and it provides the ability to use the @EJB, @PersistenceUnit and @Resource annotations in our Wicket applications. I suggest that you go to the web site hosting the library and read up on the details before continuing with the remainder of this article because it is important to understand not only what the library does for us but how it does it.

Adding The JavaEE Inject Library To Our Project

To keep things simple, I’ve created a compressed file named guestbooktutorialadditionaljars.zip which contains all the jars required by the JavaEE Inject Library and I posted it here. Download the file onto a folder on your machine and extract its content. Then follow these steps to add the jar files to the project:

  1. In the Projects panel right click on the Libraries node and select Add Jar/Folder to open the Add Jar/Folder window.
  2. Navigate to the folder on your machine where you extracted the contents of the guestbooktutorialadditionaljars.zip to and select all 3 jar files (important - do not select the zip file itself if it happens to also resides in the same folder, only select the 3 jar files) as pictured below. 2011-03-28 11h20_27
  3. Now click the Open button to close the window and add the 3 jar files to the project.

The result of the above is that NetBeans has added the 3 jar files we selected to our project’s classpath which we can see by looking at the files listed under the Libraries entry in the Projects panel.

2011-03-28 11h31_13

We’ve now included all the jars that our project requires and in the next article we’ll discuss and demonstrate adding JPA persistence support to the project. Stay tuned!

About Me

My photo
New York, NY, United States
Software Developer