<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2570247679477683751</id><updated>2012-01-07T12:53:54.889-05:00</updated><category term='google-app-engine'/><category term='Introduction'/><category term='compoundpropertymodel'/><category term='GWT'/><category term='jdbc'/><category term='javascript'/><category term='derby'/><category term='web'/><category term='glassfish'/><category term='maven'/><category term='gorm'/><category term='http'/><category term='UIComposerTestApp'/><category term='application'/><category term='jar'/><category term='library'/><category term='Wielenga'/><category term='ee5'/><category term='custom web control'/><category term='grails'/><category term='job'/><category term='project_kenai'/><category term='bigtable'/><category term='stateful'/><category term='ejb'/><category term='wicket'/><category term='dataview'/><category term='sun'/><category term='stateless'/><category term='loadabledetachablemodel'/><category term='eclipse'/><category term='idataprovider'/><category term='markup'/><category term='netbeans wicket plugin'/><category term='debug'/><category term='hibernate'/><category term='java'/><category term='mysql'/><category term='php'/><category term='ajax'/><category term='di'/><category term='lmv'/><category term='heart'/><category term='oracle'/><category term='Geertjan'/><category term='netbeans'/><category term='app-engine'/><category term='UIComposer'/><category term='appengine'/><category term='jpa'/><category term='groovy'/><category term='html'/><category term='javaee'/><category term='session'/><category term='big-table'/><category term='kenai'/><category term='gorm-jpa'/><category term='EE6'/><category term='cat'/><category term='request'/><category term='Intype'/><category term='subversion'/><category term='google'/><title type='text'>Jeff's Blog</title><subtitle type='html'>Developing Great Software</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>32</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-1564488592297283970</id><published>2011-08-14T10:58:00.000-04:00</published><updated>2011-08-14T10:58:43.622-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><title type='text'>Apache Wicket Interfaces &amp; Methods To Master – An Introduction</title><content type='html'>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).&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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&amp;nbsp;unfortunate and unnecessary because all these issues are addressed by&amp;nbsp;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.&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
I’ll be using NetbBeans 7&amp;nbsp;throughout the articles&amp;nbsp;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.&amp;nbsp;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 &lt;a href="http://netbeans.org/"&gt;http://netbeans.org/&lt;/a&gt;. 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 &lt;a href="http://jeff-schwartz.blogspot.com/2011/04/netbeans-7-wicket-plugin.html"&gt;http://jeff-schwartz.blogspot.com/2011/04/netbeans-7-wicket-plugin.html&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;UPDATED 8/14/2011&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;This and all future related articles on Wicket will now appear at my new blog site&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;a href="http://thewicketevangelist.blogspot.com/"&gt;The Wicket Evangelist&lt;/a&gt;.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-1564488592297283970?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/1564488592297283970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/05/apache-wicket-interfaces-to-master.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/1564488592297283970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/1564488592297283970'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/05/apache-wicket-interfaces-to-master.html' title='Apache Wicket Interfaces &amp;amp; Methods To Master – An Introduction'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-2243372530097129691</id><published>2011-05-07T08:23:00.001-04:00</published><updated>2011-05-07T08:23:18.546-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='glassfish'/><title type='text'>Bugs In NetBeans 7.0 GlassFish 3.1 Integration</title><content type='html'>&lt;p&gt;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:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_XzLrgIoZ_TU/TcU5sXD0ooI/AAAAAAAAAf4/f3tgUCu5w4I/s1600-h/2011-05-07%2008h04_54%5B3%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="2011-05-07 08h04_54" border="0" alt="2011-05-07 08h04_54" src="http://lh5.ggpht.com/_XzLrgIoZ_TU/TcU5tSVWPoI/AAAAAAAAAf8/JDYAxe74LLE/2011-05-07%2008h04_54_thumb%5B1%5D.png?imgmax=800" width="695" height="188" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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 &amp;amp; refresh cycle that I’ve come to expect.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;Hopefully, these bugs will be quickly addressed in a point release. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-2243372530097129691?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/2243372530097129691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/05/bugs-in-netbeans-70-glassfish-31.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2243372530097129691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2243372530097129691'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/05/bugs-in-netbeans-70-glassfish-31.html' title='Bugs In NetBeans 7.0 GlassFish 3.1 Integration'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_XzLrgIoZ_TU/TcU5tSVWPoI/AAAAAAAAAf8/JDYAxe74LLE/s72-c/2011-05-07%2008h04_54_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-5368897062587525565</id><published>2011-04-28T22:22:00.001-04:00</published><updated>2011-04-28T22:39:49.434-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='markup'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans wicket plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='Geertjan'/><title type='text'>The NetBeans 7 Wicket Plugin</title><content type='html'>&lt;p&gt;Geertjan Wielenga has released an updated version of the Wicket Plugin for NetBeans 7.&amp;#160; 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.&lt;/p&gt;  &lt;p&gt;If you haven’t done so already I urge you to &lt;a href="http://plugins.netbeans.org/plugin/3586/wicket-1-4-support" target="_blank"&gt;download this plugin&lt;/a&gt; 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:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Installing The Wicket Plugin&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;1. Go to &lt;a href="http://plugins.netbeans.org/plugin/3586/wicket-1-4-support"&gt;http://plugins.netbeans.org/plugin/3586/wicket-1-4-support&lt;/a&gt; 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.&lt;/p&gt;  &lt;p&gt;2. Start up NetBeans if it isn’t already and select Tools | Plugins from the main menu. This will open the Plugin window.&lt;/p&gt;  &lt;p&gt;3. Select the Downloaded tab and then select the Add Plugins button.&lt;/p&gt;  &lt;p&gt;4. Navigate to the folder where you the extracted files reside, select all 3 files and then select the Open button.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_XzLrgIoZ_TU/Tbog2PoeH1I/AAAAAAAAAfY/HSwQjwKWcf0/s1600-h/2011-04-28%2019h44_53%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-04-28 19h44_53" border="0" alt="2011-04-28 19h44_53" src="http://lh5.ggpht.com/_XzLrgIoZ_TU/Tbog2zXj73I/AAAAAAAAAfc/_eBc5gdNHJc/2011-04-28%2019h44_53_thumb%5B1%5D.png?imgmax=800" width="726" height="444" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;5. Select the Install button and NetBeans will install the plugin modules after which you will be prompted to restart NetBeans. Please, restart NetBeans.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Create A Wicket Project&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Lets explore some of the productivity enhancing features that the Wicket plugin provides. We’ll start first by creating a new Wicket project.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;2. Enter any name you like for the Project Name and select Next.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_XzLrgIoZ_TU/Tbog300G9zI/AAAAAAAAAfg/_l20kz30X8U/s1600-h/2011-04-28%2020h01_37%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-04-28 20h01_37" border="0" alt="2011-04-28 20h01_37" src="http://lh3.ggpht.com/_XzLrgIoZ_TU/Tbog4s3iWAI/AAAAAAAAAfk/RTESBTwLCgY/2011-04-28%2020h01_37_thumb%5B1%5D.png?imgmax=800" width="815" height="520" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;5. Select Wicket and then select Finish. NetBeans will now generate a starter Wicket application.&lt;/p&gt;  &lt;p&gt;Fully expand the newly created project in the Projects panel.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_XzLrgIoZ_TU/Tbog46KAbGI/AAAAAAAAAfo/eLfO9L5yYMA/s1600-h/2011-04-28%2020h13_02%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-04-28 20h13_02" border="0" alt="2011-04-28 20h13_02" src="http://lh6.ggpht.com/_XzLrgIoZ_TU/Tbog5gXZ5TI/AAAAAAAAAfs/DsUj2dCmfsw/2011-04-28%2020h13_02_thumb%5B1%5D.png?imgmax=800" width="329" height="547" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Run The New Wicket Application&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_XzLrgIoZ_TU/Tbog57aJAaI/AAAAAAAAAfw/e6LV4UpsF64/s1600-h/2011-04-28%2020h21_38%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-04-28 20h21_38" border="0" alt="2011-04-28 20h21_38" src="http://lh6.ggpht.com/_XzLrgIoZ_TU/Tbog6fYi6AI/AAAAAAAAAf0/EEvxEvMIX5E/2011-04-28%2020h21_38_thumb%5B1%5D.png?imgmax=800" width="612" height="230" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Starter Project&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Lets explore the components that the plugin generated for us.&lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;Now, lets look at BasePage’s markup and java implementation.&lt;/p&gt;  &lt;pre&gt;&amp;lt;!DOCTYPE html&amp;gt; 
&amp;lt;html xmlns:wicket=&amp;quot;http://wicket.apache.org&amp;quot;&amp;gt; 
    &amp;lt;head&amp;gt; 
        &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt; 
        &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;Put your description here!&amp;quot; /&amp;gt; 
    &amp;lt;wicket:head&amp;gt; 
        &amp;lt;wicket:link&amp;gt; 
            &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;style.css&amp;quot;/&amp;gt; 
        &amp;lt;/wicket:link&amp;gt; 
    &amp;lt;/wicket:head&amp;gt; 
&amp;lt;/head&amp;gt; 
&amp;lt;body&amp;gt; 
    &amp;lt;header wicket:id=&amp;quot;headerpanel&amp;quot; /&amp;gt;
    &amp;lt;section class=&amp;quot;content_container&amp;quot;&amp;gt; 
        &amp;lt;wicket:child/&amp;gt; 
    &amp;lt;/section&amp;gt; 
    &amp;lt;footer wicket:id=&amp;quot;footerpanel&amp;quot; /&amp;gt; 
&amp;lt;/body&amp;gt; 
&amp;lt;/html&amp;gt;&lt;/pre&gt;

&lt;pre&gt;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(&amp;quot;headerpanel&amp;quot;, &amp;quot;Welcome To Wicket&amp;quot;)); 
        add(new FooterPanel(&amp;quot;footerpanel&amp;quot;, &amp;quot;Powered by Wicket and the NetBeans Wicket Plugin&amp;quot;));
    } 

}&lt;/pre&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Now, lets look at HomePage’s markup and java implementation.&lt;/p&gt;

&lt;pre&gt;&amp;lt;!DOCTYPE html&amp;gt; 
&amp;lt;html xmlns:wicket=&amp;quot;http://wicket.apache.org&amp;quot;&amp;gt; 
    &amp;lt;head&amp;gt; 
        &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt; 
    &amp;lt;wicket:head&amp;gt; 
        &amp;lt;title&amp;gt;Wicket Example&amp;lt;/title&amp;gt; 
    &amp;lt;/wicket:head&amp;gt; 
&amp;lt;/head&amp;gt; 
&amp;lt;body&amp;gt; 
    &amp;lt;wicket:extend&amp;gt; 
       &amp;lt;h1 wicket:id=&amp;quot;message&amp;quot;&amp;gt;This gets replaced&amp;lt;/h1&amp;gt;
    &amp;lt;/wicket:extend&amp;gt; 
&amp;lt;/body&amp;gt; 
&amp;lt;/html&amp;gt;&lt;/pre&gt;

&lt;pre&gt;package com.myapp.wicket;           

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

public class HomePage extends BasePage {

    public HomePage() {
        add(new Label(&amp;quot;message&amp;quot;, &amp;quot;Hello, World!&amp;quot;));
    }

}&lt;/pre&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Now lets explore some of the other productivity enhancements that the Wicket plugin provides.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating A New Page And &lt;strong&gt;A New Panel&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exploring Components With Navigator&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Your will really appreciate Navigator’s Wicket Sense when you are dealing with large Java and markup files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jump To Implementation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Much Thanks And Appreciation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Geertjan, great job and thank you!&lt;/p&gt;

&lt;p&gt;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!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-5368897062587525565?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/5368897062587525565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/04/netbeans-7-wicket-plugin.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/5368897062587525565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/5368897062587525565'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/04/netbeans-7-wicket-plugin.html' title='The NetBeans 7 Wicket Plugin'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_XzLrgIoZ_TU/Tbog2zXj73I/AAAAAAAAAfc/_eBc5gdNHJc/s72-c/2011-04-28%2019h44_53_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-2276993196333156898</id><published>2011-04-28T12:02:00.001-04:00</published><updated>2011-04-28T13:25:02.679-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stateless'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='javaee'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='EE6'/><title type='text'>Wicket, Web Services, NetBeans And GlassFish</title><content type='html'>&lt;p&gt;A reader recently emailed me and wanted to know about implementing a Wicket application within a Web Service environment.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“&lt;em&gt;I have not come across any reference where Wicket has been implemented        &lt;br /&gt;within a web service environment. None of the books I have read on         &lt;br /&gt;Wicket have addressed this area to my knowledge. I am wondering if you         &lt;br /&gt;have any insight as to how this would work.&lt;/em&gt;”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“How you expose your web services has nothing to do with Wicket meaning you don't integrate your web services with wicket.”&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Additionally, I went on to say:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;“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.”&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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).&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;NetBeans, GlassFish v3.1 and JAX-WS&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;2. Package in Web container – this option should be used if your Web Service doesn’t require access to other EE containers. &lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Create A Web Service Project&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;1. If you haven’t already, fire up NetBeans and select File | New Project which will open the New Project window. &lt;/p&gt;  &lt;p&gt;2. Select Java EE from the Categories panel and select EJB Module from the Projects panel and select Next. &lt;/p&gt;  &lt;p&gt;3. Enter any valid project name you like in the Project Name text box. I am naming mine ‘EJBWebServicesAndWicketTutorial’. Select Next. &lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Create A Web Service&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;pre&gt;package WebServices;

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

/**
 *
 * @author Jeff
 */
@WebService(serviceName = &amp;quot;CalculatorWebService&amp;quot;)
@Stateless()
public class CalculatorWebService {

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

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing The CalculatorWebService add Method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;NetBeans tooling makes testing Web Services a snap so lets do that now to insure that our add service works as expected:&lt;/p&gt;

&lt;p&gt;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&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_XzLrgIoZ_TU/TbmPfq1CDyI/AAAAAAAAAe4/wGqVMBD1Kno/s1600-h/2011-04-28%2010h23_51%5B6%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-04-28 10h23_51" border="0" alt="2011-04-28 10h23_51" src="http://lh3.ggpht.com/_XzLrgIoZ_TU/TbmPf5fy6iI/AAAAAAAAAe8/TOmUVkCRkZw/2011-04-28%2010h23_51_thumb%5B4%5D.png?imgmax=800" width="748" height="339" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_XzLrgIoZ_TU/TbmPgB7uo8I/AAAAAAAAAfA/ukmsPTaA4dc/s1600-h/2011-04-28%2010h30_27%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-04-28 10h30_27" border="0" alt="2011-04-28 10h30_27" src="http://lh3.ggpht.com/_XzLrgIoZ_TU/TbmPgVI4PmI/AAAAAAAAAfE/jAjtZvHWyi4/2011-04-28%2010h30_27_thumb%5B1%5D.png?imgmax=800" width="748" height="342" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a Wicket Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;2. For Server select GlassFish Server 3.1 and for Java EE Version select Java EE 6 Web and select Next.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Now that we have a Wicket application we will use NetBeans to easily configure it to consume the Web Service we created previously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consuming Our Web Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;2. Select WSDL URL and enter the URL that you saved previously when you tested the Web Service.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Now lets actually use the Web Service in our Wicket application.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;2. Replace all the content in HomePage.html with the following:&lt;/p&gt;

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

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;Now, lets consume the add Web Service method.&lt;/p&gt;

&lt;p&gt;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 &lt;/p&gt;

&lt;pre&gt;/*
 * 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(&amp;quot;message&amp;quot;, &amp;quot;Enter 2 ints!&amp;quot;));

        Form&amp;lt;HomePage&amp;gt; form = new Form&amp;lt;HomePage&amp;gt;(&amp;quot;form&amp;quot;, new CompoundPropertyModel&amp;lt;HomePage&amp;gt;(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(&amp;quot;feedbackpanel&amp;quot;));
        form.add(new TextField&amp;lt;String&amp;gt;(&amp;quot;input1&amp;quot;));
        form.add(new TextField&amp;lt;String&amp;gt;(&amp;quot;input2&amp;quot;));
        form.add(new Label(&amp;quot;result&amp;quot;));
        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);
    }

}&lt;/pre&gt;

&lt;p&gt;In our java implementation we add the two text&amp;#160; 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&lt;/p&gt;

&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_XzLrgIoZ_TU/TbmPgqNOS9I/AAAAAAAAAfI/pgv35oM4hQQ/s1600-h/2011-04-28%2011h32_22%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-04-28 11h32_22" border="0" alt="2011-04-28 11h32_22" src="http://lh6.ggpht.com/_XzLrgIoZ_TU/TbmPgxjpQ1I/AAAAAAAAAfM/84f4kPxo6K4/2011-04-28%2011h32_22_thumb%5B1%5D.png?imgmax=800" width="748" height="342" /&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;a href="http://lh3.ggpht.com/_XzLrgIoZ_TU/TbmPhJDd1vI/AAAAAAAAAfQ/4p6z2WbUek4/s1600-h/2011-04-28%2011h34_05%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-04-28 11h34_05" border="0" alt="2011-04-28 11h34_05" src="http://lh5.ggpht.com/_XzLrgIoZ_TU/TbmPhRDehxI/AAAAAAAAAfU/UicuJ3uNrYs/2011-04-28%2011h34_05_thumb%5B1%5D.png?imgmax=800" width="748" height="342" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What We’ve Learned&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-2276993196333156898?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/2276993196333156898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/04/wicket-and-web-services.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2276993196333156898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2276993196333156898'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/04/wicket-and-web-services.html' title='Wicket, Web Services, NetBeans And GlassFish'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_XzLrgIoZ_TU/TbmPf5fy6iI/AAAAAAAAAe8/TOmUVkCRkZw/s72-c/2011-04-28%2010h23_51_thumb%5B4%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-522733534425050784</id><published>2011-04-22T16:49:00.001-04:00</published><updated>2011-04-22T16:49:25.837-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><title type='text'>Proposed Changes To The Netbeans Wicket Plugin’s Generated Starter Project</title><content type='html'>&lt;p&gt;Currently, BasePage adds its markup to HomePage’s markup which is a subclass &amp;amp; that isn't a good practice. Just 1 file needs to be added, BasePage.html &amp;amp; it should include markup for the header panel. Then BasePage.java should be modified to add the header panel component to that. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;I recommend that BasePage.html be implemented as follows:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;!DOCTYPE html&amp;gt;   &lt;br /&gt;&amp;lt;html xmlns:wicket=&amp;quot;&lt;a href="http://wicket.apache.org&amp;quot;"&gt;http://wicket.apache.org&amp;quot;&lt;/a&gt;&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;head&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;Put your description here!&amp;quot; /&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;wicket:head&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;wicket:link&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;style.css&amp;quot;/&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/wicket:link&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/wicket:head&amp;gt;    &lt;br /&gt;&amp;lt;/head&amp;gt;    &lt;br /&gt;&amp;lt;body&amp;gt;    &lt;br /&gt;&amp;lt;section class=&amp;quot;container&amp;quot; wicket:id=&amp;quot;headerpanel&amp;quot;&amp;gt;    &lt;br /&gt;&amp;lt;/section&amp;gt;    &lt;br /&gt;&amp;lt;section class=&amp;quot;content_container&amp;quot;&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;wicket:child/&amp;gt;    &lt;br /&gt;&amp;lt;/section&amp;gt;    &lt;br /&gt;&amp;lt;footer&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;span&amp;gt;Put your footer here&amp;lt;/span&amp;gt;    &lt;br /&gt;&amp;lt;/footer&amp;gt;    &lt;br /&gt;&amp;lt;/body&amp;gt;    &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;and that BasePage.java be implemented as:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;import org.apache.wicket.markup.html.WebPage;&lt;/p&gt;  &lt;p&gt;public abstract class BasePage extends WebPage {&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; public BasePage() {   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; super();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; add(new HeaderPanel(&amp;quot;headerpanel&amp;quot;));    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;and that HomePage.html be implemented as:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&amp;lt;!DOCTYPE html&amp;gt;   &lt;br /&gt;&amp;lt;html xmlns:wicket=&amp;quot;&lt;a href="http://wicket.apache.org&amp;quot;"&gt;http://wicket.apache.org&amp;quot;&lt;/a&gt;&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;head&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;wicket:head&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;title&amp;gt;Title goes here!&amp;lt;/title&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/wicket:head&amp;gt;    &lt;br /&gt;&amp;lt;/head&amp;gt;    &lt;br /&gt;&amp;lt;body&amp;gt;    &lt;br /&gt;&amp;lt;wicket:extend&amp;gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;!-- Page specific markup goes here --&amp;gt;    &lt;br /&gt;&amp;lt;/wicket:extend&amp;gt;    &lt;br /&gt;&amp;lt;/body&amp;gt;    &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;and that HomePage.java be implemented as:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;package com.buzzwords.wicket;&lt;/p&gt;  &lt;p&gt;import org.apache.wicket.markup.html.link.Link;&lt;/p&gt;  &lt;p&gt;public class HomePage extends BasePage {   &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public HomePage() {&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160; }   &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;Now BasePage remains blissfully ignorant of HomePage and its markup hierarchy.&lt;/p&gt;  &lt;p&gt;My example is using the new html5 doctype and character encoding specifications as well as some html5 tag candy.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-522733534425050784?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/522733534425050784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/04/proposed-changes-to-netbeans-wicket.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/522733534425050784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/522733534425050784'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/04/proposed-changes-to-netbeans-wicket.html' title='Proposed Changes To The Netbeans Wicket Plugin’s Generated Starter Project'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-2353671307200364144</id><published>2011-03-31T12:10:00.001-04:00</published><updated>2011-03-31T12:22:29.875-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='javaee'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='EE6'/><title type='text'>Java EE6 &amp; Wicket - Article #6 – A Wrap Up</title><content type='html'>&lt;p&gt;Welcome to the 6th in a series of detailed articles on Java EE6 &amp;amp; Wicket. If you haven’t already, please read the following previous articles before continuing.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff"&gt; &lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff"&gt; &lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff"&gt; &lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff"&gt; &lt;/font&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-4-adding-jpa.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-4-adding-jpa.html&lt;/font&gt;&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Consuming EJB In Wicket&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In &lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html" target="_blank"&gt;&lt;font color="#0000ff"&gt;article #3&lt;/font&gt;&lt;/a&gt; we added the &lt;em&gt;&lt;a href="http://wicketstuff.org/confluence/display/STUFFWIKI/JavaEE+Inject" target="_blank"&gt;&lt;font color="#0000ff"&gt;JavaEE Inject&lt;/font&gt;&lt;/a&gt;&lt;/em&gt; jars to the GuestBook project. JavaEE Inject is a Wicket module that provides integration through Java EE 6 resource injection and supports three annotations:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;@EJB &lt;/li&gt;    &lt;li&gt;@PersistenceUnit &lt;/li&gt;    &lt;li&gt;@Resource &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;@Override      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; protected void init() {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; super.init();       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; addComponentInstantiationListener(new JavaEEComponentInjector(this));       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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&amp;#160; 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.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Techniques For Using JavaEE Inject Resources Outside Of WebPages&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;GuestBook uses an instance of a DataView to display the list of names of its visitors. A DataView requires a &lt;em&gt;pseudo model&lt;/em&gt; of type IDataProvider&amp;lt;T&amp;gt; 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?&lt;/p&gt;  &lt;p&gt;The solution was to create the following interface that GuestDataProvider implements:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font size="2"&gt;public interface IEjbDataProvider&amp;lt;T&amp;gt; extends IDataProvider&amp;lt;T&amp;gt; {        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; AbstractFacade&amp;lt;T&amp;gt;&amp;#160; getFacade();         &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font size="2"&gt;&lt;font size="3"&gt;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.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In the HomePage constructor we create an instance of a GuestDataProvider and override its getFacade method by returning the reference to our session bean.&lt;/p&gt;  &lt;pre&gt;&lt;font size="2"&gt;public class HomePage extends BasePage {

    @EJB(name = &amp;quot;GuestFacade&amp;quot;)
    private GuestFacade guestFacade;

    public HomePage() {
        super();

        add(new FeedbackPanel(&amp;quot;feedback&amp;quot;));

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

            @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&amp;lt;Guest&amp;gt; guestForm = new Form&amp;lt;Guest&amp;gt;(&amp;quot;guestform&amp;quot;, new CompoundPropertyModel&amp;lt;Guest&amp;gt;(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(&amp;quot;firstNameBorder&amp;quot;)
                .add(new NameTextField(&amp;quot;firstName&amp;quot;)));
        guestForm
                .add(new FormComponentFeedbackBorder(&amp;quot;lastNameBorder&amp;quot;)
                .add(new NameTextField(&amp;quot;lastName&amp;quot;)));
        add(guestForm);

        GuestDataProvider gdp = new GuestDataProvider() {

            @Override
            public AbstractFacade&amp;lt;Guest&amp;gt; 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&amp;lt;Guest&amp;gt; guestListView = new DataView&amp;lt;Guest&amp;gt;(&amp;quot;namelist&amp;quot;, gdp) {

            @Override
            protected void populateItem(Item&amp;lt;Guest&amp;gt; item) {
                Guest guest = item.getModelObject();
                item.add(new Label(&amp;quot;name&amp;quot;, guest.toString()));
            }

        };

        add(guestListView);

    }
}&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wicket Models Put To Best Use&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 &lt;a href="http://jeff-schwartz.blogspot.com/2011/03/put-your-wicket-applications-on-diet.html"&gt;&lt;font color="#0000ff"&gt;read my article here&lt;/font&gt;&lt;/a&gt; to get up to speed on this subject.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, lets talk a bit about Wicket components and some ideas that I’d like to share with you. &lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;In &lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html" target="_blank"&gt;&lt;font color="#0000ff"&gt;article #1&lt;/font&gt;&lt;/a&gt; we expressed the business rules for GuestBook as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Limit the number of characters our visitors can key in for their first and last names to a maximum of 45 characters each. &lt;/li&gt;

  &lt;li&gt;Both first and last name are required. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GuestBook uses NameTextField, a subclass of TextField, to encapsulate and enforce its business rules.&lt;/p&gt;

&lt;pre&gt;&lt;font size="2" face="Georgia"&gt;public class NameTextField extends TextField&amp;lt;String&amp;gt;{

    /**
     *
     * @param id
     * @param model
     */
    public NameTextField(String id, IModel&amp;lt;String&amp;gt; model) {
        super(id,model);
        setRequired(true);
    }

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

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


}&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Now a word or two on structuring your code. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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!&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;I hope you have enjoyed reading this series and following along with me as much as I have enjoyed sharing my time with you.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;May all your days coding be happy and productive ones.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-2353671307200364144?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/2353671307200364144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-6-wrap-up.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2353671307200364144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2353671307200364144'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-6-wrap-up.html' title='Java EE6 &amp;amp; Wicket - Article #6 – A Wrap Up'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-2826615229441712182</id><published>2011-03-30T13:37:00.000-04:00</published><updated>2011-03-31T08:50:56.749-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='javaee'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='EE6'/><title type='text'>Java EE6 &amp; Wicket - Article #5–Building Out The Guest Book Web Application Using NetBeans</title><content type='html'>Welcome to the 5th in a series of detailed articles on Java EE6 &amp;amp; Wicket. If you haven’t already, please read the following previous articles before continuing.   &lt;br /&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html" target="_blank"&gt;&lt;span style="color: blue"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html&lt;/span&gt;&lt;/a&gt;&lt;span style="color: blue"&gt; &lt;/span&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html" target="_blank"&gt;&lt;span style="color: blue"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html&lt;/span&gt;&lt;/a&gt;&lt;span style="color: blue"&gt; &lt;/span&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html" target="_blank"&gt;&lt;span style="color: blue"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html&lt;/span&gt;&lt;/a&gt;&lt;span style="color: blue"&gt; &lt;/span&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html" target="_blank"&gt;&lt;span style="color: blue"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html&lt;/span&gt;&lt;/a&gt;&lt;span style="color: blue"&gt; &lt;/span&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-4-adding-jpa.html" target="_blank"&gt;&lt;span style="color: blue"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-4-adding-jpa.html&lt;/span&gt;&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;In this, the 5th article in this series, we will complete the implementation of the GuestBook Web application. So lets get started.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Modifying The Generated Markup And Code&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;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 &lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html" target="_blank"&gt;&lt;span style="color: blue"&gt;article #1&lt;/span&gt;&lt;/a&gt;. In order to do that we will compose the HomePage using Wicket Markup Inheritance.&lt;/p&gt;  &lt;p&gt;Our HomePage displays a Wicket logo which you can download &lt;a href="http://code.google.com/p/wickettutorials/downloads/detail?name=Apache_Wicket_logo.png&amp;amp;can=2&amp;amp;q=" target="_blank"&gt;&lt;span style="color: blue"&gt;here&lt;/span&gt;&lt;/a&gt;. Place the logo&amp;#160; in the com.myapp.wicket package.&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Right click on the com.myapp.wicket package, select New | Other to open the New File window &lt;/li&gt;    &lt;li&gt;Select Web in the Categories panel and then select HTML in the File Types panel and click the Next button.&lt;a href="http://lh5.ggpht.com/_XzLrgIoZ_TU/TZMq4FvJ0MI/AAAAAAAAAeg/uVkm24CD5hI/s1600-h/2011-03-30-08h45_573.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 10px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-30 08h45_57" border="0" alt="2011-03-30 08h45_57" src="http://lh6.ggpht.com/_XzLrgIoZ_TU/TZMq4ktciqI/AAAAAAAAAek/Lyk1jvCIbuM/2011-03-30-08h45_57_thumb1.png?imgmax=800" width="975" height="520" /&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;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. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Replace the generated markup with the following markup and save the file: &lt;/p&gt;  &lt;pre&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html xmlns:wicket=&amp;quot;http://wicket.apache.org&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;head&amp;gt;&lt;br /&gt;
        &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;A guest list of the rich and famous written in Java and Wicket&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/head&amp;gt;&lt;br /&gt;
    &amp;lt;body&amp;gt;&lt;br /&gt;
        &amp;lt;div wicket:id=&amp;quot;headerpanel&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;wicket:child/&amp;gt;&lt;br /&gt;
    &amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;

&lt;p&gt;Replace all the code in com.myapp.wicket.BasePage.java with the following code and save the file: &lt;/p&gt;

&lt;pre&gt;package com.myapp.wicket;           &lt;br /&gt;&lt;br /&gt;import org.apache.wicket.markup.html.WebPage;&lt;br /&gt;&lt;br /&gt;/** &lt;br /&gt;*&lt;br /&gt;* @author Jeff&lt;br /&gt;* @version &lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public class BasePage extends WebPage {&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Construct.&lt;br /&gt;* @param model&lt;br /&gt;*/&lt;br /&gt;public BasePage() {&lt;br /&gt;super();&lt;br /&gt;add(new HeaderPanel(&amp;quot;headerpanel&amp;quot;));&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;Replace the HTML markup in com.myapp.wicket.HeaderPanel.htm with the following markup and save the file: &lt;/p&gt;

&lt;pre&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;html xmlns:wicket=&amp;quot;http://wicket.apache.org&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;wicket:panel&amp;gt;&lt;br /&gt;&amp;lt;wicket:link&amp;gt;&lt;br /&gt;&amp;lt;img src=&amp;quot;Apache_Wicket_logo.png&amp;quot; style=&amp;quot;float:left;&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/wicket:link&amp;gt;&lt;br /&gt;&amp;lt;h1 style=&amp;quot;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&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;span wicket:id=&amp;quot;headerpanneltext&amp;quot;&amp;gt;Java EE6 And Wicket EJB Tutorial&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;hr style=&amp;quot;color: #E9601A; background-color: #E9601A; height: 1px;&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/wicket:panel&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;

&lt;p&gt;Replace the Java code in com.myapp.wicket.HeaderPanel.java with the following code and save the file: &lt;/p&gt;

&lt;pre&gt;package com.myapp.wicket;           &lt;br /&gt;&lt;br /&gt;import org.apache.wicket.markup.html.basic.Label;&lt;br /&gt;import org.apache.wicket.markup.html.panel.Panel;&lt;br /&gt;&lt;br /&gt;/** &lt;br /&gt;*&lt;br /&gt;* @author Jeff&lt;br /&gt;* @version &lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public class HeaderPanel extends Panel {&lt;br /&gt;&lt;br /&gt;public HeaderPanel(String id)&lt;br /&gt;{&lt;br /&gt;super(id);&lt;br /&gt;add(new Label(&amp;quot;headerpanneltext&amp;quot;, &amp;quot;Java EE6 And Wicket EJB Tutorial&amp;quot;));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;Replace all the HTML markup in com.myapp.wicket.HomePage.html with the following markup and save the file: &lt;/p&gt;

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

&lt;p&gt;Replace all the Java code in com.myapp.wicket.HomePage.java with the following code and save the file: &lt;/p&gt;

&lt;pre&gt;package com.myapp.wicket;&lt;br /&gt;&lt;br /&gt;import com.myapp.wicket.components.NameTextField;&lt;br /&gt;import com.myapp.wicket.dataproviders.GuestDataProvider;&lt;br /&gt;import com.myapp.entities.Guest;&lt;br /&gt;import com.myapp.sessionbeans.AbstractFacade;&lt;br /&gt;import com.myapp.sessionbeans.GuestFacade;&lt;br /&gt;import javax.ejb.EJB;&lt;br /&gt;import org.apache.wicket.markup.html.basic.Label;&lt;br /&gt;import org.apache.wicket.markup.html.form.Form;&lt;br /&gt;import org.apache.wicket.markup.html.form.validation.FormComponentFeedbackBorder;&lt;br /&gt;import org.apache.wicket.markup.html.panel.FeedbackPanel;&lt;br /&gt;import org.apache.wicket.markup.repeater.Item;&lt;br /&gt;import org.apache.wicket.markup.repeater.data.DataView;&lt;br /&gt;import org.apache.wicket.model.CompoundPropertyModel;&lt;br /&gt;import org.apache.wicket.model.LoadableDetachableModel;&lt;br /&gt;&lt;br /&gt;public class HomePage extends BasePage {&lt;br /&gt;&lt;br /&gt;@EJB(name = &amp;quot;GuestFacade&amp;quot;)&lt;br /&gt;private GuestFacade guestFacade;&lt;br /&gt;&lt;br /&gt;public HomePage() {&lt;br /&gt;super();&lt;br /&gt;&lt;br /&gt;add(new FeedbackPanel(&amp;quot;feedback&amp;quot;));&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* A loadable and detachable model whose sole purpose is to always&lt;br /&gt;* return a new Guest object when its load method is called.&lt;br /&gt;*/&lt;br /&gt;LoadableDetachableModel&amp;lt;Guest&amp;gt; newGuestLoadableDetachableModel = new LoadableDetachableModel&amp;lt;Guest&amp;gt;() {&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;protected Guest load() {&lt;br /&gt;return new Guest();&lt;br /&gt;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* The guestForm uses a nested model. The outer model is a compound property&lt;br /&gt;* model and the inner model is a light weight loadable and detachable model.&lt;br /&gt;*/&lt;br /&gt;Form&amp;lt;Guest&amp;gt; guestForm = new Form&amp;lt;Guest&amp;gt;(&amp;quot;guestform&amp;quot;, new CompoundPropertyModel&amp;lt;Guest&amp;gt;(newGuestLoadableDetachableModel)) {&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;protected void onSubmit() {&lt;br /&gt;Guest guest = getModelObject();&lt;br /&gt;guestFacade.create(guest);&lt;br /&gt;setModelObject(new Guest());&lt;br /&gt;guest = new Guest();&lt;br /&gt;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* Add the custom NameTextField compent for &lt;br /&gt;* first and last name to the form, nesting each&lt;br /&gt;* in a FormComponentFeedbackBorder for displaying&lt;br /&gt;* data entry errors.&lt;br /&gt;*/&lt;br /&gt;guestForm&lt;br /&gt;.add(new FormComponentFeedbackBorder(&amp;quot;firstNameBorder&amp;quot;)&lt;br /&gt;.add(new NameTextField(&amp;quot;firstName&amp;quot;)));&lt;br /&gt;guestForm&lt;br /&gt;.add(new FormComponentFeedbackBorder(&amp;quot;lastNameBorder&amp;quot;)&lt;br /&gt;.add(new NameTextField(&amp;quot;lastName&amp;quot;)));&lt;br /&gt;add(guestForm);&lt;br /&gt;&lt;br /&gt;GuestDataProvider gdp = new GuestDataProvider() {&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public AbstractFacade&amp;lt;Guest&amp;gt; getFacade() {&lt;br /&gt;return guestFacade;&lt;br /&gt;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* When dealing with potentially large lists of data it is&lt;br /&gt;* better to use a DataView whose constructor takes a data&lt;br /&gt;* provider as its second parameter.&lt;br /&gt;*/&lt;br /&gt;DataView&amp;lt;Guest&amp;gt; guestListView = new DataView&amp;lt;Guest&amp;gt;(&amp;quot;namelist&amp;quot;, gdp) {&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;protected void populateItem(Item&amp;lt;Guest&amp;gt; item) {&lt;br /&gt;Guest guest = item.getModelObject();&lt;br /&gt;item.add(new Label(&amp;quot;name&amp;quot;, guest.toString()));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;add(guestListView);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;Replace the content of com.myapp.wicket.style.css with the following content and save the file: &lt;/p&gt;

&lt;pre&gt;body {&lt;br /&gt;white-space: nowrap;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.feedbackPanelERROR {&lt;br /&gt;color: red !important;&lt;br /&gt;list-style: circle;&lt;br /&gt;font-weight: bold;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.feedbackPanelINFO {&lt;br /&gt;color: green;&lt;br /&gt;list-style: circle;&lt;br /&gt;font-weight: bold;&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Right click on the com.myapp.wicket package in the Projects panel and select New | Other to open the New File Window. &lt;/li&gt;

  &lt;li&gt;Select Other from Categories and select Properties File from File Types and click the Next button. &lt;/li&gt;

  &lt;li&gt;Enter HomePage for the File Name and click the Finish button. NetBeans will open the properties file in the eiditor. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add the following content to the the com.myapp.wicket.HomePage.properties file and save the file: &lt;/p&gt;

&lt;pre&gt;firstName.Required=First Name Is Required. 
    &lt;br /&gt;lastName.Required=Last Name Is Required.&lt;/pre&gt;

&lt;p&gt;Next, we will add a custom TextField component to the project. &lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Right click on Source Packages in the Projects panel and select New | Other to open the New File window. &lt;/li&gt;

  &lt;li&gt;Select Java from Categories and Java Class from File Types and click the Next button. &lt;/li&gt;

  &lt;li&gt;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. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Replace all the Java code in the NameTextField.java file with the following and save the file: &lt;/p&gt;

&lt;pre&gt;package com.myapp.wicket.components;&lt;br /&gt;&lt;br /&gt;import org.apache.wicket.markup.ComponentTag;&lt;br /&gt;import org.apache.wicket.markup.html.form.TextField;&lt;br /&gt;import org.apache.wicket.model.IModel;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* A domain specific extension of a Wicket TextField&lt;br /&gt;* that sets the required flag and adds the maxlength=45&lt;br /&gt;* and size=55 attributes to be rendered.&lt;br /&gt;*&lt;br /&gt;* Demonstrates how you can easily extend Wicket&lt;br /&gt;* components to provide domain specific requirement.&lt;br /&gt;*&lt;br /&gt;* @author Jeff&lt;br /&gt;*/&lt;br /&gt;public class NameTextField extends TextField&amp;lt;String&amp;gt;{&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;*&lt;br /&gt;* @param id&lt;br /&gt;* @param model&lt;br /&gt;*/&lt;br /&gt;public NameTextField(String id, IModel&amp;lt;String&amp;gt; model) {&lt;br /&gt;super(id,model);&lt;br /&gt;setRequired(true);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;*&lt;br /&gt;* @param id&lt;br /&gt;*/&lt;br /&gt;public NameTextField(String id) {&lt;br /&gt;this(id,null);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;protected void onComponentTag(ComponentTag tag) {&lt;br /&gt;tag.put(&amp;quot;maxlength&amp;quot;, &amp;quot;45&amp;quot;);&lt;br /&gt;tag.put(&amp;quot;size&amp;quot;, &amp;quot;55&amp;quot;);&lt;br /&gt;super.onComponentTag(tag);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;Next, we will add an interface to the project. &lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Right click on Source Packages in the Projects panel and select New | Other to open the New File window. &lt;/li&gt;

  &lt;li&gt;Select Java from Categories and select Java Interface from File Types and click the Next button. &lt;/li&gt;

  &lt;li&gt;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. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Replace all the Java code in the IEjbDataProvider.java file with the following and save the file: &lt;/p&gt;

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

&lt;p&gt;Next, we will add a Java class to the project. &lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Right click on com.myapp.wicket.dataproviders in the Projects panel and select New | Other to open the New File window. &lt;/li&gt;

  &lt;li&gt;Select Java from Categories and select Java Class from File Types and the click the Next button. &lt;/li&gt;

  &lt;li&gt;Enter GuestDataProvider for Class Name and click the Finish button. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Replace all the Java code in the GuestDataProvider.java file with the following and save the file: &lt;/p&gt;

&lt;pre&gt;package com.myapp.wicket.dataproviders;&lt;br /&gt;&lt;br /&gt;import com.myapp.entities.Guest;&lt;br /&gt;import java.util.Iterator;&lt;br /&gt;import java.util.List;&lt;br /&gt;import org.apache.wicket.model.IModel;&lt;br /&gt;import org.apache.wicket.model.LoadableDetachableModel;&lt;br /&gt;&lt;br /&gt;abstract public class GuestDataProvider implements IEjbDataProvider&amp;lt;Guest&amp;gt;{&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public Iterator&amp;lt;? extends Guest&amp;gt; iterator(int first, int count) {&lt;br /&gt;int[] range = {first, count};&lt;br /&gt;List&amp;lt;Guest&amp;gt; guests = getFacade().findRange(range);&lt;br /&gt;return getFacade().findRange(range).iterator();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public IModel&amp;lt;Guest&amp;gt; model(final Guest object) {&lt;br /&gt;&lt;br /&gt;final Integer id = object.getId();&lt;br /&gt;&lt;br /&gt;LoadableDetachableModel&amp;lt;Guest&amp;gt; ldm = new LoadableDetachableModel&amp;lt;Guest&amp;gt;(object) {&lt;br /&gt;@Override&lt;br /&gt;protected Guest load() {&lt;br /&gt;return getFacade().find(id);&lt;br /&gt;}&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;return ldm;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public int size() {&lt;br /&gt;return getFacade().count();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public void detach() {}&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;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: &lt;/p&gt;

&lt;pre&gt;package com.myapp.wicket;           &lt;br /&gt;&lt;br /&gt;import org.apache.wicket.protocol.http.WebApplication;&lt;br /&gt;import org.wicketstuff.javaee.injection.JavaEEComponentInjector;&lt;br /&gt;/** &lt;br /&gt;*&lt;br /&gt;* @author Jeff&lt;br /&gt;* @version &lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;public class Application extends WebApplication {&lt;br /&gt;&lt;br /&gt;public Application() {&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;protected void init() {&lt;br /&gt;super.init();&lt;br /&gt;addComponentInstantiationListener(new JavaEEComponentInjector(this));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public Class getHomePage() {&lt;br /&gt;return HomePage.class;&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;

&lt;p&gt;With all these changes in place you should now be able to run the project in your browser.&lt;/p&gt;

&lt;p&gt;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 &lt;a href="http://jeff-schwartz.blogspot.com/2011/03/put-your-wicket-applications-on-diet.html" target="_blank"&gt;&lt;span style="color: blue"&gt;read my article here&lt;/span&gt;&lt;/a&gt;&lt;span style="color: blue"&gt;&lt;/span&gt; to get up to speed on this subject. Stay tuned!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-2826615229441712182?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/2826615229441712182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-5building-out.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2826615229441712182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2826615229441712182'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-5building-out.html' title='Java EE6 &amp;amp; Wicket - Article #5–Building Out The Guest Book Web Application Using NetBeans'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_XzLrgIoZ_TU/TZMq4ktciqI/AAAAAAAAAek/Lyk1jvCIbuM/s72-c/2011-03-30-08h45_57_thumb1.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-9059293524562342247</id><published>2011-03-29T22:43:00.001-04:00</published><updated>2011-05-29T07:46:08.661-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Put Your Wicket Applications On A Diet</title><content type='html'>&lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;To begin out discussion of Wicket’s models let’s first look at the IModel interface.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;IModel&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;All Wicket models implement the IModel interface which is defined as follows:&lt;/p&gt;  &lt;pre&gt;public interface IModel&amp;lt;T&amp;gt; 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);
}&lt;/pre&gt;

&lt;p&gt;The IModel interface defines 2 methods:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;getObject is called by Wicket when rendering the component. &lt;/li&gt;

  &lt;li&gt;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).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;IDetachable&lt;/strong&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;In addition to defining the getObject and setObject methods, IModel also extends the IDetachable interface which is defined as follows:&lt;/p&gt;

&lt;pre&gt;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();
}&lt;/pre&gt;

&lt;p&gt;The IDetachable interface&amp;#160; defines only 1 method:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;detach is called by Wicket at the end of a request’s lifecycle. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Model – the simplest of all Wicket models. It can be used as both a static and as a dynamic model. &lt;/li&gt;

  &lt;li&gt;PropertyModel – a dynamic model. &lt;/li&gt;

  &lt;li&gt;CompoundPropertyModel – a dynamic model that also provides field binding. &lt;/li&gt;

  &lt;li&gt;LoadableDetachableModel – a dynamic model that detaches the value it wraps at the end of a request’s lifecycle. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Static And Dynamic Models&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here’s an example of using Model as a static model:&lt;/p&gt;

&lt;pre style="width: 994px; height: 148px"&gt;&lt;p&gt;Person person = Person.getPerson();&lt;/p&gt;&lt;p&gt;add(new Label(&amp;quot;firstName&amp;quot;, new Model&amp;lt;String&amp;gt;(person.getFirstName())));&lt;/p&gt;&lt;p&gt;add(new Label(&amp;quot;lastName&amp;quot;, new Model&amp;lt;String&amp;gt;(person.getLastName())));&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;And here’s an example of using Model as a dynamic model:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre&gt;Person person = Person.getPerson();

add(new Label(&amp;quot;firstName&amp;quot;, new Model&amp;lt;String&amp;gt;(){

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

}));

add(new Label(&amp;quot;lastName&amp;quot;, new Model&amp;lt;String&amp;gt;(){

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

}));&lt;/pre&gt;

&lt;p&gt;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.&lt;/p&gt;
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. 

&lt;blockquote&gt;
  &lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;
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. 

&lt;p&gt;So let me reiterate here by giving you a concise definition of static and dynamic models:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;A static model is any model that directly wraps a value. &lt;/li&gt;

  &lt;li&gt;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.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the above and for the remainder of this article I use the word ‘value’ to denote either a primitive or a reference value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some Models Are Heavier Than Others&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Lets consider a slightly more involved use case that involves a form that uses a CompoundPropertyModel:&lt;/p&gt;

&lt;pre style="width: 1094px; height: 187px"&gt;&lt;p&gt;Form&amp;lt;Person&amp;gt; form = new Form&amp;lt;Person&amp;gt;(&amp;quot;form&amp;quot;, new CompoundPropertyModel&amp;lt;Person&amp;gt;(Person.getPerson()));&lt;/p&gt;&lt;p&gt;form.add(new TextField&amp;lt;String&amp;gt;(&amp;quot;firstName&amp;quot;));&lt;/p&gt;&lt;p&gt;form.add(new TextField&amp;lt;String&amp;gt;(&amp;quot;lastName&amp;quot;)); &lt;/p&gt;&lt;p&gt;add(form);&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LoadableDetachableModel Take The Weight Off&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;pre&gt;LoadableDetachableModel ldm = new LoadableDetachableModel&amp;lt;Person&amp;gt;() {

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

};&lt;/pre&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Using&amp;#160; 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. &lt;/p&gt;

&lt;p&gt;[*** 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. ***]&lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nesting Models&lt;/strong&gt;&lt;/p&gt;

&lt;pre style="width: 1094px; height: 184px"&gt;&lt;p&gt;Form&amp;lt;Person&amp;gt; form = new Form&amp;lt;Person&amp;gt;(&amp;quot;form&amp;quot;, new CompoundPropertyModel&amp;lt;Person&amp;gt;(ldm));&lt;/p&gt;&lt;p&gt;form.add(new TextField&amp;lt;String&amp;gt;(&amp;quot;firstName&amp;quot;));&lt;/p&gt;&lt;p&gt;form.add(new TextField&amp;lt;String&amp;gt;(&amp;quot;lastName&amp;quot;));&lt;/p&gt;&lt;p&gt;add(form);&lt;/p&gt;&lt;/pre&gt;

&lt;p&gt;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!&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-9059293524562342247?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/9059293524562342247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/put-your-wicket-applications-on-diet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/9059293524562342247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/9059293524562342247'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/put-your-wicket-applications-on-diet.html' title='Put Your Wicket Applications On A Diet'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-5149700697126566593</id><published>2011-03-29T10:17:00.001-04:00</published><updated>2011-03-30T12:59:03.426-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stateless'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='javaee'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='EE6'/><title type='text'>Java EE6 &amp; Wicket - Article #4 - Adding JPA Persistence And EJB Support</title><content type='html'>&lt;p&gt;Welcome to the 4th in a series of detailed articles on Java EE6 &amp;amp; Wicket. If you haven’t already, please read the following previous articles before continuing.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html&lt;/font&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html&lt;/font&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html&lt;/font&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html&lt;/font&gt;&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;Data Access&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The GuestBook Web application we are building must access the data from the &lt;em&gt;guest table&lt;/em&gt; in the &lt;em&gt;guestbook database&lt;/em&gt; which we created together in the &lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html"&gt;&lt;font color="#0000ff"&gt;2nd article&lt;/font&gt;&lt;/a&gt;. The goal of this article is to provide access to the database using JPA and Enterprise Java Bean (EJB).&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;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. &lt;/p&gt;  &lt;p&gt;&lt;em&gt;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).&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Create A New Entity Class From A Database Table&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In the Projects panel right click on the &lt;em&gt;Source Packages&lt;/em&gt; item and select &lt;em&gt;New | Other&lt;/em&gt; which will open the New File window. In the Categories list select &lt;em&gt;Persistence&lt;/em&gt; and in File Type select &lt;em&gt;Entity Classes from Database&lt;/em&gt; and then click the Next button. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Expand the Data Source dropdown and select New Data Source to open the Create Data Source window. Enter &lt;em&gt;guestbook&lt;/em&gt; 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.       &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZHp_onbMJI/AAAAAAAAAdw/nS-x49e4Z_I/s1600-h/2011-03-29%2008h24_36%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-29 08h24_36" border="0" alt="2011-03-29 08h24_36" src="http://lh4.ggpht.com/_XzLrgIoZ_TU/TZHp_-uTEWI/AAAAAAAAAd0/hGcwgK1VcoY/2011-03-29%2008h24_36_thumb%5B1%5D.png?imgmax=800" width="503" height="217" /&gt;&lt;/a&gt;&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;If prompted for the password enter the password you created when you installed MySQL and click OK.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;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.      &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_XzLrgIoZ_TU/TZHqAc_d05I/AAAAAAAAAd4/ae_frEzHgyw/s1600-h/2011-03-29%2008h29_15%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-29 08h29_15" border="0" alt="2011-03-29 08h29_15" src="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZHqA0AesTI/AAAAAAAAAd8/0x3FuCqPVSw/2011-03-29%2008h29_15_thumb%5B1%5D.png?imgmax=800" width="779" height="520" /&gt;&lt;/a&gt;&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;Enter &lt;em&gt;com.myapp.entities&lt;/em&gt; for the Package name and click the Next button.       &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_XzLrgIoZ_TU/TZHqBboXUII/AAAAAAAAAeA/5OQ0WWg9wXE/s1600-h/2011-03-29%2009h46_00%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-29 09h46_00" border="0" alt="2011-03-29 09h46_00" src="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZHqBxFu82I/AAAAAAAAAeE/MI1Pj28I9Uk/2011-03-29%2009h46_00_thumb%5B1%5D.png?imgmax=800" width="779" height="519" /&gt;&lt;/a&gt;&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Select &lt;em&gt;java.util.List&lt;/em&gt; for the Collection Type and then click the Finish button.&lt;/p&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The result of the above steps is NetBeans created &lt;em&gt;Guest.java&lt;/em&gt; POJO with JPA annotations and placed it in the &lt;em&gt;com.myapp.entities&lt;/em&gt; package. NetBeans also created the JPA configuration file &lt;em&gt;persistence.xml.&lt;/em&gt; If you fully expand the project node in the Projects panel you will see the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_XzLrgIoZ_TU/TZHqCBX7qoI/AAAAAAAAAeI/i5D0wHhozvI/s1600-h/2011-03-29%2009h48_16%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-29 09h48_16" border="0" alt="2011-03-29 09h48_16" src="http://lh4.ggpht.com/_XzLrgIoZ_TU/TZHqCabtt6I/AAAAAAAAAeM/trIOt9dEbXA/2011-03-29%2009h48_16_thumb%5B1%5D.png?imgmax=800" width="213" height="329" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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&amp;#160; build at the application:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;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:&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;font size="2"&gt;@Override         &lt;br /&gt;public String toString() {          &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return firstName + &amp;quot; &amp;quot; + lastName;          &lt;br /&gt;}&lt;/font&gt;&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;We will make use of this method i&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Create The EJB&lt;/strong&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;p&gt;In the Projects panel right click on Source Packages and select &lt;em&gt;New | Other&lt;/em&gt; to open the New File window.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;From Categories select Persistence and from File Types select &lt;em&gt;Session Beans For Entity Classes&lt;/em&gt; and click the Next button.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Select &lt;em&gt;com.myapp.entities.Guest&lt;/em&gt; 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.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Enter &lt;em&gt;com.myapp.sessionbeans&lt;/em&gt; for the Package and click the Finish button. &lt;em&gt;Notice how we didn’t create any interfaces in this last step.&lt;/em&gt;&lt;/p&gt;      &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_XzLrgIoZ_TU/TZHqC96_fYI/AAAAAAAAAeQ/ScYE1yILsek/s1600-h/2011-03-29%2009h54_26%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-29 09h54_26" border="0" alt="2011-03-29 09h54_26" src="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZHqDGf5n9I/AAAAAAAAAeU/0lxrZie3VWk/2011-03-29%2009h54_26_thumb%5B1%5D.png?imgmax=800" width="912" height="589" /&gt;&lt;/a&gt;&lt;/p&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The result of the above steps is NetBeans created 2 classes in the &lt;em&gt;com.myapp.sessionbeans&lt;/em&gt; package, &lt;em&gt;AbstractFacade.java&lt;/em&gt; and&amp;#160; &lt;em&gt;GuestFacade.java&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZHwJo1ngUI/AAAAAAAAAeY/TW5iAz780xs/s1600-h/2011-03-29%2010h41_36%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-29 10h41_36" border="0" alt="2011-03-29 10h41_36" src="http://lh4.ggpht.com/_XzLrgIoZ_TU/TZHwKObeJRI/AAAAAAAAAec/PL5kMjbWSu0/2011-03-29%2010h41_36_thumb%5B1%5D.png?imgmax=800" width="259" height="273" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;em&gt;AbstractFacade.java&lt;/em&gt; is an abstract class that implements generalized functionality. &lt;/li&gt;    &lt;li&gt;&lt;em&gt;GuestFacade.java&lt;/em&gt;, a subclass of &lt;em&gt;AbstractFacade.java,&lt;/em&gt; provides &lt;em&gt;Guest.java&lt;/em&gt; type specific behavior and is annotated with @Stateless marking it as a stateless session bean. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;One more thing to do and then we are done. Fully expand &lt;em&gt;Server Resources&lt;/em&gt; 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:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font size="2"&gt;&amp;lt;property name=&amp;quot;Password&amp;quot; value=&amp;quot;admin&amp;quot;/&amp;gt;&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In the next article we will build out the Wicket parts of GuestBook and use the features provided by the &lt;em&gt;JavaEE Inject Library&lt;/em&gt; which we added to our project in the &lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html"&gt;&lt;font color="#0000ff"&gt;3rd article&lt;/font&gt;&lt;/a&gt; to inject the GuestFacade.java session bean into our Wicket pages. Stay tuned!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-5149700697126566593?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/5149700697126566593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-4-adding-jpa.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/5149700697126566593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/5149700697126566593'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-4-adding-jpa.html' title='Java EE6 &amp;amp; Wicket - Article #4 - Adding JPA Persistence And EJB Support'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_XzLrgIoZ_TU/TZHp_-uTEWI/AAAAAAAAAd0/hGcwgK1VcoY/s72-c/2011-03-29%2008h24_36_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-8499482162774497601</id><published>2011-03-28T07:49:00.001-04:00</published><updated>2011-03-28T12:26:08.426-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='javaee'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='EE6'/><title type='text'>Java EE6 &amp; Wicket - Article #3 – Generating The Guest Book Web Application Using NetBeans And Deploying It To GlassFish</title><content type='html'>&lt;p&gt;Welcome to the 3rd in a series of detailed articles on Java EE6 &amp;amp; Wicket. If you haven’t already, please read the following previous articles before continuing.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html" target="_blank"&gt;&lt;font color="#0000ff"&gt;Java EE6 &amp;amp; Wicket&lt;/font&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html" target="_blank"&gt;&lt;font color="#0000ff"&gt;Java EE6 &amp;amp; Wicket - Article #1 - Requirements, Architecture &amp;amp; Resources&lt;/font&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html" target="_blank"&gt;&lt;font color="#0000ff"&gt;Java EE6 &amp;amp; Wicket - Article #2 – Creating A Backing Datastore And Schema Using MySQL&lt;/font&gt;&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Simple Deployment With Java EE6 And The EJB 3.1 Specification&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;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,&amp;#160; addresses this issue and makes deploying EE6 applications much simpler. Rather than going into the details here, you can read the article &lt;a href="http://www.infoq.com/news/2010/02/jee6_ejb_31" target="_blank"&gt;&lt;font color="#0000ff"&gt;Java EE6: EJB3.1 Is a Compelling Evolution&lt;/font&gt;&lt;/a&gt;, 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.&lt;/p&gt;  &lt;p&gt;OK, lets get started. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Generating The GuestBook Web Application&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;If you haven’t already, fire up NetBeans. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;     &lt;p&gt;From the main menu select &lt;em&gt;File | New Project&lt;/em&gt; which will open the New Project window. &lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Select &lt;em&gt;Java Web&lt;/em&gt; in the Categories panel and &lt;em&gt;Web Application&lt;/em&gt; from the Projects panel and click the Next button. &lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Enter &lt;em&gt;GuestBook&lt;/em&gt; for the project name and click the Next button.&lt;/p&gt;     &lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-28 08h40_21" border="0" alt="2011-03-28 08h40_21" src="http://lh4.ggpht.com/_XzLrgIoZ_TU/TZCMzINvgTI/AAAAAAAAAc8/EUliYylq57s/2011-03-28%2008h40_21_thumb%5B1%5D.png?imgmax=800" width="812" height="520" /&gt; &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;If they aren’t already, select &lt;em&gt;GlassFish Server 3&lt;/em&gt; as the server and &lt;em&gt;Java EE 6 Web&lt;/em&gt; as the Java EE version and then click the Next button.&lt;/p&gt;     &lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-28 08h46_44" border="0" alt="2011-03-28 08h46_44" src="http://lh5.ggpht.com/_XzLrgIoZ_TU/TZCMzgx6TLI/AAAAAAAAAdA/reTPjT4kcxo/2011-03-28%2008h46_44_thumb%5B1%5D.png?imgmax=800" width="733" height="360" /&gt; &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;The Wicket plugin added Wicket to the list of frameworks that you can use in Web applications. In the Frameworks panel select &lt;em&gt;Wicket&lt;/em&gt; as the framework to use in our application and then click the Finish button. &lt;/p&gt;     &lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-28 08h55_28" border="0" alt="2011-03-28 08h55_28" src="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZCM0v8AW1I/AAAAAAAAAdI/iBbhqw1hQTI/2011-03-28%2008h55_28_thumb%5B3%5D.png?imgmax=800" width="830" height="514" /&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;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:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZCWwJBmdzI/AAAAAAAAAdM/6YRaaB1wk1E/s1600-h/2011-03-28%2009h54_44%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-28 09h54_44" border="0" alt="2011-03-28 09h54_44" src="http://lh6.ggpht.com/_XzLrgIoZ_TU/TZCWwmx_0FI/AAAAAAAAAdQ/F68ImxhAIJk/2011-03-28%2009h54_44_thumb%5B1%5D.png?imgmax=800" width="361" height="562" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;Run the application by clicking on the &lt;em&gt;Run Main Project&lt;/em&gt; 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:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_XzLrgIoZ_TU/TZCWw59FoAI/AAAAAAAAAdU/piuWwlVnlv0/s1600-h/2011-03-28%2010h03_15%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-28 10h03_15" border="0" alt="2011-03-28 10h03_15" src="http://lh4.ggpht.com/_XzLrgIoZ_TU/TZCWxGNX7FI/AAAAAAAAAdY/NOvIHO-zCd4/2011-03-28%2010h03_15_thumb%5B1%5D.png?imgmax=800" width="484" height="164" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;That’s pretty cool considering the minimal effort that was required on our part to get this application up and running at this point.&lt;/p&gt;  &lt;p&gt;If you look at the NetBeans Output window you should see a &lt;em&gt;GlassFish Server 3&lt;/em&gt; 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.: &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZCpCQBt8MI/AAAAAAAAAdc/1BvkOJoB7sc/s1600-h/2011-03-28%2010h26_31%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-28 10h26_31" border="0" alt="2011-03-28 10h26_31" src="http://lh5.ggpht.com/_XzLrgIoZ_TU/TZCpCpn2qEI/AAAAAAAAAdg/hLZ2iT8Ztdk/2011-03-28%2010h26_31_thumb%5B1%5D.png?imgmax=800" width="556" height="106" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Wicket’s Single Purpose&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;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 &lt;a href="http://wicket.apache.org/meet/vision.html" target="_blank"&gt;&lt;font color="#0000ff"&gt;here&lt;/font&gt;&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;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 &lt;a href="http://wicketstuff.org/confluence/display/STUFFWIKI/JavaEE+Inject" target="_blank"&gt;&lt;font color="#0000ff"&gt;JavaEE Inject Library&lt;/font&gt;&lt;/a&gt; and it provides the ability to use the &lt;em&gt;@EJB&lt;/em&gt;, &lt;em&gt;@PersistenceUnit&lt;/em&gt; and &lt;em&gt;@Resource&lt;/em&gt; 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.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Adding The JavaEE Inject Library To Our Project&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;To keep things simple, I’ve created a compressed file named &lt;em&gt;guestbooktutorialadditionaljars.zip&lt;/em&gt; which contains all the jars required by the JavaEE Inject Library and I posted it &lt;a href="http://code.google.com/p/wickettutorials/downloads/list" target="_blank"&gt;&lt;font color="#0000ff"&gt;here&lt;/font&gt;&lt;/a&gt;. 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:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;In the Projects panel right click on the Libraries node and select &lt;em&gt;Add Jar/Folder&lt;/em&gt; to open the Add Jar/Folder window. &lt;/li&gt;    &lt;li&gt;Navigate to the folder on your machine where you extracted the contents of the &lt;em&gt;guestbooktutorialadditionaljars.zip&lt;/em&gt; to and select all 3 jar files &lt;font color="#ff0000"&gt;(important - do not select the zip file itself if it happens to also resides in the same folder, only select the 3 jar files)&lt;/font&gt; as pictured below. &lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-28 11h20_27" border="0" alt="2011-03-28 11h20_27" src="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZCpDjVs8iI/AAAAAAAAAdk/7Al6ND4Z48c/2011-03-28%2011h20_27_thumb%5B1%5D.png?imgmax=800" width="804" height="348" /&gt; &lt;/li&gt;    &lt;li&gt;Now click the Open button to close the window and add the 3 jar files to the project. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_XzLrgIoZ_TU/TZCtGc7qGZI/AAAAAAAAAdo/U_0JTtCUJjU/s1600-h/2011-03-28%2011h31_13%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-28 11h31_13" border="0" alt="2011-03-28 11h31_13" src="http://lh5.ggpht.com/_XzLrgIoZ_TU/TZCtG-ap-iI/AAAAAAAAAds/wlCfzR2Buyc/2011-03-28%2011h31_13_thumb%5B1%5D.png?imgmax=800" width="354" height="186" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;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!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-8499482162774497601?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/8499482162774497601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/8499482162774497601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/8499482162774497601'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html' title='Java EE6 &amp;amp; Wicket - Article #3 – Generating The Guest Book Web Application Using NetBeans And Deploying It To GlassFish'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_XzLrgIoZ_TU/TZCMzINvgTI/AAAAAAAAAc8/EUliYylq57s/s72-c/2011-03-28%2008h40_21_thumb%5B1%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-7064446143242904555</id><published>2011-03-27T14:07:00.001-04:00</published><updated>2011-03-30T12:20:58.848-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='javaee'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Java EE6 &amp; Wicket - Article #2 – Creating A Backing Datastore And Schema Using MySQL</title><content type='html'>&lt;p&gt;Welcome to the 2nd in a series of detailed articles on Java EE6 &amp;amp; Wicket. If you haven’t already, please read the following previous articles before continuing.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html" target="_blank"&gt;&lt;font color="#0000ff"&gt;Java EE6 &amp;amp; Wicket&lt;/font&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html" target="_blank"&gt;&lt;font color="#0000ff"&gt;Java EE6 &amp;amp; Wicket - Article #1 - Requirements, Architecture &amp;amp; Resources&lt;/font&gt;&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;In this, my 2nd article in this series, we will discuss and demonstrate creating the backing datastore that our GuestBook Web application will use. To accomplish this, we will rely on NetBeans which has excellent built in support for working with MySQL. If you haven’t already created a connection to MySQL in NetBeans you will need to do so before continuing. If you’d like to view an excellent tutorial that demonstrates connecting to MySQL I recommend you read &lt;a href="http://netbeans.org/kb/docs/ide/mysql.html" target="_blank"&gt;&lt;font color="#0000ff"&gt;Connecting to a MySQL Database&lt;/font&gt;&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Create A New Database&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Now that you have connected to MySQL in NetBeans we can get started. If it isn’t already, fire up NetBeans and open the Services tab. &lt;/p&gt;  &lt;p&gt;We want to create a MySQL database that will be dedicated to the GuestBook Web application that we will build together in later articles. NetBeans MySQL support makes creating a new database trivial as the following steps demonstrates. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;In Services, expand the Databases item, right click on the MySQL entry and then select &lt;em&gt;Create Database. &lt;/em&gt;&lt;/li&gt;    &lt;li&gt;In the Create MySQL Database window enter &lt;em&gt;guestbook &lt;/em&gt;in the&lt;em&gt; New Database Name&lt;/em&gt; field. It should look exactly       &lt;br /&gt;like the following image. Now click OK.       &lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_XzLrgIoZ_TU/TY98wlbT03I/AAAAAAAAAcc/9KthJ4hFIR0/s1600-h/2011-03-27%2013h36_27%5B7%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-27 13h36_27" border="0" alt="2011-03-27 13h36_27" src="http://lh4.ggpht.com/_XzLrgIoZ_TU/TY98xOmUfuI/AAAAAAAAAcg/7Lcce30XiTg/2011-03-27%2013h36_27_thumb%5B3%5D.png?imgmax=800" width="554" height="175" /&gt;&lt;/a&gt;       &lt;br /&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;When we clicked OK NetBeans created a new database called &lt;em&gt;guestbook. &lt;/em&gt;It also created a new jdbc connection for the guestbook database and added it as an item listed under &lt;em&gt;Databases as the image below shows.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_XzLrgIoZ_TU/TY98xcvPngI/AAAAAAAAAck/8i6y14bC9zY/s1600-h/2011-03-27%2013h55_56%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-27 13h55_56" border="0" alt="2011-03-27 13h55_56" src="http://lh5.ggpht.com/_XzLrgIoZ_TU/TY98xroX2ZI/AAAAAAAAAco/ptRe1TlNR5A/2011-03-27%2013h55_56_thumb%5B1%5D.png?imgmax=800" width="450" height="97" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Create A New Table With Test Data&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Now that we have created the guestbook database and jdbc connection we can create a table which we will call &lt;em&gt;guest&lt;/em&gt; and which will serve to store the information that our GuestBook Web application visitors will provide. We also want to load the table with some test data which we will use to insure that our database is working properly and also later on when we test our GuestBook Web application.&lt;/p&gt;  &lt;p&gt;To make this step easier for you, I’ve created a SQL script that we will run to generate the table and load it with test data. This is the script that we will run:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font size="2"&gt;CREATE&amp;#160; TABLE `guestbook`.`guest` (&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;&amp;#160; `id` INT NOT NULL AUTO_INCREMENT ,&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;&amp;#160; `firstName` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL ,&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;&amp;#160; `lastName` VARCHAR(45) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL ,&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;&amp;#160; PRIMARY KEY (`id`) );        &lt;br /&gt;&amp;#160; &lt;br /&gt;INSERT INTO `guestbook`.`guest` (`firstName`, `lastName`) VALUES ('James', 'Taylor');&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;INSERT INTO `guestbook`.`guest` (`firstName`, `lastName`) VALUES ('Eric', 'Clapton');&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;INSERT INTO `guestbook`.`guest` (`firstName`, `lastName`) VALUES ('Bill', 'Gates');&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;INSERT INTO `guestbook`.`guest` (`firstName`, `lastName`) VALUES ('Steven', 'Jobs');&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;INSERT INTO `guestbook`.`guest` (`firstName`, `lastName`) VALUES ('John', 'Glenn');&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;INSERT INTO `guestbook`.`guest` (`firstName`, `lastName`) VALUES ('John', 'Kennedy');&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;INSERT INTO `guestbook`.`guest` (`firstName`, `lastName`) VALUES ('Glenn', 'Ford');&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;INSERT INTO `guestbook`.`guest` (`firstName`, `lastName`) VALUES ('Al', 'Pacino');&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font size="2"&gt;INSERT INTO `guestbook`.`guest` (`firstName`, `lastName`) VALUES ('President', 'Obama');&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The above script creates a table by defining its schema in the &lt;em&gt;CREATE TABLE&lt;/em&gt; command. The schema declares 3 columns - id, firstName and lastName. The id column is defined as an auto incrementing column whose values will serve as the table’s primary key. The first and lastName columns are used to store the first and last names of the visitors to our GuestBook Web application. They are both defined as being required and able to store up to 45 characters. &lt;/p&gt;  &lt;p&gt;The interesting part of the firstName and lastName column definitions are our use of &lt;em&gt;CHARACTER SET 'utf8' &lt;/em&gt;and &lt;em&gt;COLLATE 'utf8_general_ci' &lt;/em&gt;to define the character sets and collation for these columns: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;By using &lt;em&gt;CHARACTER SET 'utf8'&lt;/em&gt; in the column definitions we are instructing MySQL to use the &lt;em&gt;utf8 character set &lt;/em&gt;for the characters stored in these columns. This will allow us to store the names of our GuestBook Web application’s visitors from all over the world whose names might require 3 bytes per character&lt;em&gt;.&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;By using &lt;em&gt;COLLATE 'utf8_general_ci'&lt;/em&gt; in the column definitions we are instructing MySQL to use case insensitive collation on these columns. The benefit of this is that when we query on the guest table we will be able to order the result set on firtName and lastName and MySQL will order the result set using case insensitive collation on these columns. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The remaining statements in the script, the &lt;em&gt;INSERT&lt;/em&gt; statements, insert rows into the table whose data will be used to test the GuestBook Web application.&lt;/p&gt;  &lt;p&gt;NetBeans has built in support for running scripts against an already created database. Please follow these steps to run the above script against the guestbook database:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;In NetBeans Services right click on the jdbc connection that was created when we created the guestbook database and select &lt;em&gt;Execute Command&lt;/em&gt; to open a SQL Command window in the editor. &lt;/li&gt;    &lt;li&gt;Copy the script from above and paste it into the SQL Command editor window and then click on the Run SQL icon located on the window’s button bar. Now fully expand the the guestbook jdbc connection in the Services pane and you should see the following:      &lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZNYZMX_9fI/AAAAAAAAAeo/384k9IT5NTU/s1600-h/2011-03-30%2012h16_18%5B3%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="2011-03-30 12h16_18" border="0" alt="2011-03-30 12h16_18" src="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZNYZsVx0II/AAAAAAAAAes/_5cZCRpSYvo/2011-03-30%2012h16_18_thumb%5B1%5D.png?imgmax=800" width="472" height="171" /&gt;&lt;/a&gt;&amp;#160;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;We can see that NetBeans successfully applied our SQL script to the guestbook database creating the guest table which contains id, firstName and lastName columns. We can now issue a query against the table to retrieve the list of names we loaded the table with:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;In the Services window, right click on the guest table’s entry and select Execute Command. &lt;/li&gt;    &lt;li&gt;In the newly opened SQL Command window, type &lt;em&gt;SELECT * FROM guestbook.guest ORDER BY firstName, lastName&lt;/em&gt; and then click on the command window’s Run SQL icon located in its icon bar to run the query against the guest table. When the query completes the result set will be displayed listing the 9 rows of data that we loaded into the guest table:&lt;a href="http://lh3.ggpht.com/_XzLrgIoZ_TU/TZNYZwOEq_I/AAAAAAAAAew/1NYpyKYdswk/s1600-h/2011-03-30%2012h19_58%5B3%5D.png"&gt;        &lt;br /&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="2011-03-30 12h19_58" border="0" alt="2011-03-30 12h19_58" src="http://lh4.ggpht.com/_XzLrgIoZ_TU/TZNYakUekEI/AAAAAAAAAe0/U_qjlOfUGX8/2011-03-30%2012h19_58_thumb%5B1%5D.png?imgmax=800" width="864" height="330" /&gt;&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;With our database preparation out of the way the next article will focus on the fun stuff – generating an &lt;em&gt;ear-less&lt;/em&gt; dynamic web application, adding the Wicket framework to it and deploying it to GlassFish. Stay tuned!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-7064446143242904555?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/7064446143242904555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/7064446143242904555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/7064446143242904555'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html' title='Java EE6 &amp;amp; Wicket - Article #2 – Creating A Backing Datastore And Schema Using MySQL'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_XzLrgIoZ_TU/TY98xOmUfuI/AAAAAAAAAcg/7Lcce30XiTg/s72-c/2011-03-27%2013h36_27_thumb%5B3%5D.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-6080995484876539178</id><published>2011-03-24T09:59:00.000-04:00</published><updated>2011-03-28T12:06:51.947-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='javaee'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Java EE6 &amp; Wicket - Article #1 - Requirements, Architecture &amp; Resources</title><content type='html'>&lt;p&gt;Welcome to the first in a series of detailed articles on Java EE6 &amp;amp; Wicket. If you haven’t already, please read my &lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html"&gt;&lt;font color="#0000ff"&gt;previous article&lt;/font&gt;&lt;/a&gt; before continuing.&lt;/p&gt;  &lt;p&gt;Lets begin with a discussion of the requirements for GuestBook, the Web application we will create.&lt;/p&gt;  &lt;p&gt;It is always a good idea to define the purpose of an application right up front so here’s ours for GuestBook &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Present a Web page that allows visitors to sign a guest book and view a list of visitors who have signed the guest book. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Rather simple, isn’t it. But even simple applications have business rules so here’s ours for GuestBook&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;GuestBook Requirements – Business Rules&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Collect the first and last name of each visitor. &lt;/li&gt;    &lt;li&gt;Limit the number of characters our visitor can key in for their first and last names to a maximum of 45 characters each. &lt;/li&gt;    &lt;li&gt;Both first and last name are required. So when either are omitted we have to display appropriate and informative warning messages and also highlight the offending data entry fields. &lt;/li&gt;    &lt;li&gt;The list of names displayed should be rendered to the browser in a case-insensitive manner. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;GuestBook Requirements – GUI&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Good! We’ve succinctly defined our business rules but we haven’t decided what GuestBook should actually look like. My budget for the project is zero so I can’t hire a professional graphic artist. Therefore, I’ve enlisted the assistance of Vincent Van Gosh, a friend of mine, to work up an image of the page. Below is what he came up with. Nothing fancy, mind you (so what do you expect to get for free these days, anyway?) but it will serve our purpose.&lt;/p&gt;  &lt;p&gt;&lt;a href="https://lh3.googleusercontent.com/-J_T3jQtnIwQ/TYEjEYO4LJI/AAAAAAAAAcY/y3Nx3E7sBlU/s1600/2011-03-16+16h44_45_thumb%255B3%255D"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" border="0" src="https://lh3.googleusercontent.com/-J_T3jQtnIwQ/TYEjEYO4LJI/AAAAAAAAAcY/y3Nx3E7sBlU/s400/2011-03-16+16h44_45_thumb%255B3%255D" width="244" height="218" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;As you can see from the above image, the GuestBook application consists of a single page on which are the following sections:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;A header section display the Wicket graphic and the title. &lt;/li&gt;    &lt;li&gt;Below the header section is a form which visitors use to enter their first and last names to sign the guest book. Both fields are required and each field is limited to a maximum of 45 characters. The form also contains two buttons, one for submitting the form and one for clearing out its contents. &lt;/li&gt;    &lt;li&gt;Below the form section is a list of the names of the visitors who have previously signed our guest book. The first and last names are in ascending order by first and then last name and collated in a case-insensitive manner. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;b&gt;GuestBook Requirements – Data&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;We can’t display the list of names of our visitors if we don’t store them somewhere. So here are the requirements for storing visitor data.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;We will use the popular open source MySQL relational database as our datastore. &lt;/li&gt;    &lt;li&gt;The name of the table in which we will store the data is going to be called ‘guest’. &lt;/li&gt;    &lt;li&gt;The schema for the quest table defines three columns: 1) id (an auto increment identity column); 2) firstName (a variable character column able to store up to 45 characters) and 3) lastName (like firstName, a variable character column able to store up to 45 characters). &lt;/li&gt;    &lt;li&gt;The firstName and lastName columns should be defined so that they use case-insensitive collation. Remember, above we stated that the list of names displayed should be rendered in a case-insensitive manner. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;GuestBook Architecture&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;So far we have expressed the purpose for GuestBook, we defined its business rules, worked up a graphic for what we want the Web page to look like and defined the data requirements. But we haven’t touched on what architecture we will use for actually developing GuestBook, so lets define that now.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;GuestBook will be developed as a browser-based Web application. &lt;/li&gt;    &lt;li&gt;We will use Oracle GlassFish as the Java EE6 application server. &lt;/li&gt;    &lt;li&gt;For our presentation tier we will use the Wicket Web framework. &lt;/li&gt;    &lt;li&gt;MySQL will be used for the datastore tier. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So our architecture stack looks something like the following:&lt;/p&gt;  &lt;table style="width: 405px" border="1" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="403" align="center"&gt;&lt;span style="color: red"&gt;&lt;strong&gt;Browser&lt;/strong&gt;&lt;/span&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="403" align="center"&gt;&lt;strong&gt;&lt;span style="color: lime"&gt;Java EE6/GlassFish&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="403" align="center"&gt;         &lt;table style="width: 396px" border="1" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;             &lt;tr&gt;               &lt;td valign="top" width="197" align="center"&gt;&lt;strong&gt;&lt;span style="color: blue"&gt;Wicket&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;                &lt;td valign="top" width="198" align="center"&gt;&lt;strong&gt;&lt;span style="color: blue"&gt;MySQL&lt;/span&gt;&lt;/strong&gt;&lt;/td&gt;             &lt;/tr&gt;           &lt;/tbody&gt;&lt;/table&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;strong&gt;IDE&lt;/strong&gt;&lt;/p&gt; &lt;strong&gt;&lt;/strong&gt;  &lt;p&gt;I originally thought about also using Eclipse in these articles but in all honesty the Netbeans tooling is far superior to that of Eclipse when it comes to targeting Java EE and GlassFish. In my opinion, Eclipse is a great IDE. In fact, I use it very often and I am very comfortable and productive with it but I’ve come to recognize that both IDEs have their strengths and weaknesses and so I’ve opted to use NetBeans for these articles.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What you will need to complete GuestBook&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Following is a list of items that I will use to complete the GuestBook application. If you intend to code along with me (and I certainly hope that you do) then you will need to have these items installed on your development machine. The list provides links to each item’s home page and download page.&lt;/p&gt;  &lt;table style="width: 981px" border="1" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="108" align="center"&gt;&lt;span style="background-color: #cccccc; color: black"&gt;ITEM&lt;/span&gt;&lt;/td&gt;        &lt;td valign="top" width="218" align="center"&gt;&lt;span style="background-color: #cccccc; color: black"&gt;DESCRIPTION&lt;/span&gt;&lt;/td&gt;        &lt;td valign="top" width="194" align="center"&gt;         &lt;div align="center"&gt;&lt;span style="background-color: #cccccc"&gt;HOME PAGE&lt;/span&gt;&lt;/div&gt;       &lt;/td&gt;        &lt;td valign="top" width="341" align="center"&gt;&lt;span style="background-color: #cccccc"&gt;DOWNLOAD PAGE&lt;/span&gt;&lt;/td&gt;        &lt;td valign="top" width="118" align="center"&gt;&lt;span style="background-color: #cccccc; color: black"&gt;COMMENT&lt;/span&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="107"&gt;         &lt;div align="left"&gt;&lt;span style="font-size: x-small"&gt;&lt;span style="color: #cccccc"&gt;&lt;span style="background-color: white"&gt;&lt;span style="color: black"&gt;MySQL Community Server&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;       &lt;/td&gt;        &lt;td valign="top" width="216"&gt;&lt;span style="font-size: x-small"&gt;&lt;span style="color: black"&gt;Open Source Database&lt;/span&gt; &lt;/span&gt;&lt;/td&gt;        &lt;td valign="top" width="196"&gt;&lt;a href="http://www.mysql.com/"&gt;&lt;span style="color: blue; font-size: x-small"&gt;http://www.mysql.com/&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="342"&gt;&lt;a href="http://www.mysql.com/downloads/"&gt;&lt;span style="color: blue; font-size: x-small"&gt;http://www.mysql.com/downloads/&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="118"&gt;&lt;span style="color: black; font-size: x-small"&gt;Version 5.5.10 at the time of writing this article &lt;/span&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="107"&gt;&lt;span style="font-size: x-small"&gt;MySQL Workbench&lt;/span&gt;&lt;/td&gt;        &lt;td valign="top" width="215"&gt;&lt;span style="font-size: x-small"&gt;To design, manage and document database schemata&lt;/span&gt;&lt;/td&gt;        &lt;td valign="top" width="196"&gt;&lt;a href="http://www.mysql.com/"&gt;&lt;span style="color: blue; font-size: x-small"&gt;http://www.mysql.com/&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="342"&gt;&lt;a href="http://www.mysql.com/downloads/"&gt;&lt;span style="color: blue; font-size: x-small"&gt;http://www.mysql.com/downloads/&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="118"&gt;&lt;span style="font-size: x-small"&gt;This is totally optional as I will provide the database schemas for you. But it is a very good tool to have so I thought I’d mention it here.            &lt;br /&gt;            &lt;br /&gt;Version 5.2.33b at the time of writing this article&lt;/span&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="107"&gt;&lt;span style="font-size: x-small"&gt;NetBeans&lt;/span&gt;&lt;/td&gt;        &lt;td valign="top" width="215"&gt;&lt;span style="font-size: x-small"&gt;Open Source Java IDE&lt;/span&gt;&lt;/td&gt;        &lt;td valign="top" width="196"&gt;&lt;a href="http://netbeans.org/"&gt;&lt;span style="color: blue; font-size: x-small"&gt;http://netbeans.org/&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="342"&gt;&lt;a href="http://netbeans.org/downloads/index.html"&gt;&lt;span style="color: blue; font-size: x-small"&gt;http://netbeans.org/downloads/index.html&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="118"&gt;&lt;span style="font-size: x-small"&gt;Version 6.9.1 at the time of writing this article.&lt;/span&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="107"&gt;&lt;span style="font-size: x-small"&gt;Wicket Plugin For NetBeans&lt;/span&gt;&lt;/td&gt;        &lt;td valign="top" width="220"&gt;&lt;span style="font-size: x-small"&gt;Adds wicket support to the NetBeans IDE&lt;/span&gt;&lt;/td&gt;        &lt;td valign="top" width="200"&gt;&lt;a href="http://netbeans.org/"&gt;&lt;span style="color: blue; font-size: x-small"&gt;http://netbeans.org/&lt;/span&gt;&lt;/a&gt;&lt;/td&gt;        &lt;td valign="top" width="345"&gt;&lt;span style="color: blue; font-size: x-small"&gt;&lt;a href="http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=3586"&gt;&lt;font color="#0000ff"&gt;http://plugins.netbeans.org/PluginPortal/                &lt;br /&gt;faces/PluginDetailPage.jsp?pluginid=3586&lt;/font&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;        &lt;td valign="top" width="124"&gt;&lt;span style="font-size: x-small"&gt;Supports NetBeans 6.9.1 at the time of writing this article&lt;/span&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Please download and install the items listed above. In the next article, Java EE6 &amp;amp; Wicket - Article #2, we will focus on setting up the GuestBook MySQL database. We will define the database schema for the GuestBook application and apply it to create the guest table. We will also load the guest table with data that will be used during testing.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-6080995484876539178?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/6080995484876539178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/6080995484876539178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/6080995484876539178'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html' title='Java EE6 &amp;amp; Wicket - Article #1 - Requirements, Architecture &amp;amp; Resources'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh3.googleusercontent.com/-J_T3jQtnIwQ/TYEjEYO4LJI/AAAAAAAAAcY/y3Nx3E7sBlU/s72-c/2011-03-16+16h44_45_thumb%255B3%255D' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-9171087856679734582</id><published>2011-03-15T09:57:00.001-04:00</published><updated>2011-03-31T13:23:51.188-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='javaee'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Java EE6 &amp; Wicket</title><content type='html'>&lt;p&gt;&lt;b&gt;Back To The Future&lt;/b&gt;&lt;b&gt;      &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;It's been a while since I've written about Java EE &amp;amp; Wicket. My last articles on the subject covered Java EE5 and EJB dependency injection (DI) in Wicket objects. Since I wrote those articles Java EE6 has been released along with compliant EE6 servers like GlassFish, Wicket has seen a number of point updates and the popular NetBeans IDE has upgraded its tooling.&lt;/p&gt;  &lt;p&gt;The most interesting new feature that EE6 provides, at least from my perspective, is EAR-less deployments. With EE5 you often needed to resort to having to implement an EAR module and tie all the sub projects into that. Java EE6 eliminates that requirement - though EARs are still supported – which greatly simplifies creating Java EE6 applications and NetBeans supports creating EAR-less projects.&lt;/p&gt;  &lt;p&gt;It would be impossible to cover all the new features that EE6 provides so I’ve decided to write a few articles covering my favorite Java related topics – EE and Wicket. In my opinion NetBeans has much better tooling and plugin support for dynamic Web projects that use Wicket so I will also discuss its tooling support for EE6 and Wicket.&lt;/p&gt;  &lt;p&gt;I will use a simple Guest Book application as the context for the articles and I will try to keep each article small but well focused so as not to overwhelm you with too much information all at once. As I see it now the topics for each article will be something along the lines of the following:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;An introduction presenting the requirements for the GuestBook Web application as well as discuss its architecture. I will also identify those pieces of the architecture that you will need to download and install on your development box. &lt;/li&gt;    &lt;li&gt;Creating a backing datastore and schema using MySQL – here I’ll discuss creating the database that will be used as the backing data store for the Guest Book Web application. &lt;/li&gt;    &lt;li&gt;Generating the Guest Book Web application using NetBeans and deploying it to GlassFish. We will also add all the required jar files to the project. &lt;/li&gt;    &lt;li&gt;Adding JPA Persistence support to the project. &lt;/li&gt;    &lt;li&gt;Building out the Guest Book Web application using NetBeans and testing it. &lt;/li&gt;    &lt;li&gt;A wrap up. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;This is what the finished Guest Book Application will look like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_XzLrgIoZ_TU/TYEjEABG_eI/AAAAAAAAAcU/CnuF8XoUO78/s1600-h/2011-03-16%2016h44_45%5B5%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-03-16 16h44_45" border="0" alt="2011-03-16 16h44_45" src="http://lh3.ggpht.com/_XzLrgIoZ_TU/TYEjEYO4LJI/AAAAAAAAAcY/Hs8_g2uL5mA/2011-03-16%2016h44_45_thumb%5B3%5D.png?imgmax=800" width="244" height="218" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Stay tuned! I’ll be rolling these articles out over the next few weeks so please check back frequently.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Updated 3/31/2011&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Here’s a list of urls for the 6 articles in this series:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-1-requirements.html&lt;/font&gt;&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-2-creating.html&lt;/font&gt;&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-3-generating.html&lt;/font&gt;&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-4-adding-jpa.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-4-adding-jpa.html&lt;/font&gt;&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-5building-out.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-5building-out.html&lt;/font&gt;&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-6-wrap-up.html"&gt;&lt;font color="#0000ff"&gt;http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket-article-6-wrap-up.html&lt;/font&gt;&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-9171087856679734582?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/9171087856679734582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/9171087856679734582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/9171087856679734582'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2011/03/java-ee6-wicket.html' title='Java EE6 &amp;amp; Wicket'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_XzLrgIoZ_TU/TYEjEYO4LJI/AAAAAAAAAcY/Hs8_g2uL5mA/s72-c/2011-03-16%2016h44_45_thumb%5B3%5D.png?imgmax=800' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-329609027544075239</id><published>2010-11-28T10:07:00.000-05:00</published><updated>2010-11-28T10:07:10.186-05:00</updated><title type='text'>I-Emote on Google AppEngine</title><content type='html'>&lt;a href="http://i-emote.appspot.com/"&gt;I-Emote&lt;/a&gt; is a social Web application I am writing that allows users to create posts that can be associated with Web based content such as other Web sites and YouTube videos. Members can add their own comments and indicate they 'like' a post or comment.&lt;br /&gt;
&lt;br /&gt;
Each member has their own profile page on which other members may view their latest posts as well as any personal information the member wishes to share. Profile pages also provide the means to subscribe to members' posts as well as unsubscribing.&lt;br /&gt;
&lt;br /&gt;
When I set out to write I-Emote I did so as an academic study of what it takes to create a social Web site as well as target Google's cloud infrastructure - App Engine - and as such it is a work in progress; there are numerous features that it still lacks and that I am eager to implement such as email and SMS notifications, general message broadcasting and more member-centric features such as picture albums. I will eventually fill in the gaps as time permits. I intend to use what I have learned about writing a social Web site in other projects that I am and will be working on to provide them with some light weight social Web features such as commenting, fan-out and profile pages.&lt;br /&gt;
&lt;br /&gt;
Below are a few screen shots that I hope you find interesting:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPJsdhf983I/AAAAAAAAAXE/8eGDifGCMYA/s1600/2010-11-28+09h40_35.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPJsdhf983I/AAAAAAAAAXE/8eGDifGCMYA/s1600/2010-11-28+09h40_35.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TPJsebvjfII/AAAAAAAAAXI/RHzt1NpmZy8/s1600/2010-11-28+09h41_21.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TPJsebvjfII/AAAAAAAAAXI/RHzt1NpmZy8/s1600/2010-11-28+09h41_21.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPJse-R5tYI/AAAAAAAAAXM/o35JafNu63o/s1600/2010-11-28+09h41_58.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPJse-R5tYI/AAAAAAAAAXM/o35JafNu63o/s1600/2010-11-28+09h41_58.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPJsfsakeNI/AAAAAAAAAXQ/OoQxiuvFCrI/s1600/2010-11-28+09h44_32.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPJsfsakeNI/AAAAAAAAAXQ/OoQxiuvFCrI/s1600/2010-11-28+09h44_32.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPJvMqJe7FI/AAAAAAAAAXY/7I0Mf78pLeM/s1600/2010-11-28+09h45_38.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPJvMqJe7FI/AAAAAAAAAXY/7I0Mf78pLeM/s1600/2010-11-28+09h45_38.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-329609027544075239?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/329609027544075239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2010/02/gaelyk-on-google-appengine.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/329609027544075239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/329609027544075239'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2010/02/gaelyk-on-google-appengine.html' title='I-Emote on Google AppEngine'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPJsdhf983I/AAAAAAAAAXE/8eGDifGCMYA/s72-c/2010-11-28+09h40_35.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-3420680766115332350</id><published>2010-11-18T08:31:00.071-05:00</published><updated>2010-12-28T08:35:24.720-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='GWT'/><category scheme='http://www.blogger.com/atom/ns#' term='app-engine'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='google-app-engine'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='lmv'/><title type='text'>Screenshots of Love My Vehicle On The Web</title><content type='html'>A number of years back I had written a desktop software package for tracking and managing the maintenance of vehicles and it was called Love My Vehicle. The software was well received and it managed to attract a rather large &amp;amp; loyal following of paid customers and had won numerous awards from various software rating groups as well as user groups. The application was written for Windows using Microsoft C++ and the MFC framework.&lt;br /&gt;
&lt;br /&gt;
Many things have changed since I originally wrote that package. Most noticeably, the Web has become the preferred target for delivering services and value to customers. The Web's influence can be said to have changed the landscape of application development and delivery. Cloud based Web services have also contributed to the changing landscape by offering software developers the opportunity to deliver services to their customers without the need to invest in infrastructure and by also providing solutions for wide scalability and resiliency. Numerous cloud options now exist including Amazon's EC2 and Google's App Engine for which I have written numerous applications .&lt;br /&gt;
&lt;br /&gt;
About six months ago one of my customers contacted me about migrating her licenses for Love My Vehicle to new computers her company had purchased. Unfortunately, I wasn't able to offer her any assistance because I had lost the source code to the application a few years back (which could serve as the subject for its own article). As a result I decided to create a modern version of the software targeting, of course, the Web and the cloud and as I already had practical hands on experience with App Engine I opted to target Google's cloud.&lt;br /&gt;
&lt;br /&gt;
One of the early lesson I learned about targeting App Engine is that Google's limit on the amount of time allotted to each HTTP request severely limits what I can and cannot do on their servers. I learned that the best approach was to limit each request to retrieving and updating data only and to do all HTML rendering on the browser using Ajax and DOM manipulation. The added benefit of this approach is the RIA experience for the user.&lt;br /&gt;
&lt;br /&gt;
The applications I already have written for App Engine all use Java and Groovy on the servers for processing Ajax requests and jQuery on the browser for DOM manipulation. The shortcoming to this approach is that client side development tends to be tedious and you lose the benefits provided by compilers and IDEs, especially catching coding errors early and code refactoring. I wondered what other options I had that would offer the same set of resources on the client that I had become accustomed to having on the server side of development. Enter Google's GWT.&lt;br /&gt;
&lt;br /&gt;
GWT is Google's pure Java approach for developing rich internet applications (RIA) and it uses a novel approach of compiling Swing like Java code to native Javascript targeting IE, FF, Chrome and the Safari browsers. Using GWT lets you develop both your servlets and client side code in Java without having to give up your favorite IDE which in my case is Eclipse.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;In the course of two months and coding in my spare time I have manged to be very productive using GWT. After studying and learning its "ins and outs" I have already managed to put together a nice little prototype of Love My Vehicle running on Google's App Engine cloud. This isn't a clone of the older application but rather a complete rewrite with new features and of course, Web based. Here's the link: &lt;a href="http://lovemyvehicle.appspot.com/"&gt;http://lovemyvehicle.appspot.com/&lt;/a&gt;. Though early in its life cycle and sans source code for the original product, I am applying my knowledge of the original software's functionality to build out the new product which will support the popular 'freemium' subscription model.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;As I progress  in adding and refining functionality I will post updates here. I also intend to write new  articles specifically relating to its development that will also include GWT and App Engine.&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Screen shots of early prototype&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;&lt;a href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TOUhtfTQyQI/AAAAAAAAAVk/xY28oheCB_A/s1600/2010-11-18+07h52_33.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TOUhtfTQyQI/AAAAAAAAAVk/xY28oheCB_A/s1600/2010-11-18+07h52_33.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TOUiDsFRfjI/AAAAAAAAAVo/9B97Fkarvac/s1600/2010-11-18+07h54_09.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TOUiDsFRfjI/AAAAAAAAAVo/9B97Fkarvac/s1600/2010-11-18+07h54_09.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TOUiS_kkJUI/AAAAAAAAAVs/Zo_JMgt9lFQ/s1600/2010-11-18+07h55_20.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TOUiS_kkJUI/AAAAAAAAAVs/Zo_JMgt9lFQ/s1600/2010-11-18+07h55_20.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TOUgFM2UJGI/AAAAAAAAAVg/YTR4YHd7vuw/s1600/2010-11-18+07h43_14.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TOUgFM2UJGI/AAAAAAAAAVg/YTR4YHd7vuw/s1600/2010-11-18+07h43_14.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TOUjDIjFhpI/AAAAAAAAAV0/G5P29uhP_-k/s1600/2010-11-18+07h58_37.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TOUjDIjFhpI/AAAAAAAAAV0/G5P29uhP_-k/s1600/2010-11-18+07h58_37.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TOUjWbhJO1I/AAAAAAAAAV4/pgbEKSYrxbU/s1600/2010-11-18+07h59_52.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TOUjWbhJO1I/AAAAAAAAAV4/pgbEKSYrxbU/s1600/2010-11-18+07h59_52.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TOUjp9ISKFI/AAAAAAAAAV8/29hOmPqKkzY/s1600/2010-11-18+08h01_00.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TOUjp9ISKFI/AAAAAAAAAV8/29hOmPqKkzY/s1600/2010-11-18+08h01_00.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Updated 11/27/2010&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Since posting the original article I've made numerous changes to some of the views and I've also implemented a couple of new views, all of which are included below. But first, allow me to make a few obvious but none the less important observations about application development in general.&lt;br /&gt;
&lt;br /&gt;
One of the keys to successful development IMHO is the constant refinement of concepts and ideas. No matter how good a first implementation is there is always room for improvement. As concepts and ideas materialize and as the complexity of the application increases it is very important to review your implementations frequently, looking for ways to improve them. In addition, as development progresses you can sometimes find that you need to reuse an implementation but in its current state it is tightly bound to a single point of use.&lt;br /&gt;
&lt;br /&gt;
IDE refactoring support makes this repetitive cycle of coding and refinement manageable and Eclipse, my preferred choice of IDE, shines in this area saving me literally hours compared to what it would have taken me to manually make all the modifications up to this point.&lt;br /&gt;
&lt;br /&gt;
So, if your current IDE doesn't shine in its refactoring support look to upgrade to a better IDE. JetBrains, Eclipse and Netbeans all provide excellent support for refactoring code and of the 3 only JetBrains requires a paid license for non open source projects.&lt;br /&gt;
&lt;br /&gt;
With that little tidbit out of the way here are the screen shots I promised:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;S&lt;/b&gt;&lt;b&gt;creen shots of modified views from early prototype&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPEuTVH9ubI/AAAAAAAAAWk/Xf6x_9vrqHU/s1600/2010-11-27+10h11_41.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPEuTVH9ubI/AAAAAAAAAWk/Xf6x_9vrqHU/s1600/2010-11-27+10h11_41.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TPEu4RF0DvI/AAAAAAAAAWo/puCC91ZrzuY/s1600/2010-11-27+10h54_14.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TPEu4RF0DvI/AAAAAAAAAWo/puCC91ZrzuY/s1600/2010-11-27+10h54_14.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TPEu45CCfUI/AAAAAAAAAWs/vA1SDxpe4jg/s1600/2010-11-27+10h57_56.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TPEu45CCfUI/AAAAAAAAAWs/vA1SDxpe4jg/s1600/2010-11-27+10h57_56.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPEu5Yr1VEI/AAAAAAAAAWw/fbJwwWxXXlk/s1600/2010-11-27+11h00_44.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPEu5Yr1VEI/AAAAAAAAAWw/fbJwwWxXXlk/s1600/2010-11-27+11h00_44.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Screen shots of recently added views from early prototype&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TPEvbuCn3FI/AAAAAAAAAW0/bvAH-GjXld8/s1600/2010-11-27+11h07_40.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TPEvbuCn3FI/AAAAAAAAAW0/bvAH-GjXld8/s1600/2010-11-27+11h07_40.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPEvcPoolWI/AAAAAAAAAW4/Oe-WYl1tniQ/s1600/2010-11-27+11h08_32.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPEvcPoolWI/AAAAAAAAAW4/Oe-WYl1tniQ/s1600/2010-11-27+11h08_32.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TPEvcSgwfmI/AAAAAAAAAW8/vdAUowPZhwM/s1600/2010-11-27+11h09_00.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TPEvcSgwfmI/AAAAAAAAAW8/vdAUowPZhwM/s1600/2010-11-27+11h09_00.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPEvdkv-pNI/AAAAAAAAAXA/VJU_1tyGv1w/s1600/2010-11-27+11h09_25.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPEvdkv-pNI/AAAAAAAAAXA/VJU_1tyGv1w/s1600/2010-11-27+11h09_25.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Updated 12/5/2010&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Since my last update I've done a lot more refactoring, made some improvements and changes to the the existing views, implemented the Parts, Fluids and Suppliers views and I've added one new view, Notifications, to the Manage sub menu. The data displayed in the following screen shots is bogus of course and is for testing purposes only, mainly to verify that my sorting routines are working correctly. Screen shots follow:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPvKcR1PHlI/AAAAAAAAAYc/UssctqX4Nxc/s1600/2010-12-05+12h22_01.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPvKcR1PHlI/AAAAAAAAAYc/UssctqX4Nxc/s1600/2010-12-05+12h22_01.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPvH2XUGo-I/AAAAAAAAAYA/0R8lWqk8xqc/s1600/2010-12-05+11h56_32.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPvH2XUGo-I/AAAAAAAAAYA/0R8lWqk8xqc/s1600/2010-12-05+11h56_32.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPpZhJ-DQbI/AAAAAAAAAXk/9g6_d1-fvZo/s1600/2010-12-04+09h56_00.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPpZhJ-DQbI/AAAAAAAAAXk/9g6_d1-fvZo/s1600/2010-12-04+09h56_00.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPvMdjxxWMI/AAAAAAAAAYg/gAL6V8EZm04/s1600/2010-12-05+12h26_52.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPvMdjxxWMI/AAAAAAAAAYg/gAL6V8EZm04/s1600/2010-12-05+12h26_52.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPvIXfPmJaI/AAAAAAAAAYI/-ESjfEHFbs0/s1600/2010-12-05+11h59_38.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPvIXfPmJaI/AAAAAAAAAYI/-ESjfEHFbs0/s1600/2010-12-05+11h59_38.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPpckDG8ceI/AAAAAAAAAXs/UcHRpYZGVMU/s1600/2010-12-04+10h13_08.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPpckDG8ceI/AAAAAAAAAXs/UcHRpYZGVMU/s1600/2010-12-04+10h13_08.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TPpckdKNntI/AAAAAAAAAXw/Mknx64WqLCo/s1600/2010-12-04+10h13_25.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TPpckdKNntI/AAAAAAAAAXw/Mknx64WqLCo/s1600/2010-12-04+10h13_25.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPvImi_cEnI/AAAAAAAAAYM/L9fi6PaMh2k/s1600/2010-12-05+12h04_01.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPvImi_cEnI/AAAAAAAAAYM/L9fi6PaMh2k/s1600/2010-12-05+12h04_01.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPpcl6T9cYI/AAAAAAAAAX4/R8s8u9Cw-2E/s1600/2010-12-04+10h15_31.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPpcl6T9cYI/AAAAAAAAAX4/R8s8u9Cw-2E/s1600/2010-12-04+10h15_31.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TPpcmVeKxnI/AAAAAAAAAX8/DwD-KVmi6d8/s1600/2010-12-04+10h15_51.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TPpcmVeKxnI/AAAAAAAAAX8/DwD-KVmi6d8/s1600/2010-12-04+10h15_51.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPvJQWX86oI/AAAAAAAAAYQ/Qlvt8fBSgxQ/s1600/2010-12-05+12h05_26.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/TPvJQWX86oI/AAAAAAAAAYQ/Qlvt8fBSgxQ/s1600/2010-12-05+12h05_26.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPvJTC0MnjI/AAAAAAAAAYU/k0jQ1v71cgY/s1600/2010-12-05+12h06_06.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPvJTC0MnjI/AAAAAAAAAYU/k0jQ1v71cgY/s1600/2010-12-05+12h06_06.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPvJTeFiCmI/AAAAAAAAAYY/Ktoy3syOHl0/s1600/2010-12-05+12h06_31.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TPvJTeFiCmI/AAAAAAAAAYY/Ktoy3syOHl0/s1600/2010-12-05+12h06_31.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Updated 12/19/2010&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Complex Web 2.0 pages are highly dynamic and require a lot of DOM manipulation for adding, removing, hiding and showing page elements in response to the user's actions; that's how they mimic desktop applications providing a similar rich user experience.&lt;br /&gt;
&lt;br /&gt;
Love My Vehicle's Misc. Purchases View is one such example of a complex, highly dynamic page that responds to the user's actions by manipulating the DOM accordingly. The view supports the display of a document non editing view of a purchase which has numerous areas on which the user can click on to manipulate such purchase related items as purchase line items and sales tax.&lt;br /&gt;
&lt;br /&gt;
For example, when the user clicks the Add Purchase Item button DOM manipulation is used to display an editor that allows the input of a purchase item. The user can save their input by clicking the editor's Save Purchase Item button or they can cancel the operation by clicking the editor's Cancel button. If they click the Save Purchase Item button the information they entered is first validated and if it is valid the DOM is again manipulated to display a document non editing view of the line item entry. If the information fails validation then the line item editor displays an error message which provides feedback to the user prompting them to correct the data.&lt;br /&gt;
&lt;br /&gt;
The same line item editor also supports editing of an existing purchase line item which would be the case if the user is editing an existing purchase or a line item they previously entered in a new purchase.&lt;br /&gt;
&lt;br /&gt;
Sales tax works similarly to the purchase line item editor supporting both a document non editing view and an editing view.&lt;br /&gt;
&lt;br /&gt;
Whenever the users saves their data in either the line item editor or the sales tax editor the page recalculates the net and gross amounts for the purchase.&lt;br /&gt;
&lt;br /&gt;
In the coming weeks I intend to publish an article dedicated to my  approach to developing these types of highly dynamic pages and of course  I will focus on using GWT to implement them. It is possible that this will be a multi part article as the topic requires a lot of detail and I think would be easier to consume if it wasn't all tossed out at you at one time.&lt;br /&gt;
&lt;br /&gt;
I have added some screen shots below of the views that I described above as well as a screen shot of the Purchase view which shows a list of all purchases as well as showing a document view of the selected purchase.&lt;br /&gt;
&lt;br /&gt;
I hope you have found this latest update interesting and as always, feel free to provide your feedback.&lt;br /&gt;
&lt;br /&gt;
Have a very happy holiday and new year.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TQ44WDQwGsI/AAAAAAAAAYk/mjZe1PUMI3U/s1600/2010-12-19+10h47_41.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TQ44WDQwGsI/AAAAAAAAAYk/mjZe1PUMI3U/s1600/2010-12-19+10h47_41.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TQ44Wq5b9II/AAAAAAAAAYo/NYgMj3eZJk0/s1600/2010-12-19+10h55_37.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TQ44Wq5b9II/AAAAAAAAAYo/NYgMj3eZJk0/s1600/2010-12-19+10h55_37.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TQ45uWaF1zI/AAAAAAAAAY0/zxXeQC-mpY4/s1600/2010-12-19+11h55_54.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/TQ45uWaF1zI/AAAAAAAAAY0/zxXeQC-mpY4/s1600/2010-12-19+11h55_54.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TQ48tzqvSII/AAAAAAAAAY8/BJD5kglUBy0/s1600/2010-12-19+12h09_05.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/TQ48tzqvSII/AAAAAAAAAY8/BJD5kglUBy0/s1600/2010-12-19+12h09_05.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Updated 12/19/2010&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In real life one rarely gets the opportunity to do things over but software development is an exception. After implementing the Purchase views I realized that I had failed to provide the user with a report view of a purchase. What do I mean when I say a report view? A report view is any view of data that when viewed looks like a well laid out report and as close to the real life document that it is supposed to represent. An invoice is an example of a report view with a header, line items, and a summary. A&lt;b&gt; &lt;/b&gt;purchase is also an example and is very similar to an invoice in that it also has a header, line items and a summary.&lt;br /&gt;
&lt;br /&gt;
Business applications, which Love My Vehicle really is when you get down to it, usually have to provide a lot of report views and implementing them is often time consuming because of the detail required to get the views to look like real documents. I made two passes at implementing the Purchase report view, one using a div only approach and one using tables. In the end I chose the tables approach because it was more straight forward and it allowed me to use GWT's excellent support for table row and cell generation.&lt;br /&gt;
&lt;br /&gt;
The following is a screen shot of a Purchase report view. Besides providing the user with a report view of what a Purchase document should look like, it also provides the user with the ability to edit and delete the backing purchase data:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TRnm-NZ4qaI/AAAAAAAAAZE/Pv6w1TQP_tQ/s1600/2010-12-28+08h30_23.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/TRnm-NZ4qaI/AAAAAAAAAZE/Pv6w1TQP_tQ/s1600/2010-12-28+08h30_23.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-3420680766115332350?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/3420680766115332350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2010/11/screenshots-of-love-my-vehicle-on-web.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/3420680766115332350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/3420680766115332350'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2010/11/screenshots-of-love-my-vehicle-on-web.html' title='Screenshots of Love My Vehicle On The Web'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_XzLrgIoZ_TU/TOUhtfTQyQI/AAAAAAAAAVk/xY28oheCB_A/s72-c/2010-11-18+07h52_33.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-5903384674601804296</id><published>2010-02-03T10:41:00.010-05:00</published><updated>2010-02-16T20:36:11.138-05:00</updated><title type='text'>"Hey Larry"</title><content type='html'>As you probably know, Oracle has begun its consolidation of the assets it has obtained from its purchase of Sun Microsystems. Yesterday I received an email notifying me that Oracle has pulled the plug on Kenai.com. You can interpret this as you see fit but in my opinion this is a mistake for a number of reasons, not least of which is the message it sends to developers.&lt;br /&gt;
&lt;br /&gt;
So "Hey Larry" will be my channel for commenting on both the good and the not so good steps that Oracle takes in regard to those Sun assets which we developers have come to rely on. To start things off, here's the first "Hey Larry" entry...&lt;br /&gt;
&lt;br /&gt;
02/03/2010&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/S2rGxB4bBjI/AAAAAAAAARk/3dYZAO7ndEg/s1600-h/thumbs_down.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/S2rGxB4bBjI/AAAAAAAAARk/3dYZAO7ndEg/s320/thumbs_down.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Hey Larry,&lt;br /&gt;
I just heard that you are shutting down Kenai.com. Why? You don't think it is an asset for developers to have a Kenai.com service as a resource? You don't value the good will a resource like Kenai.com generates with your developer community? What else are you going to "shutdown"? Netbeans, MySql, Java, OpenOffice.org, etc.? I was enthusiastic about the Oracle/Sun deal but I feared something like this would result. I guess my fears were justified. Hey Larry ... don't be a jerk with your developer community. It might come back to haunt ya!&lt;br /&gt;
&lt;br /&gt;
02/04/2010&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/S2rHFFjC9CI/AAAAAAAAARs/uQE427-qm9Q/s1600-h/thumbs_up.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/S2rHFFjC9CI/AAAAAAAAARs/uQE427-qm9Q/s320/thumbs_up.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Hey Larry,&lt;br /&gt;
I like what I heard in this &lt;a href="http://oracle.com.edgesuite.net/ivt/4000/8104/9236/12627/lobby_external_flash_clean_480x360/default.htm" target="_blank"&gt;web cast&lt;/a&gt;, especially what you are promising for Netbeans and Netbeans.org. Keeping the Netbeans devevelopment team intact is smart as is sharing between the 3 IDE platform groups&lt;br /&gt;
&lt;br /&gt;
02/07/2010&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/S2rHFFjC9CI/AAAAAAAAARs/uQE427-qm9Q/s1600-h/thumbs_up.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/S2rHFFjC9CI/AAAAAAAAARs/uQE427-qm9Q/s320/thumbs_up.png" /&gt;&lt;/a&gt;Hey Larry,&lt;/div&gt;I just read your clarification regarding your plans for Kenai.com (see below) which I received yesterday. This will, I am sure, be very well received by your developer community. I can hear their collective sigh of relief. It doesn't matter why the 180 on Kenai.com but my naturally curious nature tells me that the negative reaction to your original announcement played 'something' of a role. That you listened and reevaluated and came to what can only be called a very smart decision demonstrates a resolve to embrace your developer community. Good move!&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;blockquote&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;span style="font-size: x-small;"&gt;Gentlepeople,&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;In an effort to get information out to the Kenai community quickly, while trying to manage the integration of our two companies, I think we did a poor job at communicating our plans for Kenai.com to you. I would like to remedy that now.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;Our strategy is simple. We don't believe it makes sense to continue investing in multiple hosted development sites that are basically doing the same thing. Our plan is to shut down kenai.com and focus our efforts on java.net as the hosted development community.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;We are in the process of migrating java.net to the kenai technology. This means that any project currently hosted on kenai.com will be able to continue as you are on java.net. We are still working out the technical details, but the goal is to make this migration as seamless as possible for the current kenai.com projects.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;So in the meantime I suggest that you stay put on kenai.com&lt;/span&gt;&lt;a class="cssButton" href="javascript:void(0)" id="publishButton" onclick="if (this.className.indexOf(&amp;quot;ubtn-disabled&amp;quot;) == -1) {var e = document['postingForm'].publish;(e.length) ? e[0].click() : e.click(); if (window.event) window.event.cancelBubble = true; return false;}" target=""&gt; &lt;/a&gt;&lt;span style="font-size: x-small;"&gt;and let us work through the details and get back to you later this month.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;Thanks for your feedback and patience.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;-Ted Farrell&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;Oracle Corporation&lt;/span&gt;&lt;/blockquote&gt;02/15/2010&lt;br /&gt;
&lt;a href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/S2rHFFjC9CI/AAAAAAAAARs/uQE427-qm9Q/s1600-h/thumbs_up.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/S2rHFFjC9CI/AAAAAAAAARs/uQE427-qm9Q/s320/thumbs_up.png" /&gt;&lt;/a&gt;Hey Larry,&lt;br /&gt;
Congratulations on &lt;a href="http://news.yahoo.com/s/ap/20100214/ap_on_sp_ot/sai_america_s_cup"&gt;winning back America's Cup&lt;/a&gt;. Outstanding!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-5903384674601804296?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/5903384674601804296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2010/02/hey-larry.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/5903384674601804296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/5903384674601804296'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2010/02/hey-larry.html' title='&quot;Hey Larry&quot;'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_XzLrgIoZ_TU/S2rGxB4bBjI/AAAAAAAAARk/3dYZAO7ndEg/s72-c/thumbs_down.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-5192246758510546469</id><published>2010-01-09T12:08:00.004-05:00</published><updated>2010-02-16T16:34:10.834-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bigtable'/><category scheme='http://www.blogger.com/atom/ns#' term='gorm'/><category scheme='http://www.blogger.com/atom/ns#' term='big-table'/><category scheme='http://www.blogger.com/atom/ns#' term='app-engine'/><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='gorm-jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='google-app-engine'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='appengine'/><title type='text'>Grails On The Google's App Engine - Grope... bump... ouch!</title><content type='html'>I thought I'd comment on some of my experiences using Grails on Google's App Engine. I am new to the App Engine and it is quite different from the typical environment provided by Java web servers. For example, it only provides limited Java support and there is no SQL database, only BigTable. Poor or missing documentation just compounds the difficulty. It is like feeling your way around in the dark - there are a lot of things you are going to bump in to. So occasionally I will update my 'bumps' here and maybe save you some of the bruises.&lt;br /&gt;
&lt;br /&gt;
Yesterday, for example, I hit a snag building an application running the grails command app-engine. This was a new problem. The app had been built and run successfully prior to this. The only difference is that I added a new domain class, a new controller and a few new views to support the new domain class to the project. The ant task that the Google App Engine SDK provides in the file config\user\ant-macros.xml was blowing up in the Datanucleus Enhancement phase  because the parameter it created to feed to the enhancer included all the classes in the war and its length exceeded the max path length allowed by Windows. I finally got around the problem by modifying the ant script to only include the application's domain objects and I was able to build and run the project again. The problem here is that this isn't documented and it literally took me hours to find a blog post that provided the solution.&lt;br /&gt;
&lt;br /&gt;
By the way, my environment is set up to use Grails 1.1.1 and not the latest 1.2 because the app-engine plugin doesn't yet support it. I am using GORM-Jpa as well.&lt;br /&gt;
&lt;br /&gt;
GORM-Jpa plugin is another point of frustration. It claims to provide dynamic finder support but in reality it only provides a very limited subset. The experience of determining what finders it actually supports is again like groping around in the dark. What I have learned so far is to limit my queries with &lt;domainclass&gt;.findWhere queries which suffice for a majority of my queries. For fringe cases I have also resorted to JPQL which I was happy to find that GORM-Jpa supports. These take the form of &lt;domainclass&gt;&amp;lt;DomainObject&amp;gt;.findAll("SELECT o FROM &lt;domainclass&gt; &lt;/domainclass&gt;&lt;/domainclass&gt;&lt;/domainclass&gt;&amp;lt;DomainObject&amp;gt; &lt;domainclass&gt;&lt;domainclass&gt;&lt;domainclass&gt;o WHERE o.x like :search",[search:'a%'] as an example. Again, no documentation and this discovery took considerable trial and error until I got it to work.&lt;/domainclass&gt;&lt;/domainclass&gt;&lt;/domainclass&gt;&lt;br /&gt;
&lt;br /&gt;
Developing for the App Engine with Grails is very fragile. A lot of things that you just take for granted in Grails just do not work or work differently. This is in part due to the immaturity of the Java App Engine api as well as Grails App Engine support. I hope to see both mature rapidly :) And thank heavens for Netbeans' Grails support. I'd have gotten nowhere fast if it weren't for Netbeans' ability to debug Grails apps.&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
So, if you have any gems you'd care to share on Grails on Google App Engine please do it here. It might save me and many others some bruises as well. And, likewise, I will share with you what I learn as I grope my way around in the darkness of Grails and Google App Engine.&lt;br /&gt;
&lt;br /&gt;
Grope... bump... ouch! Grope... bump... ouch! ...&lt;br /&gt;
&lt;br /&gt;
2/16/2010 Update&lt;br /&gt;
&lt;br /&gt;
I probably should have posted this sooner but I have given up with Grail on AppEngine and switched to &lt;a href="http://gaelyk.appspot.com/"&gt;Gaelyk&lt;/a&gt; which was purposely designed to be light weight and run on top of Google's AppEngine. It doesn't have all the bells and wistles that Grails has but you really don't need them for AppEngine. JDO/JPA just gets in the way and really doesn't fit with the BigTable database so why use it. Gaelyk comes with some very nice wrappers for Google's cloud apis and are extremely easy to work with. Startup times for Grails apps on AppEngine are horrendous and unacceptable whereas Gaelyk apps don't suffer the same startup latency. And the best thing about Gaelyk is that it is Groovy which means you still have access to litterally thousands of open source libraries at your disposal. Grails on AppEngine is like trying to run a Rolls Royce in a Nascar race where Gaelyk on AppEngine is like a speedy agile little sports car. Gaelyk support is fantastic.&amp;nbsp;Guillaume Laforge, who is the Groovy project manager and head of groovy development at SpringSource is one of Gaelyk's primary developers. He is very committed to the project and I have found him to be extremely responsive to emails posted on the Gaelyk users group.&lt;br /&gt;
&lt;br /&gt;
So the bottom lines my friends is this, if you are writing an app for a typical servelet environment then go with Grails. It is a fabulous framework. But forget about it on AppEngine, it just doesn't fit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-5192246758510546469?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/5192246758510546469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2010/01/grails-on-googles-app-engine-grope-bump.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/5192246758510546469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/5192246758510546469'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2010/01/grails-on-googles-app-engine-grope-bump.html' title='Grails On The Google&apos;s App Engine - Grope... bump... ouch!'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-539034924385143907</id><published>2009-12-26T13:44:00.009-05:00</published><updated>2009-12-28T11:19:15.297-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UIComposer'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='UIComposerTestApp'/><category scheme='http://www.blogger.com/atom/ns#' term='project_kenai'/><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='kenai'/><title type='text'>UIComposer On Project Kenai</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SzZD2C17XOI/AAAAAAAAAQ4/gKTJyKBOMZ4/s1600-h/greenshot_2009-12-25_16-21-09.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SzZD2C17XOI/AAAAAAAAAQ4/gKTJyKBOMZ4/s640/greenshot_2009-12-25_16-21-09.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;UIComposer v0.4a Now On Project Kenai&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I have created a new project on &lt;a href="http://kenai.com/"&gt;Project Kenai&lt;/a&gt; to house &lt;a href="http://kenai.com/projects/uicomposer"&gt;UIComposer&lt;/a&gt; which is currently at version 0.4a.&lt;b&gt;&amp;nbsp;&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
UIComposer is a Wicket custom control that provides similar functionality as Facebook's "What's On Your Mind" page widget. It is composed of an optional image which can be associated with a link, a data entry field for user input and a button that posts the user's data back to the server using AJAX.&lt;br /&gt;
&lt;br /&gt;
UIComposer comes in many flavors but using it in your applications is easy. All its resources and dependencies are fully self contained. So adding UIComposer is as simple as adding its lib to your project, importing it into your source files and creating the control:&lt;br /&gt;
&lt;blockquote&gt;import UIComposer.Wicket.Component.UICompositeWithImage;&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
add(new UICompositeWithImage("uicomposite", "What's on your mind?") {&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
&lt;/blockquote&gt;UIComposer's use of abstract methods allow tailoring the controls' behavior at run time making it suitable in situations that are specific to each application.&lt;br /&gt;
&lt;br /&gt;
Access to the project's source code is available using Subversion at the following url:&lt;br /&gt;
&lt;blockquote&gt;https://svn.kenai.com/svn/uicomposer~subversion &lt;br /&gt;
&lt;/blockquote&gt;Anonymous access to the repository is allowed but if you aren't already I would recommend you create your own account on Project Kenai to reap the greatest benefit as it affords many resources to developers.&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
Included in the distrobution is a Wicket application, UIComposerTestApp, for testing its various flavors and ways of using UIComposer.&lt;br /&gt;
&lt;br /&gt;
You will need to install &lt;a href="http://www.open.collab.net/downloads/subversion.html"&gt;Subversion&lt;/a&gt; on your system in order to obtain the UIComposer source code.&lt;br /&gt;
&lt;br /&gt;
If you use &lt;a href="http://www.netbeans.org/"&gt;Netbeans&lt;/a&gt; then you are in luck. Netbeans has excellent integration with Subversion and Project Kenai. In Netbeans, once you are logged in to Project Kenai, you can effortlessly download the project directly into Netbeans, all without leaving the Netbeans IDE.&lt;br /&gt;
&lt;br /&gt;
Please down load UIComposer. Play with it! Try to break it! Provide lots of feedback! Bug tracking is supported via Jira which is accessible from the project's &lt;a href="http://kenai.com/projects/uicomposer"&gt;home page&lt;/a&gt; on Project Kenai. The more feedback the better UIComposer will be.&lt;br /&gt;
&lt;br /&gt;
Currently UIComposer is covered under the GPL-2.0 source license. I am entertaining loosening the licensing restrictions with the lesser version of GPL but only after considerable thought has been given to doing so.&lt;br /&gt;
&lt;br /&gt;
In the new year I will contribute numerous articles that deal with creating custom Wicket components and UIComposer will serve as an example for many of them. But UIComposer is more than a tool for future articles, it is my contribution to the Wicket community. I hope users of the Wicket framework who need the features that UIComposer provides will take advantage of it, work with me and provide their feedback.&lt;br /&gt;
&lt;br /&gt;
Oh, and one more thing, that mug in the picture at the top of the page is mine :)&lt;br /&gt;
&lt;br /&gt;
Jeff&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-539034924385143907?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/539034924385143907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/12/uicomposer-on-project-kenai.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/539034924385143907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/539034924385143907'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/12/uicomposer-on-project-kenai.html' title='UIComposer On Project Kenai'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_XzLrgIoZ_TU/SzZD2C17XOI/AAAAAAAAAQ4/gKTJyKBOMZ4/s72-c/greenshot_2009-12-25_16-21-09.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-1228879881465312430</id><published>2009-12-24T09:48:00.011-05:00</published><updated>2009-12-26T14:07:16.130-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='heart'/><category scheme='http://www.blogger.com/atom/ns#' term='sun'/><category scheme='http://www.blogger.com/atom/ns#' term='Intype'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='kenai'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Some Musings About This Year &amp; Next</title><content type='html'>Oracle's pending purchase of Sun seems appropriate in the sense that it seems to add to the year end anxiety. Oracle will, I imagine, be able to alleviate the EEC's concern over MySql and will eventually see the EEC approve the deal. But developers have their concerns about where that will leave Netbeans, the free and open source Java IDE and rich client platform. Hopefully, Oracle will fully embrace Netbeans and provide the assets that are needed to move Netbeans along. And there is much to do.&lt;br /&gt;
&lt;br /&gt;
Recently released Netbeans v6.8 has lots of new features. It is very good but at times it is too memory hungry and brings my HP laptop (Vista OS with 2 gigs of memory) to its knees. The project scanning/indexing issue seems to have reappeared in this release for who knows why. Current support for Groovy and Grails, which I believe will see a tremendous growth in the coming year, is nowhere near where it could be. Intellij Idea, for example, really shines here and sets the bar that Netbeans will have to aim for in the coming year if it wants to attract and keep Groovy and Grails developers. The Zend framework needs to be among the PHP frameworks that are supported and Wicket support needs to be folded into Netbeans.&lt;br /&gt;
&lt;br /&gt;
Wicket has seen much improvement in 2009 and I am confident that it will continue to do so in 2010. Its developers are top-notch and its developer community is alive and well. Hopefully, the new year will see improved support for Java EE/EJB along the same lines that Wicket currently has for Spring.&lt;br /&gt;
&lt;br /&gt;
Cloud computing became a reality in 2009 and should see healthy adoption in 2010.&lt;br /&gt;
&lt;br /&gt;
Apparently the Intype editor project isn't dead after all and its developers seem to have a renewed determination towards putting out a new release. For all of us who have wished for a TextMate like editor for Windows, well we seem to be a few steps closer to that end.&lt;br /&gt;
&lt;br /&gt;
In the few remaining days of 2009 I will place my custom Wicket component on Project Kenai which will serve as the subject for numerous future articles. I am very excited about this. I was going to postpone putting the project on Kenai because it needs some minor refactoring and there is one api that I haven't even touched on yet. After some thought, though, I decided that it was more important to get it out there, that the remaining tasks should be visible and hopefully will attract developers' input and contributions to the project.&lt;br /&gt;
&lt;br /&gt;
And, finally, a voice on the radio just told me that this was the most dangerous time of the year for people to experience heart problems. I imagine this year will be even more severe than most due to the state of the economy and the prospect of a long and protracted recovery. Hopefully, those who found themselves struggling in 2009 will see better things coming their way during the coming year.&lt;br /&gt;
&lt;br /&gt;
A very happy holiday and new year to you all.&lt;br /&gt;
&lt;br /&gt;
Jeff&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-1228879881465312430?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/1228879881465312430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/12/some-musings-about-this-year-next.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/1228879881465312430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/1228879881465312430'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/12/some-musings-about-this-year-next.html' title='Some Musings About This Year &amp; Next'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-751360383437042264</id><published>2009-08-29T12:35:00.006-04:00</published><updated>2009-08-29T14:18:17.255-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='ee5'/><title type='text'>Improving Wicket's Support for Java EE5 Applications</title><content type='html'>I am a huge fan of the Wicket Web framework. Wicket has made Web application development fun again for me and for many other developers by greatly lowering the impedance mismatch that exists between HTTP and the Java language.

As perfect as Wicket is, though, it could use some improvement in its ability to support Java EE5 based applications. So here I offer my take on what I believe can be done to make Wicket an even better framework.

Currently Wicket's support for Java EE5 applications is provided by wicket-contrib-javaee. By adding this add-on to your Wicket application you can reference the functionality exposed by any EJB simply by using the @EJB annotation and adding a few lines of initialization code to the Wicket WebApplication class.

However, some developers who have worked with this add-on have voiced concerns about it causing problems in their applications. At the same time, the support behind this add-on appears to be somewhat questionable. This is an unfortunate state of affairs but one which could be rectified if the functionality provided by it was instead folded into the core Wicket distribution. This should not be seen as an endorsement of EE but rather as a recognition that there is a significant interest to employ Wicket in EE applications. This recognition would be similar to that which has already been given to Spring and Guice by having included their interfacing libraries as part of Wicket's core distribution. Such an adaption could result in a greater acceptance of Wicket in environments where EE is the chosen platform for Enterprise applications. 

In conjunction with this I would also suggest that the next edition of the marvelous Wicket In Action book include a new chapter dedicated to showing just how easy it is to create this type of application. I would gladly contribute it myself if I were asked :)

Sincerely,
Jeff&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-751360383437042264?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/751360383437042264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/08/what-can-make-wicket-even-better.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/751360383437042264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/751360383437042264'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/08/what-can-make-wicket-even-better.html' title='Improving Wicket&apos;s Support for Java EE5 Applications'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-4516703456929081224</id><published>2009-08-28T17:06:00.004-04:00</published><updated>2009-11-18T12:27:00.748-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cat'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='job'/><title type='text'>Coming Soon - An Article About Developing Custom Ajax Enabled Wicket Components</title><content type='html'>As I have been very busy looking for full-time work  I haven't had time to devote to writing my next article. I've got 5 cats to feed and they eat a lot so I better land a job soon or I might wind up eating my 5 cats LOL.

Anyway, I gave it a lot of thought and my next article will be about developing custom Ajax enabled Wicket components. The component that I will create in the tutorial will be similar to the What's On Your Mind component seen on Facebook pages. In the process I will demonstrate how Wicket makes developing this type of component almost trivial.

Sincerely,
Jeff&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-4516703456929081224?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/4516703456929081224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/08/whats-next.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/4516703456929081224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/4516703456929081224'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/08/whats-next.html' title='Coming Soon - An Article About Developing Custom Ajax Enabled Wicket Components'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-6431594225993919079</id><published>2009-07-17T06:59:00.037-04:00</published><updated>2009-08-30T10:02:15.248-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stateless'/><category scheme='http://www.blogger.com/atom/ns#' term='http'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='stateful'/><category scheme='http://www.blogger.com/atom/ns#' term='request'/><category scheme='http://www.blogger.com/atom/ns#' term='session'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Wicket, A Stateful Web Framework</title><content type='html'>&lt;span style="font-weight: bold;"&gt;HTTP Is Stateless&lt;/span&gt;

Desktop application programmers as well as programmers developing in a traditional multi-user, client/server environment don't normally have to worry about maintaining the state of an application's objects.  After all, programming languages like C, C++, Java and C# have built-in mechanisms that maintain a variable's state during the lifetime of the application, insuring that the value of a variable is maintained and that it is 'reachable' upon referencing that variable.

The stateless nature of HTTP, however, creates artificial workflows for web applications that do not exist in applications developed for the desktop or for a traditional multi-user, client/server environment. Because HTTP doesn't persist an application's state across multiple HTTP requests means that application servers and frameworks have to provide some mechanisms to allow the programmer to do this. A common method uses hash tables that are stored to physical memory or to a database or  file system at the end of processing an HTTP requests. The ability to persist these values so that they can be read back when the next HTTP request hits the server for the same client session provides the glue or the narrative thread that web applications need in order to bind the multiple HTTP requests into something that simulates an unbroken (broken by HTTP request boundaries) and contiguous workflow.

Managing this session state is the responsibility of the application programmer. Every application and workflow  imposes its own requirements as to what and when something is required to be persisted and herein lies the problem: getting this right 100% of the time  is often the most difficult challenge a developer faces when developing a web application that is maintainable, responsive and scalable. To make matters worse, the difficulty grows proportionately as the application grows in complexity and as more maintenance is done. With tight schedules and dwindling budgets there is often no time to thoroughly conduct a regression test to ensure that new bugs aren't being introduced.

My own experiences working on web applications have led me to believe that this isn't the best approach to dealing with the stateless nature of HTTP and that there has to be a better way. I have spent far too many nights and weekends  debugging and fixing problems related to changes made to application logic and the subsequent mismanagement of session state needed to support the work flows across multiple HTTP requests to think that this is an optimal solution.

&lt;span style="font-weight: bold;"&gt;Using The Session Hash Table&lt;/span&gt;
&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;
Perhaps now is a good time to provide an example of how hash table based session state frameworks attempt to overcome the stateless nature of HTTP and the types of problems that are associated with this technique. I will juxtapose Wicket's approach to handling this after.

Lets consider what appears on the surface to be a rather simple scenario, that of maintaining and displaying a counter whose value represents the number of times the web page is processed on the server and rendered in the browser. When the user requests the web page for the first time it should be rendered displaying a value of 1 for the counter. When the user clicks the button on the web page the browser should issue a get request back to the server. The application running on the server should process the get request by incrementing the counter and rendering the page back to the browser displaying the current value of the counter. The web page itself is simple and looks like the following:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SmCe8_pIpJI/AAAAAAAAAPI/tdalqj90MnA/s1600-h/greenshot_2009-07-17_11-54-42.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 343px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SmCe8_pIpJI/AAAAAAAAAPI/tdalqj90MnA/s400/greenshot_2009-07-17_11-54-42.png" alt="" id="BLOGGER_PHOTO_ID_5359458327284196498" border="0" /&gt;&lt;/a&gt;
The first time the user requests the page it will be rendered in the browser with a value of 1 for the counter. Each subsequent click of the button whose label is 'Click Here' will result in the browser issueing a get back to the server and the page being rendered to the browser with an incremented counter. The image below shows what the page would look like after being rendered for the second time:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SmCfMBX7isI/AAAAAAAAAPQ/jgBhvIXVM34/s1600-h/greenshot_2009-07-17_11-56-13.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 343px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SmCfMBX7isI/AAAAAAAAAPQ/jgBhvIXVM34/s400/greenshot_2009-07-17_11-56-13.png" alt="" id="BLOGGER_PHOTO_ID_5359458585446943426" border="0" /&gt;&lt;/a&gt;
Notice how the counter's value in the above image is 2. This is in response to it having been incremented on the server.

So what does it take code-wise on the server to provide this functionality? Using a web framework such as ASP.DotNet and ASPX Web Forms, the object associated with an  aspx page would be created in response to the HTTP request and the object's  load method would be called in which it would retrieve the value from the session state hash table using a string value to identify the value. It would then  convert the value to an integer, increment the value by 1, convert the value back to a string, assign the value to the label on the web page, save the value to the session hash and lastly render the page back to the browser. But wait! What would happen if this is the first time the page is processing? If you didn't compensate for this and have an alternate branch of logic the  named value wouldn't exist in the session hash table and the program would abort because it was attempting to manipulate a null string reference. But wait!  Couldn't you instead, you ask,  store the value in a field of the aspx page object and just increment it every time it processes the request? The answer is no  because ASP.DotNet like many other frameworks does not persist the state of the objects that represent web pages and HTML controls on the server between HTTP requests. Instead, ASP.DotNet as do many other frameworks instantiates the object associated with the web page every time a new request arrives. Instantiation of the  object causes the object's fields to be  assigned their initial values according to the object constructor or to their appropriate default initial values based on their variable types. While this is a trivial example, it isn't hard to see how this way of dealing with persisting state between HTTP requests can quickly snowball out of control.

Now imagine that there is  a web framework out there that actually does persist the objects associated with web pages and HTML controls across HTTP requests. Suddenly, schemes such as having to save application state in hash tables and persist them across HTTP requests are  no longer necessary. Now your favorite object oriented programming language behaves almost the same way in web applications as it does in desktop or client-server applications. Imagine that the fact that the web application  is running in a stateless HTTP environment is hidden from the developer and the framework takes care of persisting and restoring the objects associated with your application's web pages and HTML controls for you.

&lt;span style="font-weight: bold;"&gt;Enter Wicket, Simply Eloquent and Eloquently Simple&lt;/span&gt;

Well, you are not left to your  imagination because there actually is a web application framework that does this and a whole lot more for you. It is the Java based Apache Wicket web framework. Using the example from above, here is the actual code written to the Wicket web framework that renders the web page pictured above:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SpqGQ54fGLI/AAAAAAAAAQI/9BiWCiAsJkc/s1600-h/greenshot_2009-08-30_10-01-04.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 327px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SpqGQ54fGLI/AAAAAAAAAQI/9BiWCiAsJkc/s400/greenshot_2009-08-30_10-01-04.png" alt="" id="BLOGGER_PHOTO_ID_5375756730193877170" border="0" /&gt;&lt;/a&gt;
That's it. Nowhere is there code to save or retrieve string values from a session based hash table. Nor are there alternate paths of logic needed to differentiate processing that should happen the first time a web page is being requested from all other requests. There is just "normal" Java code - i is initialized in the HomePage constructor and i is incremented in response to the button's onClick method. The current value of i is  rendered back to the browser in response to each request. This style will seem very familiar to those who have coded Java SE Swing based applications or to anyone who has coded desktop applications using other programming languages such as C# or even Basic.

And if you are thinking that there must be some magic happening in the HTML page well there isn't and here it is:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SmC-6Bvfd_I/AAAAAAAAAPg/rZan4xOa_4Q/s1600-h/greenshot_2009-07-17_14-11-27.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 166px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SmC-6Bvfd_I/AAAAAAAAAPg/rZan4xOa_4Q/s400/greenshot_2009-07-17_14-11-27.png" alt="" id="BLOGGER_PHOTO_ID_5359493460680210418" border="0" /&gt;&lt;/a&gt;
Nothing but pure HTML. Wicket is a Model/View/Controller based framework. HTML pages never mix markup with code. They are strictly the 'view' part of the MVC equation.

The actual magic is happening behind the scenes and within the Wicket framework's request cycle processing which is responsible for persisting the HomePage object at the end of each request cycle and restoring it at the start of each request cycle. This is completely transparent to the application developer who can just assume that objects behave like... objects. Wicket hides the stateless nature of HTTP and enables  coding web applications like one would code non web applications.

Of course the developer must exercise sound judgment when  deciding what and how much to persist in the objects associated with Wicket web pages and HTML controls. Persisting a list of 100,000 database records, for instance, for thousands of concurrent users is wasteful and could cause severe degradation or even cause the server to fail altogether.

For instance, persisting a database table row's unique identity in a web page object is preferable to persisting the actual row of data since the database itself already serves as the underlying cache for the data. Having the identity of the row of data is enough to allow the data to be retrieved through a query to the database when and if it is needed. Wicket also provides a model architecture that promotes this type of resource usage. Wicket's  LoadableDetachableModel class provides the developer with the  ability to persist only the minimum amount of information across HTTP requests - such as a data row's identity value - which can be used to query the database for the actual data when and if it is needed and released at the end of the request.

&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;

The Apache Wicket web framework eliminates one of the greatest challenges faced by developers of web applications, the dreaded persistence problem caused by the stateless nature of HTTP. Wicket also provides numerous other advantages to developers of web application, some of which I have already written about and which you can read  here in my blog.

I hope you have enjoyed reading this article as much as I have enjoyed presenting it to you. And as always, please feel free to leave your comments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-6431594225993919079?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/6431594225993919079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/07/wicket-state-icing-on-cake.html#comment-form' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/6431594225993919079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/6431594225993919079'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/07/wicket-state-icing-on-cake.html' title='Wicket, A Stateful Web Framework'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_XzLrgIoZ_TU/SmCe8_pIpJI/AAAAAAAAAPI/tdalqj90MnA/s72-c/greenshot_2009-07-17_11-54-42.png' height='72' width='72'/><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-7109588660774274194</id><published>2009-05-21T09:00:00.028-04:00</published><updated>2009-05-30T11:36:34.594-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='javaee'/><category scheme='http://www.blogger.com/atom/ns#' term='di'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='ee5'/><title type='text'>Wicket + EJB + DI With Netbeans - Part 3</title><content type='html'>&lt;span style="font-weight: bold;font-size:130%;" &gt;Part 3 - Using The @EJB Annotation To Provide Dependency Injection Support In The Web Tier And Consuming The Services Provided By Their Backing EJBs

&lt;/span&gt;&lt;span style="font-size:100%;"&gt;For this last part of the tutorial I am going to demonstrate how to use Wicket in an EE container environment such as Glassfish. wicket-contrib-javaee is a wicket module that provides integration through Java EE 5 resource injection. With wicket-contrib-javaee you can use the following 3 annotations in your wicket pages:&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;@EJB&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;@PersistenceUnit&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;@Resource&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:100%;"&gt;In particular, I will demonstrate how to use the @EJB annotation for dependency injection of the CustomerFacade ejb that was developed in Part 2 of this tutorial.

&lt;span style="font-weight: bold;"&gt;Adding wicket-contrib-javaee-1.1.jar&lt;/span&gt;

Begin by downloading the wicket-contrib-javaee-1.1.jar &lt;/span&gt;&lt;span style="font-size:100%;"&gt;which can be found &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=134391&amp;amp;package_id=219263&amp;amp;release_id=568606"&gt;here&lt;/a&gt; on SOURCEFORGE.NET. Once you have downloaded the jar and saved it locally it then needs to be added to the WicketEETutorial1-war module:
&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Right click the Libraries node and select Add Jar/Folder. This will open the Add Jar/Folder window. &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Navigate to the location where you saved the wicket-contrib-javaee-1.1.jar file and select it. Make sure that the Copy To Libraries Folder option is selected.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SiBRVYbC3lI/AAAAAAAAAMs/vFGYgfl8-z0/s1600-h/greenshot_2009-05-29_17-17-39.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 229px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SiBRVYbC3lI/AAAAAAAAAMs/vFGYgfl8-z0/s400/greenshot_2009-05-29_17-17-39.png" alt="" id="BLOGGER_PHOTO_ID_5341358585836396114" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Click Open and Netbeans will add the jar file to the module.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SiBSRwmfMjI/AAAAAAAAAM0/ae8SZj-79-k/s1600-h/greenshot_2009-05-29_17-22-49.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SiBSRwmfMjI/AAAAAAAAAM0/ae8SZj-79-k/s400/greenshot_2009-05-29_17-22-49.png" alt="" id="BLOGGER_PHOTO_ID_5341359623118991922" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;
&lt;/span&gt;Now we need to add the wicket-ioc jar to the module. wicket-ioc.jar is included with the wicket distribution which we downloaded in Part 1 of this tutorial.

&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Adding wicket-ioc jar&lt;/span&gt;&lt;span style="font-size:100%;"&gt;
&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Right click the Libraries node and select Add Jar/Folder. This will open the Add Jar/Folder window. &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Navigate to the location where you saved the wicket distribution that we downloaded in Part 1 of this tutorial. In the lib folder select the wicket-ioc jar file. Make sure that the Copy To Libraries Folder option is selected.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SiBdfTGiM5I/AAAAAAAAANM/duDdCJTK6co/s1600-h/greenshot_2009-05-29_18-09-22.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 229px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SiBdfTGiM5I/AAAAAAAAANM/duDdCJTK6co/s400/greenshot_2009-05-29_18-09-22.png" alt="" id="BLOGGER_PHOTO_ID_5341371950346417042" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Click Open and Netbeans will add the jar file to the module.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SiBeJ3tFwEI/AAAAAAAAANU/sUQiEWTsCTA/s1600-h/greenshot_2009-05-29_18-13-19.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 321px; height: 400px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SiBeJ3tFwEI/AAAAAAAAANU/sUQiEWTsCTA/s400/greenshot_2009-05-29_18-13-19.png" alt="" id="BLOGGER_PHOTO_ID_5341372681726312514" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:100%;"&gt;The wicket-ioc jar has a dependency on cglib jar so we need to include that in the module as well.

&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Adding cglib jar&lt;/span&gt;&lt;span style="font-size:100%;"&gt;

The cglib jar is hosted on SourceForge and you can download it from &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=56933&amp;amp;package_id=98218&amp;amp;release_id=601998"&gt;here&lt;/a&gt;. &lt;/span&gt;&lt;span style="font-size:100%;"&gt;Once you have downloaded the jar and saved it locally it then needs to be added to the WicketEETutorial1-war module:
&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Right click the Libraries node and select Add Jar/Folder. This will open the Add Jar/Folder window. &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Navigate to the location where you saved the cglib jar file and select it. Make sure that the Copy To Libraries Folder option is selected.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SiBmVucwTOI/AAAAAAAAANc/nYvJUTifI7U/s1600-h/greenshot_2009-05-29_18-48-01.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 229px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SiBmVucwTOI/AAAAAAAAANc/nYvJUTifI7U/s400/greenshot_2009-05-29_18-48-01.png" alt="" id="BLOGGER_PHOTO_ID_5341381681493331170" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Click Open and Netbeans will add the jar file to the module.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SiBm9EGD2gI/AAAAAAAAANk/UgP6DABwp1E/s1600-h/greenshot_2009-05-29_18-51-05.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 306px; height: 400px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SiBm9EGD2gI/AAAAAAAAANk/UgP6DABwp1E/s400/greenshot_2009-05-29_18-51-05.png" alt="" id="BLOGGER_PHOTO_ID_5341382357318621698" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:100%;"&gt;
The web.xml file needs to be modified to include a reference to the CustomerFacade ejb.
&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;Adding A Reference In web.xml To &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;CustomerFacade EJB&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span&gt;

In the Projects pane expand the Configuration Files node and double click the web.xml file to open it in the editor and click on the References tab.
&lt;/span&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span&gt;Expand the EJB References panel and click the Add button. This will open the Add EJB Reference window.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span&gt;Enter WicketEETutorial1-ejb/CustomerFacade for the EJB Reference Name.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span&gt;Select Session for the EJB Type.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span&gt;Select Local for Interface Type.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span&gt;Enter ejbs.CustomerFacadeLocal for the Local Interface.&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SiBWd3EBr_I/AAAAAAAAAM8/2WuvTAJ_xPo/s1600-h/greenshot_2009-05-29_17-39-43.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 235px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SiBWd3EBr_I/AAAAAAAAAM8/2WuvTAJ_xPo/s400/greenshot_2009-05-29_17-39-43.png" alt="" id="BLOGGER_PHOTO_ID_5341364229058441202" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span&gt;Click the OK button to save the changes to the web.xml file.&lt;/span&gt;
&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:100%;"&gt;Now we need to override the init method in Application.java.

&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt; Modifying Application.java

&lt;/span&gt;&lt;span style="font-size:100%;"&gt;Open the Application.java file and add the following code:

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

Right click in the editor and select Fix Imports to add the needed import statements.

Application.java file should now look like the following:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SiBZZ66RktI/AAAAAAAAANE/l3m4kDJMZ0M/s1600-h/greenshot_2009-05-29_17-52-06.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 315px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SiBZZ66RktI/AAAAAAAAANE/l3m4kDJMZ0M/s400/greenshot_2009-05-29_17-52-06.png" alt="" id="BLOGGER_PHOTO_ID_5341367459906687698" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;Now we need to modify HomePage.java where we wiill include the @EJB annotation for the CustomerFacade ejb and consume its services.

&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Adding The @EJB Annotation

&lt;/span&gt;Open HomePage.java in the editor and add the following to the HomePage class definition&lt;span style="font-weight: bold;"&gt;:

&lt;/span&gt;    @EJB(name="WicketEETutorial1-ejb/CustomerFacade")
private CustomerFacadeLocal customerEjb;
&lt;span style="font-weight: bold;"&gt;
&lt;/span&gt;*** Note that the name we are providing for the @EJB annotation is the same one we used when we added the EJB reference to the web.xml file.

Now everything is in place for us to actually consume the data access services that are provided by the CustomerFacade ejb so lets add some more code to the HomePage constructor to get a list of Customer entities and get a count of how many entities there are in the list.

&lt;span style="font-weight: bold;"&gt;Consuming The Data Access Services Provided By The CustomerFacade ejb&lt;/span&gt;

Modify the HomePage constructor so that it looks exactly like the following:

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

List&lt;customer&gt; customers = customerEjb.findAll();
int count = customers.size();

add(new Label("customercount",String.valueOf(count)));

}
&lt;/customer&gt;&lt;customer&gt;
Right click the editor and select Fix Imports to add the needed import statements. Your HomePage.java file should now look like the following;&lt;/customer&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SiE-FVTRSqI/AAAAAAAAAOE/qP-E0-l-uhA/s1600-h/greenshot_2009-05-30_10-05-50.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 280px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SiE-FVTRSqI/AAAAAAAAAOE/qP-E0-l-uhA/s400/greenshot_2009-05-30_10-05-50.png" alt="" id="BLOGGER_PHOTO_ID_5341618894376356514" border="0" /&gt;&lt;/a&gt;
Open HomePage.html in the editor and modify its markup so that it looks exactly like the following;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SiE-nt4gAoI/AAAAAAAAAOM/xjWrj7YMjUM/s1600-h/greenshot_2009-05-30_10-10-31.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 126px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SiE-nt4gAoI/AAAAAAAAAOM/xjWrj7YMjUM/s400/greenshot_2009-05-30_10-10-31.png" alt="" id="BLOGGER_PHOTO_ID_5341619485090513538" border="0" /&gt;&lt;/a&gt;
We have added a Wicket component that will display the number of Customer entities in the list of Customers returned from calling the findAll method of the CustomerFacade ejb.

&lt;customer&gt;We are now ready to build and run our application.

&lt;span style="font-weight: bold;"&gt;Running Our Application&lt;/span&gt;

Rick click the WicketEETutorial1 node in the Projects pane and select Run to build and run the application. Your browser should open and render the following;&lt;/customer&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SiFAb85JvjI/AAAAAAAAAOU/nvFrN-FPgbM/s1600-h/greenshot_2009-05-30_10-18-00.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 180px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SiFAb85JvjI/AAAAAAAAAOU/nvFrN-FPgbM/s400/greenshot_2009-05-30_10-18-00.png" alt="" id="BLOGGER_PHOTO_ID_5341621481984605746" border="0" /&gt;&lt;/a&gt;
As you can see from the above image, we were able to obtain a reference to the CustomerFacade ejb via the use of the @EJB annotation and call the findAll method which the CustomerFacade ejb exposes. findAll returned a list of Customer entities and from the list we were able to obtain a count of Customer entities.

&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;

Netbeans greatly simplifies the whole process of generating the Enterprise Application's modules. Netbeans wizards generate a lot of code that we would otherwise have to hand code ourselves. To a very large degree Netbeans trivializes Java EE5 applications allowing us to focus on the domain issues of the application and not its plumbing and wiring.

Who said Java EE was too heavy and complex? I hope this tutorial demonstrated that neither is true.

With the addition of the wicket-contrib-javaee jar file, Wicket applications gain the ability to use Java EE5 annotations that allow it to take full advantage of services esxposed in enterprise java beans when running in a Java EE5 container such as the one Glassfish provides.

All in all, very cool, isn't it? And easy, too!And how cool is it to be able to use Wicket as the web framework in a Java EE application and have it be able to consume services exposed through ejbs using standard Java EE annotations?

Though this application was trivial by design so as to keep it simple for demonstration purposes, the principles demonstrated here will work for applications of much greater size and complexity.

&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;

This concludes the tutorial and I hope you had as much fun following along as I had presenting it. Please feel free to provide your comments. I look forward to hearing from you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-7109588660774274194?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/7109588660774274194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/05/wicket-ejb-di-with-netbeans-part-3.html#comment-form' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/7109588660774274194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/7109588660774274194'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/05/wicket-ejb-di-with-netbeans-part-3.html' title='Wicket + EJB + DI With Netbeans - Part 3'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_XzLrgIoZ_TU/SiBRVYbC3lI/AAAAAAAAAMs/vFGYgfl8-z0/s72-c/greenshot_2009-05-29_17-17-39.png' height='72' width='72'/><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-3975800577666883514</id><published>2009-05-18T12:26:00.028-04:00</published><updated>2009-05-30T11:36:24.705-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='javaee'/><category scheme='http://www.blogger.com/atom/ns#' term='di'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='ee5'/><title type='text'>Wicket + EJB + DI With Netbeans - Part 2</title><content type='html'>&lt;span style="font-weight: bold;font-size:130%;" &gt;Part 2 - &lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Creating Entity Classes That Map To An Existing Database And Exposing Data Access Services Through EJBs&lt;/span&gt;&lt;span style="font-size:130%;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;With Netbeans&lt;/span&gt;

&lt;/span&gt;&lt;span&gt;For this part of the tutorial I am going to use the Sample database that comes with the Java DB which should have been installed when you installed Netbeans and Glassfish. You can verify that the Sample database is recognized by Netbeans by expanding the Database node in the Services pane where you should see a connection listed there that looks like the highlighted one below.&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SgNTbMozFYI/AAAAAAAAAIc/H4wk_gUiUm4/s1600-h/greenshot_2009-05-07_17-31-28.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 232px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SgNTbMozFYI/AAAAAAAAAIc/H4wk_gUiUm4/s400/greenshot_2009-05-07_17-31-28.png" alt="" id="BLOGGER_PHOTO_ID_5333198110450718082" border="0" /&gt;&lt;/a&gt;
&lt;span&gt;If you fully expand the connection node you can see that there are a number of tables already defined. For this tutorial we want to create one entity class for the Customer table. However, we will not have to hand code this entity class because &lt;/span&gt;&lt;span&gt;Netbeans has excellent tooling support for generating entity classes that map to tables in a database.&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SgQdpf01AYI/AAAAAAAAAI8/65oCuB0AUyI/s1600-h/greenshot_2009-05-08_07-46-37.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 355px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SgQdpf01AYI/AAAAAAAAAI8/65oCuB0AUyI/s400/greenshot_2009-05-08_07-46-37.png" alt="" id="BLOGGER_PHOTO_ID_5333420457468428674" border="0" /&gt;&lt;/a&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;span style="font-size:100%;"&gt;Creating Our Customer Entity Class&lt;/span&gt;

&lt;/span&gt;&lt;span&gt;Please follow these steps to create the Customer entity class for the Customer table in the Sample database:
&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span&gt;In the Projects pane right click the WicketEETutorial1-ejb module node and select New|Other from the context menu. This will open the New File window. In the Categories pane select Persistence and in the File Types pane select Entity Classes From Database and click Next.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Expand the Data Source drop-down menu in the Data Tables Pane and select the jdbc/sample option. Netbeans will fill the Available Tables list with all the tables defined in the Sample DB.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Uncheck the Include Related Tables option.&lt;/li&gt;&lt;li&gt;Select the CUSTOMER table from the list of Available Tables.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/ShLwrL2uMPI/AAAAAAAAALU/wBRG8G08rAs/s1600-h/greenshot_2009-05-19_13-45-42.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 272px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/ShLwrL2uMPI/AAAAAAAAALU/wBRG8G08rAs/s400/greenshot_2009-05-19_13-45-42.png" alt="" id="BLOGGER_PHOTO_ID_5337593133094809842" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Click the Add button and then click Next.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Enter entities as the package name in the Package field and the click the Create Persistence Unit button. In the Create Persistence Unit window accept all the defaults and click the Create button. Now click the Next button.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;In the Mapping Options pane select java.util.List for the Collection Type and click the Finish button.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;Upon completing the above steps, Netbeans will create the Customer entity class and place it in the entities package.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/ShVOTZl9eiI/AAAAAAAAAMU/ec39h6YN-YQ/s1600-h/greenshot_2009-05-21_08-49-30.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 220px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/ShVOTZl9eiI/AAAAAAAAAMU/ec39h6YN-YQ/s400/greenshot_2009-05-21_08-49-30.png" alt="" id="BLOGGER_PHOTO_ID_5338259028512176674" border="0" /&gt;&lt;/a&gt;
Netbeans will also generate the persistence.xml file and place it under the Configuration Files tab.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/ShVOrkF8R7I/AAAAAAAAAMc/53UpnVxVILE/s1600-h/greenshot_2009-05-21_08-52-12.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 220px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/ShVOrkF8R7I/AAAAAAAAAMc/53UpnVxVILE/s400/greenshot_2009-05-21_08-52-12.png" alt="" id="BLOGGER_PHOTO_ID_5338259443647530930" border="0" /&gt;&lt;/a&gt;
With our entity class and persistence unit file created we can now go on and encapsulate our database access code in EJBs. Like our entity class we will not have to hand code our database access code. Netbeans has excellent tooling support for generating database access code that map to existing entity classes.

&lt;span style="font-weight: bold;"&gt;Creating Our Customer Data Access EJB
&lt;/span&gt;&lt;span&gt;
Please follow these steps to create the EJB that will encapsulate the database access code:
&lt;/span&gt;&lt;ol&gt;&lt;li&gt;&lt;span&gt;In the Projects pane right click the WicketEETutorial1-ejb module node and select New|Other from the context menu. This will open the New File window. In the &lt;/span&gt;&lt;span&gt;Categories pane select Persistence and in the File Types pane select Session Beans For Entity Classes and click Next. As you can see, Netbeans has filled the Available Entity Classes list with the Customer entity class we created.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Select the Customer entity in the list of Available Entity Classes.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/ShL2ctu9tpI/AAAAAAAAALs/ozkcVptTT1Q/s1600-h/greenshot_2009-05-19_14-08-46.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 282px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/ShL2ctu9tpI/AAAAAAAAALs/ozkcVptTT1Q/s400/greenshot_2009-05-19_14-08-46.png" alt="" id="BLOGGER_PHOTO_ID_5337599481560807058" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Click the Add buttom and then click the Next button.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;In the Generated Session Beans pane enter ejbs for the package name. We want to create a local interface so make sure the Local checkbox is checked.&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/ShL31HC5a1I/AAAAAAAAAL0/Xlde6057DDI/s1600-h/greenshot_2009-05-19_14-10-37.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 256px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/ShL31HC5a1I/AAAAAAAAAL0/Xlde6057DDI/s400/greenshot_2009-05-19_14-10-37.png" alt="" id="BLOGGER_PHOTO_ID_5337601000183786322" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;Now click the Finish button.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;Upon completing the above steps, Netbeans will create the local interface and implementation class files for the Customer entity that we selected and place these files in the ejbs package.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/ShVPHMjo9HI/AAAAAAAAAMk/JWaT-WjCVk8/s1600-h/greenshot_2009-05-21_08-54-21.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 243px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/ShVPHMjo9HI/AAAAAAAAAMk/JWaT-WjCVk8/s400/greenshot_2009-05-21_08-54-21.png" alt="" id="BLOGGER_PHOTO_ID_5338259918365979762" border="0" /&gt;&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;

This concludes Part 2 of the tutorial. As you can see, Netbeans greatly simplifies coding the service tear in an Enterprise Application. We have taken advantage of the tooling available in Netbeans to generate our Customer entity class, persistence.xml and CustomerFacade EJB class files for us. In the next part of this tutorial, Part 3,  we will expand the web tier to consume the services exposed by the CustomerFacade EJB that we have just created.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-3975800577666883514?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/3975800577666883514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/05/wicket-ejb-di-with-netbeans-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/3975800577666883514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/3975800577666883514'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/05/wicket-ejb-di-with-netbeans-part-2.html' title='Wicket + EJB + DI With Netbeans - Part 2'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_XzLrgIoZ_TU/SgNTbMozFYI/AAAAAAAAAIc/H4wk_gUiUm4/s72-c/greenshot_2009-05-07_17-31-28.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-6045315088585327197</id><published>2009-05-06T12:39:00.085-04:00</published><updated>2009-05-30T11:36:04.199-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ejb'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='javaee'/><category scheme='http://www.blogger.com/atom/ns#' term='di'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='ee5'/><title type='text'>Wicket + EJB + DI With Netbeans - Part 1</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;

This 3 part tutorial demonstrates how easy it is to create a Java EE5 Enterprise Application with Netbeans. The Web tier of the Enterprise Application will be based on the Wicket Web framework and the services tier -- the EJBs (Enterprise Java Beans) -- will serve up data from a database which will be consumed by the Web tier.

In particular, it demonstrates how easy it is for the Web tier to consume the services exposed by EJBs and to manage references to the EJBs through DI (dependency injection) using the @EJB annotation and the wicket-contrib-javaee jar library.

The tutorial has 3 parts covered in 3 separate articles:
&lt;ol&gt;&lt;li&gt;Part 1 will demonstrate creating the Enterprise Application in Netbeans and configuring the Web tier to use the latest build of the Wicket framework.&lt;/li&gt;&lt;li&gt;Part 2 will demonstrate creating entity classes that map to an existing database and exposing data access services through EJBs.&lt;/li&gt;&lt;li&gt;Part 3 will demonstrate using the @EJB annotation to provide dependency injection support in the Web tier and consuming the services provided by their backing EJBs.&lt;/li&gt;&lt;/ol&gt;
At the conclusion of this 3 part tutorial we will have created a fully functional Wicket based Web application running in the Java EE5 container supplied by the Glassfish application server. The Web application will use standard Java EE5 based annotations such as @EJB to resolve references to EJBs at run time through the use of dependency injection.

It is also my hope that this tutorial will serve to dispel the belief by many that the Java EE5 container is too heavy and complex to develop for.
&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;
&lt;/span&gt;&lt;span style="font-size:130%;"&gt;Part 1 - Creating A Java EE5 Enterprise Application With Netbeans&lt;/span&gt;&lt;span style="font-size:100%;"&gt;
&lt;/span&gt;
Creating The Application

&lt;/span&gt;&lt;span&gt;Netbeans greatly simplifies the creation of Java EE5 based applications as the following demonstrates. Please follow these steps: &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;
&lt;/span&gt;&lt;ol&gt;&lt;li&gt;Open Netbeans.&lt;/li&gt;&lt;li&gt;Select File|New Project from the main menu. This will open the New Project window&lt;/li&gt;&lt;li&gt;In the Categories pane select Java EE and in the Projects pane select Enterprise Application and click Next.&lt;/li&gt;&lt;li&gt;Enter WicketEETutorial1 or any other name you chose for the Project Name as pictured below and click Next.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/ShGqXmVRhXI/AAAAAAAAALM/5YP2jXkC_nY/s1600-h/greenshot_2009-05-18_14-33-14.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 279px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/ShGqXmVRhXI/AAAAAAAAALM/5YP2jXkC_nY/s400/greenshot_2009-05-18_14-33-14.png" alt="" id="BLOGGER_PHOTO_ID_5337234355814237554" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;From the Server drop-down selection list select Glassfish v2 or better. Accept the other options' default settings as pictured below and click Finish.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SgMxt7bfKuI/AAAAAAAAAH8/QcNxp02AYLQ/s1600-h/greenshot_2009-05-07_15-06-20.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 275px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SgMxt7bfKuI/AAAAAAAAAH8/QcNxp02AYLQ/s400/greenshot_2009-05-07_15-06-20.png" alt="" id="BLOGGER_PHOTO_ID_5333161048853654242" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;As a result of completing the above, Netbeans will generate and open 3 module projects in the Projects pane as pictured below.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/ShVMBMEj0LI/AAAAAAAAAME/HGFacpj5CoY/s1600-h/greenshot_2009-05-21_08-38-10.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 340px; height: 105px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/ShVMBMEj0LI/AAAAAAAAAME/HGFacpj5CoY/s400/greenshot_2009-05-21_08-38-10.png" alt="" id="BLOGGER_PHOTO_ID_5338256516621521074" border="0" /&gt;&lt;/a&gt;&lt;span&gt;The 3 modules and their associated projects that were generated for us are summarized below:&lt;/span&gt;
&lt;ol&gt;&lt;li&gt;WicketEETutorial1 is an Enterprise Application module project and its ear (enterprise archive) file is what will be deployed to the server. &lt;/li&gt;&lt;li&gt;WicketEETutorial1-ejb is an EJB module project and it is here where we will define our entity classes and encapsulate our JPA data access code in EJBs (Enterprise Java Beans). This module will serve as our service layer tier and provide both domain and business functionality to our Web application. Its jar file is included in the ear file mentioned above.
&lt;/li&gt;&lt;li&gt;WicketEETutorial1-war is a Web module project and it is here where we will define our presentation layer tier. Its war (web archive) file is included in the ear file mentioned above. As a default, Netbeans configures the web tier to serve up JSP pages. In the next step we will change this so that the web tier will use the Wicket web framework instead.&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Configuring the Web tier to use Apache Wicket &lt;/span&gt;

For this tutorial I am using the latest release candidate of the Wicket web framework which at the time of writing this was version 1.4-rc2 and which I downloaded from the &lt;a href="http://wicket.apache.org/"&gt;Apache Wicket web site&lt;/a&gt;. A basic Wicket web application only needs the wicket-1.4-rc2.jar file so I added it to the module.

Wicket has a dependency on the slf4j which is a logging API. I was able to download the SLF4J distribution from the &lt;a href="http://www.slf4j.org/"&gt;SLF4J web site&lt;/a&gt;. This distribution also includes the jar file for log4j which is a popular logging implementation. I added 3 jar files from this distribution to the module.

Now the web tier's Libraries node contains the following jars:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ShVM0uE7_1I/AAAAAAAAAMM/T1qFKVv0zo8/s1600-h/greenshot_2009-05-21_08-43-38.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 258px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ShVM0uE7_1I/AAAAAAAAAMM/T1qFKVv0zo8/s400/greenshot_2009-05-21_08-43-38.png" alt="" id="BLOGGER_PHOTO_ID_5338257401923239762" border="0" /&gt;&lt;/a&gt;
To keep this part of the tutorial as simple as can be, the web application will for now only display the gratuitous Hello, World! In the web tier module I created the following source code package and 3 files:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ShF_qD7BdYI/AAAAAAAAAKE/0chHa8lBd6g/s1600-h/greenshot_2009-05-18_11-32-20.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 77px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ShF_qD7BdYI/AAAAAAAAAKE/0chHa8lBd6g/s400/greenshot_2009-05-18_11-32-20.png" alt="" id="BLOGGER_PHOTO_ID_5337187393994847618" border="0" /&gt;&lt;/a&gt;

The contents of each of the above files is shown below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/ShGBbV1O7-I/AAAAAAAAAKU/pl_v_WSFi54/s1600-h/greenshot_2009-05-18_11-40-10.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 274px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/ShGBbV1O7-I/AAAAAAAAAKU/pl_v_WSFi54/s400/greenshot_2009-05-18_11-40-10.png" alt="" id="BLOGGER_PHOTO_ID_5337189340127621090" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ShGB5KCd-RI/AAAAAAAAAKc/c-BCK-Wch_0/s1600-h/greenshot_2009-05-18_11-42-07.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 114px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ShGB5KCd-RI/AAAAAAAAAKc/c-BCK-Wch_0/s400/greenshot_2009-05-18_11-42-07.png" alt="" id="BLOGGER_PHOTO_ID_5337189852357982482" border="0" /&gt;&lt;/a&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ShGCM0OysDI/AAAAAAAAAKk/oT1Ddv9H0vU/s1600-h/greenshot_2009-05-18_11-43-29.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 197px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ShGCM0OysDI/AAAAAAAAAKk/oT1Ddv9H0vU/s400/greenshot_2009-05-18_11-43-29.png" alt="" id="BLOGGER_PHOTO_ID_5337190190101475378" border="0" /&gt;&lt;/a&gt;The web.xml file which is located under the Configuration Files tab in the Projects pane needs to be modified as well and should look exactly like the following highlighted text:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ShGDirrr6LI/AAAAAAAAAKs/ZxHLI9yJBnY/s1600-h/greenshot_2009-05-18_11-48-16.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 156px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ShGDirrr6LI/AAAAAAAAAKs/ZxHLI9yJBnY/s400/greenshot_2009-05-18_11-48-16.png" alt="" id="BLOGGER_PHOTO_ID_5337191665275496626" border="0" /&gt;&lt;/a&gt;
As can be seen from the Home.html and Home.java files, the span element with the wicket:id of sayhello will have its contents replaced with Hello, World!

&lt;span style="font-weight: bold;"&gt;Running The Application&lt;/span&gt;

When we build and run the application the following is rendered in the browser:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/ShGIqmMmKHI/AAAAAAAAAK0/d5EKbo8QhmA/s1600-h/greenshot_2009-05-18_12-09-36.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 145px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/ShGIqmMmKHI/AAAAAAAAAK0/d5EKbo8QhmA/s400/greenshot_2009-05-18_12-09-36.png" alt="" id="BLOGGER_PHOTO_ID_5337197298800011378" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;

This concludes Part 1 of the tutorial. As you can see, we have successfully created, built and run a Java EE5 Enterprise Application with a web tier using the Wicket web framework. The application as it now stands is trivial as it only displays the ubiquitous Hello, World! In the next part of this tutorial, Part 2, we will expand on the service side (the EJBs) and in Part 3, we will expand the web tier to consume the services exposed by the EJBs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-6045315088585327197?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/6045315088585327197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/05/wicket-ejb-di-with-netbeans-part-1.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/6045315088585327197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/6045315088585327197'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/05/wicket-ejb-di-with-netbeans-part-1.html' title='Wicket + EJB + DI With Netbeans - Part 1'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_XzLrgIoZ_TU/ShGqXmVRhXI/AAAAAAAAALM/5YP2jXkC_nY/s72-c/greenshot_2009-05-18_14-33-14.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-2050741581552874093</id><published>2009-04-29T08:26:00.008-04:00</published><updated>2009-05-07T07:44:10.886-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sun'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Will We Ever See Netbeans v7?</title><content type='html'>&lt;span style="font-weight: bold;"&gt;With Oracle's acquisition of Sun Microsystems the big question in my mind and those of many dedicated Netbeans users is what will happen to the Netbeans IDE platform? &lt;/span&gt;

Will we ever see a release of Netbeans v7? While the release of Netbeans v6.7 is highly anticipated, its development was begun under the auspices of Sun, who throughout the years has steadfastly committed itself to the platform. Will Oracle follow suit and provide the level of human, financial and organizational capital that will be required to take Netbeans to its next generation?

I guess we will have to wait and see but I think you can guess what I am hoping.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-2050741581552874093?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/2050741581552874093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/04/will-we-ever-see-netbeans-v7.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2050741581552874093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2050741581552874093'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/04/will-we-ever-see-netbeans-v7.html' title='Will We Ever See Netbeans v7?'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-2275182952708107800</id><published>2009-04-05T11:45:00.041-04:00</published><updated>2009-05-12T16:30:12.563-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='loadabledetachablemodel'/><category scheme='http://www.blogger.com/atom/ns#' term='compoundpropertymodel'/><category scheme='http://www.blogger.com/atom/ns#' term='dataview'/><category scheme='http://www.blogger.com/atom/ns#' term='idataprovider'/><title type='text'>JPA/Hibernate and Wicket Repeating Views with Netbeans- Part 2</title><content type='html'>&lt;span style="font-family:courier new;"&gt;[***Note This is the second and final article in this series and requires that you have completed the exercises in the &lt;/span&gt;&lt;a style="font-family: courier new;" href="http://jeff-schwartz.blogspot.com/2009/03/netbeans-apache-wicket-applications.html"&gt;first article&lt;/a&gt;&lt;span style="font-family:courier new;"&gt; in this series. If you haven't already, please do so now before preceding with the exercises in this article.]&lt;/span&gt;

This is the second and final article in this series of using JPA/Hibernate and Wicket repeating views. This article will cover the remaining tasks that will allow us to render the the data from the Customer table in a tabular view to the browser using Apache Wicket repeating views and models.

&lt;span style="font-weight: bold;"&gt;Wicket's Repeating Views&lt;/span&gt;

Wicket's repeating views allow you to render data from a collection of objects, such as a List&lt;customer&gt;&lt;customer&gt;. HTML tables can be used to display the information in the browser where each row in the table represents one item in the List&lt;customer&gt; collection and columns in the table represent each List&lt;customer&gt; item's fields.

The markup we want to generate for this exercise is an HTML table with the following elements:
&lt;ul&gt;&lt;li&gt;A table header with header columns for each of the columns from the Customer table that we want to display. For our exercise, we will display the Customer ID, Customer Discount Code, Customer Zip, and Customer Name columns from the Customer table.
&lt;/li&gt;&lt;li&gt;A table row for each of the Customer entities returned when we query the Customer table for its contents. The cells in these rows will contain data from their corresponding fields in the Customer entity objects that are returned when we query the Customer table. Their corresponding fields are customerId, discountCode, zip, and name.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:courier new;"&gt;[***Note Because there is a one-to-many relationship between the Customer entity and the DiscountCode entity, the customer's discount code can be referenced through the Customer entity. We will see this later when we write the code to actually render the data to the browser.]

&lt;/span&gt;Wicket provides numerous components that render content and markup to the browser. Among these are repeating view components that repetitively render the same markup but with varying content depending on the current item associated with the current view. The item associated with current view in our example is the current Customer entity from a List of Customer entities that we want to render.

&lt;span style="font-weight: bold;"&gt;Models - IModel and IDetachable&lt;/span&gt;

Wicket's components access data through models. This is the Model part in Wicket's Model View Controller implementation. Models are wrappers around data; they keep a reference to the data they are wrapping.

Wicket provides numerous models such as Model, PropertyModel, CompoundPropertyModel, and LoadableDetachableModel to name a few. All models must implement the IModel interface, which publishes two methods:
&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;T&lt;/span&gt; getObject() - returns and object of type &lt;span style="font-style: italic;"&gt;T&lt;/span&gt;.
&lt;/li&gt;&lt;li&gt; &lt;span style="font-style: italic;"&gt;void&lt;/span&gt; setObject(&lt;span style="font-style: italic;"&gt;T&lt;/span&gt; object) - set the model data to object of type &lt;span style="font-style: italic;"&gt;T&lt;/span&gt;.
&lt;/li&gt;&lt;/ul&gt; IModel also extends the IDetachable interface which publishes one method:
&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;void&lt;/span&gt; detach() - detaches the model data and is called after rendering has completed.
&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Wicket Is A Stateful Framework&lt;/span&gt;

Wicket is a stateful web framework; at the end of a request, after the markup has been sent to the browser, Wicket stores the page, component hierarchy, and associated models (state) in the page store. Since models keep references to their data, data will also be stored if it hasn't been detached from the model first. In order for the data to be stored it must be serializeable. Detaching the data from a model reduces the memory overhead on the server and also allows models to be associated with data that isn't serializeable.

&lt;span style="font-weight: bold;"&gt;LoadableDetachableModel&lt;/span&gt;

Wicket provides an abstract implementation of a detachable model, LoadableDetachableModel. &lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;It is a model that can be serialized to the page store without its data; its reference to its data is declared as transient. &lt;customer&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;It implements IModel and IDetachable.

LoadableDetachableModel calls its load method when the view component it is attached to needs access to its data. This allows clients, which implement this method, to load the data it wraps from any data source, a database for instance.

We will see an example of using the LoadableDetachableModel later in the exercise when we implement the code for the view.

&lt;span style="font-weight: bold;"&gt;DataView

&lt;/span&gt;The DataView is a repeating view component. It makes it very simple to populate a repeating view from a database. DataView's are constructed as follows:&lt;/customer&gt;
&lt;ul&gt;&lt;li&gt;protected DataView(String id, IDataProvider&lt;t&gt; dataProvider)&lt;/t&gt;&lt;/li&gt;&lt;li&gt;protected DataView(String id, IDataProvider&lt;t&gt; dataProvider, int itemsPerPage)&lt;/t&gt;&lt;/li&gt;&lt;/ul&gt;&lt;customer&gt;Both constructors take an id of String as their first parameter.  Its value must be set to the wicket:id attribute of the HTML tag we are attaching the DataView component to.

Both constructors take an IDataProvider as their second parameter. &lt;/customer&gt;The IDataProvider acts as an interface between the database and the Dataview.&lt;customer&gt;

itemsPerPage, an int, can be passed as a third parameter and is used when implementing pagination.

For this article, we will use the first constructor, which takes only two parameters, an id and an IDataprovider.

&lt;span style="font-weight: bold;"&gt;The IDataProvider Interface - a wrapper around data&lt;/span&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;

IDataProvier is really nothing more than a wrapper around a collection. It &lt;customer&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;extends IDetachable and publishes three methods that must be implemented:
&lt;ul&gt;&lt;li&gt;iterator(int first, int count) - Gets an iterator for the subset of total data.&lt;/li&gt;&lt;li&gt;model(T object - Callback used by the consumer of this data provider to wrap the object retrieved from the iterator(int, int) with a model (usually a detachable one).
&lt;/li&gt;&lt;li&gt;size() - Gets the total number of items in the collection represented by the DataProvider.&lt;/li&gt;&lt;/ul&gt;&lt;/customer&gt;&lt;customer&gt;&lt;span style="font-weight: bold;"&gt;Implementing an IDataProvider&lt;/span&gt;

Below is the implementation of IDataProvieder that will be used by our DataView component:&lt;/customer&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/Sds_LVrNp3I/AAAAAAAAAGc/P3IH2_vKF9k/s1600-h/4-7-2009+7-54-25+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 314px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/Sds_LVrNp3I/AAAAAAAAAGc/P3IH2_vKF9k/s400/4-7-2009+7-54-25+AM.png" alt="" id="BLOGGER_PHOTO_ID_5321916848697878386" border="0" /&gt;&lt;/a&gt;
&lt;customer&gt;Let's discuss each of the methods in our implementation of IDataProvider:
&lt;ul&gt;&lt;li&gt;iterator calls the CustomerJpaController's findCustomerEntities method with 2 parameters, count and first and will return an Iterator for the list of Customer objects that the findCustomerEntities method returns.&lt;/li&gt;&lt;li&gt;size calls the CustomerJpaController's getCustomerCount method to get the count of Customers and returns the result.&lt;/li&gt;&lt;li&gt;model creates and returns an anonymous LoadableDetachableModel&lt;customer&gt; object which wraps our Customer entity object which will be detached after rendering has completed.&lt;/customer&gt;&lt;/li&gt;&lt;li&gt;detach has an empty implementation because we do not have any models directly associated with our implementation of IDataProvider that need to be detached.
&lt;/li&gt;&lt;/ul&gt;We create an anonymous instance of the DataView component and add it to our HomePage as follows:&lt;/customer&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SdtD27V4bsI/AAAAAAAAAGk/bZGd1UVmerU/s1600-h/4-7-2009+8-14-38+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 172px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SdtD27V4bsI/AAAAAAAAAGk/bZGd1UVmerU/s400/4-7-2009+8-14-38+AM.png" alt="" id="BLOGGER_PHOTO_ID_5321921995589840578" border="0" /&gt;&lt;/a&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;
There are a few things to notice in the above code:
&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;ul&gt;&lt;li&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;We are attaching the DataView to an HTML element whose wicket:id is rows. We will discuss the HomePage.html markup later.&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/li&gt;&lt;li&gt;populateItem will be called by the DataView component for each Customer object provided by customerDataProvider.
&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/li&gt;&lt;li&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;We are using a CompoundPropertyModel to bind the fields in the the Customer object to the four Label components. &lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;The field in the Customer object is identified by the id we pass to each Label's constructor.&lt;/li&gt;&lt;li&gt;Because there is a 1 to many relationship between the Customer and the DiscountCode entity objects, we must use discountCode.discountCode to reference the discountCode field in the DiscountCode entity associated with the Custmoer entity.
&lt;/li&gt;&lt;/ul&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;Here is the complete code for HomePage.java:&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdtGc7kiz7I/AAAAAAAAAGs/l5zcoqogvwA/s1600-h/4-7-2009+8-23-29+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 234px; height: 400px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdtGc7kiz7I/AAAAAAAAAGs/l5zcoqogvwA/s400/4-7-2009+8-23-29+AM.png" alt="" id="BLOGGER_PHOTO_ID_5321924847509622706" border="0" /&gt;&lt;/a&gt;
&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;&lt;customer&gt;Here is the complete markup for HomePage.html. Notice how each of the wicket:id attribute values match the id values we passed to our DataView and four Labels :

&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdtKe3fSinI/AAAAAAAAAG0/PQlOpCaYMbY/s1600-h/4-7-2009+8-42-42+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 200px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdtKe3fSinI/AAAAAAAAAG0/PQlOpCaYMbY/s400/4-7-2009+8-42-42+AM.png" alt="" id="BLOGGER_PHOTO_ID_5321929278820092530" border="0" /&gt;&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;Add some styling to our page&lt;/span&gt;

Lets add some styling to our page:
&lt;ol&gt;&lt;li&gt;Right click the Web Pages node in the Projects pane and select New | Other which will open the New File window.&lt;/li&gt;&lt;li&gt;Select Web from the Categories pane and select Cascading Style Sheet from the File Types pane and click Next.&lt;/li&gt;&lt;li&gt;Enter style for the CSS File Name and click Finish which will open the style.css file in the editor.&lt;/li&gt;&lt;/ol&gt;Add the following styling attributes to the style.css file:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SdtOu75bjlI/AAAAAAAAAHE/JeywvkkMLys/s1600-h/4-7-2009+8-51-17+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 272px; height: 332px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SdtOu75bjlI/AAAAAAAAAHE/JeywvkkMLys/s400/4-7-2009+8-51-17+AM.png" alt="" id="BLOGGER_PHOTO_ID_5321933952927895122" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Modify CustomerJpaController

&lt;/span&gt;Lets modify the JPA query in the CustomerJpaController class to return our Customer entities in ascending CustomerId order:
&lt;ol&gt;&lt;li&gt;Fully expand the Source Packages node in the Projects pane and double click the CustomerJpaController node. This will open the file in the editor.&lt;/li&gt;&lt;li&gt;Locate the &lt;customer&gt;findCustomerEntities(boolean all, int maxResults, int firstResult) method and add order by o.customerId to the JPA query string.&lt;/customer&gt;&lt;/li&gt;&lt;/ol&gt;The complete code for the method should now look like the following:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SdtSew_dseI/AAAAAAAAAHU/qRdzqtdnbkg/s1600-h/4-7-2009+9-10-12+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 119px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SdtSew_dseI/AAAAAAAAAHU/qRdzqtdnbkg/s400/4-7-2009+9-10-12+AM.png" alt="" id="BLOGGER_PHOTO_ID_5321938073169015266" border="0" /&gt;&lt;/a&gt;
Now lets run the project.

&lt;span style="font-weight: bold;"&gt;Run the project&lt;/span&gt;

Run the project by right clicking the project node in the Projects pane and selecting Run which will open your browser and render the following:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SdtPU6NgikI/AAAAAAAAAHM/lhK4Xtq3xyM/s1600-h/4-7-2009+9-03-20+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 395px; height: 400px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SdtPU6NgikI/AAAAAAAAAHM/lhK4Xtq3xyM/s400/4-7-2009+9-03-20+AM.png" alt="" id="BLOGGER_PHOTO_ID_5321934605310265922" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;
&lt;ul&gt;&lt;li&gt;We create a Wicket DataView to render repeating data in an HTML table to the browser.&lt;/li&gt;&lt;li&gt;We implement an instance of IDataProvider to act as an interface between the database and the DataView.&lt;/li&gt;&lt;li&gt;Our implementation of IDataProvider's model method creates and returns a LoadableDetachable model.&lt;/li&gt;&lt;li&gt;We assign a CompoundPropertyModel to the view, wrapping the Customer object.&lt;/li&gt;&lt;li&gt;We create four Label components. Each is bound to a field in the Customer object. The field in the Customer object is identified by the id we pass to each Label's constructor.
&lt;/li&gt;&lt;li&gt;We modified our JPA query to return our Customer entities in customerId order.&lt;/li&gt;&lt;/ul&gt;Well, that concludes our discussion of working with JPA/Hibernate and Wicket repeating views with Netbeans. Please note that you are not limited to using Hibernate as your persistence provider; the same principles we applied here will work with any JPA compatible persistence provider, such as EclipseLink. Similarly, these techniques will work with a number of database systems, such as MySql for example.

In a future post, I will discuss what I believe to be is a more efficient, effective and easier method of working with JPA and Wicket. Using Netbeans v6.5 I will demonstrate how to create a Java EE5 enterprise application and create EJBs that provide back-end database services through dependency injection to a Wicket web application. Stay tuned!&lt;/customer&gt;&lt;/customer&gt;&lt;/customer&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-2275182952708107800?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/2275182952708107800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/04/apache-wicket-jpahibernate-and-wicket.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2275182952708107800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/2275182952708107800'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/04/apache-wicket-jpahibernate-and-wicket.html' title='JPA/Hibernate and Wicket Repeating Views with Netbeans- Part 2'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_XzLrgIoZ_TU/Sds_LVrNp3I/AAAAAAAAAGc/P3IH2_vKF9k/s72-c/4-7-2009+7-54-25+AM.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-7115235182613496663</id><published>2009-03-31T11:40:00.039-04:00</published><updated>2009-05-12T16:29:43.133-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='jpa'/><category scheme='http://www.blogger.com/atom/ns#' term='jar'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='library'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><category scheme='http://www.blogger.com/atom/ns#' term='derby'/><title type='text'>JPA/Hibernate and Wicket Repeating Views with Netbeans- Part 1</title><content type='html'>&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;This is the first part in a multi-part series of articles that will teach you how to create Web applications that use the Apache Wicket Web framework and JPA/Hibernate. In particular, these articles will demonstrate the following:
&lt;ul&gt;&lt;li&gt;Using Netbeans to create Mavan based Apache Wicket projects.&lt;/li&gt;&lt;li&gt;Using Netbeans to add and configure Hibernatea, a JPA comaptable Persistence provider to the project.&lt;/li&gt;&lt;li&gt;Render tabular data from a database to the browser using Apache Wicket repeating views and models.
&lt;/li&gt;&lt;/ul&gt;At the end of this series of articles we will have created an Apache Wicket Web application that retrieves data from a database using JPA and Hibernate and formats the data in a tabular view in the browser using an Apache Wicket DataView control.

This article, the first in this series, will cover the following topics:
&lt;ul&gt;&lt;li&gt;Creating a Maven Apache Wicket Web project in Netbeans&lt;/li&gt;&lt;li&gt;Configuring the project to use JPA and Hibernate.
&lt;/li&gt;&lt;li&gt;Adding the required libraries to the project using Maven&lt;/li&gt;&lt;li&gt;Mapping POJOs to Database tables using JPA support in Netbeans.&lt;/li&gt;&lt;li&gt;Creating a JPA utility class that adds CRUD capability using JPA support in Netbeans&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:courier new;"&gt;***Note - There are numerous ways to configure the 3 layers (presentation, business, and domain) found in 3-tier Java applications. In this article we will employ a direct approach; we will use tight-coupling that binds our code directly to the JPA persistence service. In future articles we will explore using other methods such as Spring IOC (Inversion Of Control) and EJB (Enterprise Java Beans) to layer the different services in loosely coupled fashion.&lt;/span&gt;

&lt;span style="font-weight: bold;"&gt;You will need the following to complete this exercise:&lt;/span&gt;
&lt;ul&gt;&lt;li&gt;Netbeans v6.5 or greater&lt;/li&gt;&lt;li&gt;Maven Netbeans Plugin &lt;/li&gt;&lt;li&gt;Derby Sample Database which should have been installed when you downloaded and installed Netbeans&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Creating a Maven Apache Wicket Web project in Netbeans&lt;/span&gt;

To create the project that will serve as the foundation for the remainder of this series of artices, please review and follow the exercises in my previous article, &lt;a href="http://jeff-schwartz.blogspot.com/2009/03/netbeans-maven-projects.html"&gt;Netbeans Maven Projects&lt;/a&gt;. This will give you a good overview of Maven, and creating an Apache Wicket Maven based project using Netbeans.

Once you have completed creating the project, please start Netbeans and open the project.

&lt;span style="font-weight: bold;"&gt;Remove the junit test files from the project
&lt;/span&gt;
Testing with junit is a good practice but we won't need to use it for this exercise, so we will remove the project's test classes. Instead of physically deleting them, however, we will use Netbeans' safe delete option to remove them from the project. Please follow these steps:
&lt;ol&gt;&lt;li&gt;Completely expand the Test Packages node in the Projects pane and select both the Start.java and TestHomePage.java files&lt;/li&gt;&lt;li&gt;Right click and select Delete which will open the Delete window.&lt;/li&gt;&lt;li&gt;Click the Safely delete checkbox so that it is checked and then click the Refactor button. This will remove the 2 files from the project but will not delete them.
&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Adding JPA and Hibernate to the project

&lt;/span&gt;Please follow these steps to add JPA and Hibernate to the project:&lt;ol&gt;&lt;li&gt;Right click the project node in the Projects pane and select New | Other. This will open the New File window. Now select Persistence from the Categories pane and Entity Classes from Database from the File Types pane as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdNirfOIR2I/AAAAAAAAAEM/Lmah284rLyo/s1600-h/4-1-2009+8-47-29+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 279px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdNirfOIR2I/AAAAAAAAAEM/Lmah284rLyo/s400/4-1-2009+8-47-29+AM.png" alt="" id="BLOGGER_PHOTO_ID_5319704084109346658" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Click the Next button and in the Database connection drop down menu select the jdbc derby sample database. In the Available Tables list box select Customer an click the Add button which will then add the Customer and the Discount_Code tables to be included in the Selected Tables list box as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SdNkareRRvI/AAAAAAAAAEU/bnIEQNzQFcU/s1600-h/4-1-2009+8-55-19+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 264px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SdNkareRRvI/AAAAAAAAAEU/bnIEQNzQFcU/s400/4-1-2009+8-55-19+AM.png" alt="" id="BLOGGER_PHOTO_ID_5319705994363750130" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Now click the Next button and in the Package text field enter Hibernate for the name of the Java package and then click the Create Persistence Unit button which will open the Create Persistence Unit window.
&lt;/li&gt;&lt;li&gt;From the Persistence Library drop down menu please select Hibernate and then click the Create button which will close the Create Persistence Unit window.&lt;/li&gt;&lt;li&gt;Now click Next and Finish which will close the New Entity Classes from Database window.&lt;/li&gt;&lt;/ol&gt;As a result of the above steps, Netbeans has added numerous files to our project. If you fully expand Other Sources node in the Projects pane you will see that Netbeans has added the persistence.xml file to our project. This is the file that is used by JPA to cinfigure persistence at runtime. If you double click the persistence.xml file node it will open in the editor. In this file you can see that there is a Provider tag that specifies that we have chosen Hibernate as the  persistence provider:

&lt;div style="text-align: center;"&gt;    &amp;lt;provider&amp;gt;org.hibernate.ejb.HibernatePersistence&amp;lt;/provider&amp;gt;

&lt;div style="text-align: left;"&gt;You can also see that there are 2 class tags which identify the Java classes that represent our business entity classes, Customer and DiscountCode:

&lt;div style="text-align: center;"&gt; &amp;lt;class&amp;gt;hibernate.Customer&amp;lt;/class&amp;gt;
&amp;lt;class&amp;gt;hibernate.DiscountCode&amp;lt;/class&amp;gt;
&lt;div style="text-align: left;"&gt;
In addition to the above tags, there are numerous property tags that are used to identify the database driver, username and password, connection url and cache provider. JPA uses these properties at run time as well to connect to the da.

Please fully expand the libraries node in the Project pane and you will notice that the hibernate-3.2.5.ga.jar Hibernate library has been added to our project. Later, we will use Netbeans' Maven support to replace this library with a more recent version.
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
Please fully expand the Source Packages node in the Project pane. Notice that 2 Pojos, Customer.java and DiscountCode.java, our entity classes, have been added and are located in the hibernate package as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SdNt5UfKOjI/AAAAAAAAAEc/CpQqL0Wt_lI/s1600-h/4-1-2009+9-35-59+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 207px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SdNt5UfKOjI/AAAAAAAAAEc/CpQqL0Wt_lI/s400/4-1-2009+9-35-59+AM.png" alt="" id="BLOGGER_PHOTO_ID_5319716416374061618" border="0" /&gt;&lt;/a&gt;Double click each Pojo and they will open in Netbeans' Java editor window. Notice how each Pojo has numerous errors which we will now correct by adding libraries to our project using Netbeans' Maven support.

&lt;span style="font-weight: bold;"&gt;Replacing and adding libraries to our project
&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;
&lt;/span&gt;We need to replace and add a few libraries to our project. We will use Netbeans Maven support to do this. First, lets replace the hibernate-3.2.5.ga.jar with a more recent version.

Right click the Libraries node in the Project pane and select Add Library. This will open the Add Library window, which will allow us to search for the most recent version of this library. Please follow these steps:
&lt;ol&gt;&lt;li&gt;In the GroupId text box enter org.hibernate&lt;/li&gt;&lt;li&gt;In the ArtifactId text box press the space bar on your keyboard. This will open a list of all the Artifacts that are identified by the org.hibernate GroupId we entered.&lt;/li&gt;&lt;li&gt;From this list select Hibernate.&lt;/li&gt;&lt;li&gt;In the Version text box press the space bar on your keyboard. This will open a list of all the different versions that are available for this library. &lt;/li&gt;&lt;li&gt;Select 3.2.6.ga from the list. &lt;/li&gt;&lt;/ol&gt;The Add Library window should now appear as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdN58Qo8JEI/AAAAAAAAAEk/YBUdnp0Mn0Q/s1600-h/4-1-2009+10-27-22+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 396px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdN58Qo8JEI/AAAAAAAAAEk/YBUdnp0Mn0Q/s400/4-1-2009+10-27-22+AM.png" alt="" id="BLOGGER_PHOTO_ID_5319729661020480578" border="0" /&gt;&lt;/a&gt;
Click the Ok button to close this window. We have replaced the hibernate-3.2.5.ga.jar with the hibernate-3.2.6.ga.jar and you can confirm this by expanding the Libraries node in the Project window.

Next we need to add support JPA/Hibernate annotations. We will do this using the same procedure above by right clicking the Libraries pane in the Project window, selecting Add Library which will open the Add Library window, which will allow us to search for the most recent version of this library. Please follw these steps:
&lt;ol&gt;&lt;li&gt;In the GroupId text box enter org.hibernate&lt;/li&gt;&lt;li&gt;In the ArtifactId text box press the space bar on your keyboard. This will open a list of all the Artifacts that are identified by the org.hibernate GroupId we entered.&lt;/li&gt;&lt;li&gt;From this list select hibernate-annotations.&lt;/li&gt;&lt;li&gt;In the Version text box press the space bar on your keyboard. This will open a list of all the different versions that are available for this library. &lt;/li&gt;&lt;li&gt;Select 3.4.0.GA from the list. &lt;/li&gt;&lt;/ol&gt; The Add Library window should now appear as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SdN-9iuyMnI/AAAAAAAAAE0/TclJvvX54Eg/s1600-h/4-1-2009+10-48-32+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 396px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SdN-9iuyMnI/AAAAAAAAAE0/TclJvvX54Eg/s400/4-1-2009+10-48-32+AM.png" alt="" id="BLOGGER_PHOTO_ID_5319735180614840946" border="0" /&gt;&lt;/a&gt;
Click the Ok button to close this window. We have added the hibernate-annotations-3.4.0.GA.jar and you can confirm this by expanding the Libraries node in the Project window.

Next we need to add support for Hibernate entity management. We will do this using the same procedure above by right clicking the Libraries pane in the Project window, selecting Add Library which will open the Add Library window, which will allow us to search for the most recent version of this library. Please follw these steps:
&lt;ol&gt;&lt;li&gt;In the GroupId text box enter org.hibernate&lt;/li&gt;&lt;li&gt;In the ArtifactId text box press the space bar on your keyboard. This will open a list of all the Artifacts that are identified by the org.hibernate GroupId we entered.&lt;/li&gt;&lt;li&gt;From this list select hibernate-entitymanager.&lt;/li&gt;&lt;li&gt;In the Version text box press the space bar on your keyboard. This will open a list of all the different versions that are available for this library. &lt;/li&gt;&lt;li&gt;Select 3.4.0.GA from the list. &lt;/li&gt;&lt;/ol&gt; The Add Library window should now appear as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdOPvTn8YNI/AAAAAAAAAFE/n2i6xyFNB0E/s1600-h/4-1-2009+11-57-58+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 396px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdOPvTn8YNI/AAAAAAAAAFE/n2i6xyFNB0E/s400/4-1-2009+11-57-58+AM.png" alt="" id="BLOGGER_PHOTO_ID_5319753627739119826" border="0" /&gt;&lt;/a&gt;
Click the Ok button to close this window. We have added the hibernate-entitymanager-3.4.0.GA.jar and you can confirm this by expanding the Libraries node in the Project window.

Next we need to add javax.persistence support. We will do this using the same procedure above by right clicking the Libraries pane in the Project window, selecting Add Library which will open the Add Library window, which will allow us to search for the most recent version of this library. Please follw these steps:
&lt;ol&gt;&lt;li&gt;In the GroupId text box enter javax.persistence&lt;/li&gt;&lt;li&gt;In the ArtifactId text box press the space bar on your keyboard. This will open a list of all the Artifacts that are identified by the org.hibernate GroupId we entered.&lt;/li&gt;&lt;li&gt;From this list select persistence-api.&lt;/li&gt;&lt;li&gt;In the Version text box press the space bar on your keyboard. This will open a list of all the different versions that are available for this library. &lt;/li&gt;&lt;li&gt;Select 1.0 from the list. &lt;/li&gt;&lt;/ol&gt; The Add Library window should now appear as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SdOSTHPWpyI/AAAAAAAAAFM/YBOWJBItr3A/s1600-h/4-1-2009+12-11-07+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 396px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SdOSTHPWpyI/AAAAAAAAAFM/YBOWJBItr3A/s400/4-1-2009+12-11-07+PM.png" alt="" id="BLOGGER_PHOTO_ID_5319756441913304866" border="0" /&gt;&lt;/a&gt;
Click the Ok button to close this window. We have added the persistence-api-1.0.jar and you can confirm this by expanding the Libraries node in the Project window.

Next we need to add Derby database driver support. We will do this using the same procedure above by right clicking the Libraries pane in the Project window, selecting Add Library which will open the Add Library window, which will allow us to search for the most recent version of this library. Please follw these steps:
&lt;ol&gt;&lt;li&gt;In the GroupId text box enter org.apache.derby&lt;/li&gt;&lt;li&gt;In the ArtifactId text box press the space bar on your keyboard. This will open a list of all the Artifacts that are identified by the org.hibernate GroupId we entered.&lt;/li&gt;&lt;li&gt;From this list select derbyclient.&lt;/li&gt;&lt;li&gt;In the Version text box press the space bar on your keyboard. This will open a list of all the different versions that are available for this library. &lt;/li&gt;&lt;li&gt;Select 10.4.2.0 from the list. &lt;/li&gt;&lt;/ol&gt; The Add Library window should now appear as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdOUhLDFIQI/AAAAAAAAAFU/g41qs-XOlF8/s1600-h/4-1-2009+12-20-47+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 396px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdOUhLDFIQI/AAAAAAAAAFU/g41qs-XOlF8/s400/4-1-2009+12-20-47+PM.png" alt="" id="BLOGGER_PHOTO_ID_5319758882476990722" border="0" /&gt;&lt;/a&gt;
Click the Ok button to close this window. We have added the derbyclient-10.4.2.0.jar and you can confirm this by expanding the Libraries node in the Project window.

Next we need to add support for transactions. We will do this using the same procedure above by right clicking the Libraries pane in the Project window, selecting Add Library which will open the Add Library window, which will allow us to search for the most recent version of this library. Please follw these steps:
&lt;ol&gt;&lt;li&gt;In the GroupId text box enter javax.transaction&lt;/li&gt;&lt;li&gt;In the ArtifactId text box press the space bar on your keyboard. This will open a list of all the Artifacts that are identified by the org.hibernate GroupId we entered.&lt;/li&gt;&lt;li&gt;From this list select jta.&lt;/li&gt;&lt;li&gt;In the Version text box press the space bar on your keyboard. This will open a list of all the different versions that are available for this library. &lt;/li&gt;&lt;li&gt;Select 1.1 from the list. &lt;/li&gt;&lt;/ol&gt; The Add Library window should now appear as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SdOBeCPjM3I/AAAAAAAAAE8/UFRHZ8LbBTM/s1600-h/4-1-2009+10-59-27+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 396px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SdOBeCPjM3I/AAAAAAAAAE8/UFRHZ8LbBTM/s400/4-1-2009+10-59-27+AM.png" alt="" id="BLOGGER_PHOTO_ID_5319737937852838770" border="0" /&gt;&lt;/a&gt;
Click the Ok button to close this window. We have added the jta-1.1.jar and you can confirm this by expanding the Libraries node in the Project window.

We have added all the libraries that we will need to run and test our project. Build the project by right clicking the project node in the Projects pane and select Build. Your project should build without any errors.

&lt;span style="font-weight: bold;"&gt;Creating a JPA Controller Class&lt;/span&gt;

A JPA Controller class provides methods that support CRUD operations. We could write this ourselves but we can have Netbeans generate this class for us. To do so, please follow these steps:
&lt;ol&gt;&lt;li&gt;Right click the project node in the Project pane and select New | Other. This will open the New File window. &lt;/li&gt;&lt;li&gt;Select Persistence from the Categories pane and JPA Controller Classes from Entity Classes from the File Types pane and click Next.&lt;/li&gt;&lt;li&gt;Click Add All to add the 2 available entity classes to the list of selected entity classes and click Next.&lt;/li&gt;&lt;li&gt;Select hibernate from the Package drop down menu and then click Finish.&lt;/li&gt;&lt;/ol&gt;Netbeans has added the CustomerJPAController.java file to our hibernate package and created a new hibernate.exceptions package which contains numerous files for dealing with persistence exceptions that can occur.

If you double click on the CustomerJPAController.java file in the hibernate package it will open in the Netbeans Java editor. Please take a few minutes to look at the code that was generated in this file. There are methods for your basic CRUD  operations including transaction support. We will take advantage of the findCustomerEntities method to retrieve a list of Customer entities.

&lt;span style="font-weight: bold;"&gt;Developing a testing strategy&lt;/span&gt;

We need to test our project to prove the following:
&lt;ul&gt;&lt;li&gt;We can connect to the sample Derby database.&lt;/li&gt;&lt;li&gt;We can query the Customer table to return all the rows.
&lt;/li&gt;&lt;li&gt;We can get a list of Customer entities as a result from the query and the list contains the correct number of entities.
&lt;/li&gt;&lt;/ul&gt;We can determine the correct number of Customer entities that should be returned by viewing the contents of the Customer table using Netbeans database support. Please follow these steps:
&lt;ol&gt;&lt;li&gt;In the Services window, expand the Databases node and right click the jdbc derby sample database node and then select Connect to connect to the database.&lt;/li&gt;&lt;li&gt;Once the connection to the database is made, expand the Tables node, right click the Customer table and select View Data. This will open a SQL Command window.
&lt;/li&gt;&lt;/ol&gt;In the SQL Command window you should see a result set containing all the rows in the Customer table, and the total number of rows returned should be indicated as well. When I run this it indicates that there are 13 rows of data but your results may be different. What is important is that we now know that our test should confirm the number that you see when you display the contents of the Customer table in the SQL Command window:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SdOgbm5AqGI/AAAAAAAAAFc/0i4uzxh9EAI/s1600-h/4-1-2009+1-11-15+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 237px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SdOgbm5AqGI/AAAAAAAAAFc/0i4uzxh9EAI/s400/4-1-2009+1-11-15+PM.png" alt="" id="BLOGGER_PHOTO_ID_5319771981011265634" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Adding code to HomePage.java to test&lt;/span&gt;

Now lets add the code to test our project. Please follow these steps:
&lt;ol&gt;&lt;li&gt;Fully expand the Source Packages node in the Projects pane and double click the HomePage.java file which will open the file in the Netbeans Java editor window.&lt;/li&gt;&lt;li&gt;Add this method to the HomePage class:

private void TestDatabase(){
CustomerJpaController custcont = new CustomerJpaController();
int i = custcont.findCustomerEntities().size();
System.out.println("custcont.findCustomerEntities() returned " +
Integer.valueOf(i)   +  " Customer entities");
}

&lt;/li&gt;&lt;li&gt;Modify the HomePage constructor to call our new method. The constructor should look like the following:

public HomePage(final PageParameters parameters) {
// call out method
TestDatabase();

// Add the simplest type of label
add(new Label("message",
  "If you see this message wicket is properly configured and running"));
}&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Testing our application&lt;/span&gt;

Right click the project node in the Projects pane and select Run. This could take a few moments because Maven may need to download dependencies from a Maven repository if they aren't already in your local repository. Once the project builds without errors it will be deployed to the server and then it will run. You should see the output in your browser. Now switch back to Netbeans and click on the Server tab in the Output window. Scroll down to the bottom of the window and you should see something like the following:
&lt;ul&gt;&lt;li&gt;INFO: custcont.findCustomerEntities() returned 13 Customer entities&lt;/li&gt;&lt;/ul&gt;13 exactly matches the number of rows returned when I displayed the contents of the Customer table. We have confirmed that we can connect, query and get results back from our database.

Job well done!

&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;
&lt;ul&gt;&lt;li&gt;We added all the latest versions of the required libraries.&lt;/li&gt;&lt;li&gt;We configured JPA/Hibernate.&lt;/li&gt;&lt;li&gt;We added 2 Pojos to represent our domain objects.&lt;/li&gt;&lt;li&gt;We added CRUD support.
&lt;/li&gt;&lt;li&gt;We created a testing strategy.&lt;/li&gt;&lt;li&gt;We tested and confirmed that our application works as anticipated.&lt;/li&gt;&lt;/ul&gt; &lt;span style="font-weight: bold;"&gt;What's Next&lt;/span&gt;

In the next article in this series we will add to our project, giving it the ability to display the contents of the Customer table in the browser. We will use Apache Wicket models and the DataView control to implement the displaying of the data.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-7115235182613496663?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/7115235182613496663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/03/netbeans-apache-wicket-applications.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/7115235182613496663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/7115235182613496663'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/03/netbeans-apache-wicket-applications.html' title='JPA/Hibernate and Wicket Repeating Views with Netbeans- Part 1'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_XzLrgIoZ_TU/SdNirfOIR2I/AAAAAAAAAEM/Lmah284rLyo/s72-c/4-1-2009+8-47-29+AM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-4072503693850759548</id><published>2009-03-26T08:50:00.032-04:00</published><updated>2009-03-27T10:58:02.295-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Netbeans Maven Projects</title><content type='html'>Developing  Java applications today is a lot like building with Lego blocks. Applications are typically composed of numerous modules and libraries, some of which you write yourself and others which are obtained from open source projects. Relying on open source to provide functionality to your applications offers many advantages. Following the DRY (Don't Repeat Yourself) principle, why recreate the wheel?
&lt;ul&gt;&lt;li&gt;Feedback on the Web is readily available; just Google the library or functionality you are interested in. Chatter on the web will either confirm your choice or send you looking elsewhere.&lt;/li&gt;&lt;li&gt;Bug issues can often be resolved by a quick Google search.&lt;/li&gt;&lt;li&gt;Numerous support groups are available for the most popular open source projects.
&lt;/li&gt;&lt;/ul&gt;Incorporating open source into your application brings a unique set of challenges. Many open source projects rely on other open source projects to provide APIs and/or implementations to their products. This is, after all, just another example of the DRY principle.

For example, numerous open source libraries incorporate logging but instead of 'hard coding' to a specific logging implementation, such as Log4J, they code to the  commons-logging  or the
Simple Logging Facade for Java (SLF4J) library, which are open source projects which act as a bridge between different logging implementations. This is an example of the Service Provider pattern where an API and possibly abstract classes provide a contract and that contract is fulfilled by numerous implementations.

So how does one create applications today when faced with piecing them together from the Lego blocks made up of open source libraries and where the challenge is in resolving all the interdependencies between libraries that exist in such an environment? Trying to manually create a build script and gather all the required libraries and their correct versions has become a monumental task. It would be far better if there were a means of offloading this responsibility from the developer. That is where Maven comes into play.

&lt;span style="font-weight: bold;"&gt;Maven&lt;/span&gt;

Maven  is defined on the Apache Maven project's web site as follows:
&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;Maven is a software project management and comprehension tool. Based on the concept of a project object model         (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.&lt;/span&gt;&lt;/blockquote&gt;As far as descriptions go, the above is obviously acurate. But what it doesn't describe is how Maven actually resolves the issues of dependency when developing applications in today's open source environment.

Imagine that you are a provider of an open source library. If your library is anything other than trivial, you most likely incorporate other open source libraries to satisfy some API, feature or functionality. You test your library and once you are satisfied that your library works as expected you publish it and make it available to the open source community. But you also provide a POM that users of your library can use to incorporate your library into their own Maven based projects. The POM not only 'defines' your library but also defines all the dependencies that your library has on other libraries. You publish your POM on one of the POM repositories so that other developers can discover it and use it to incorporate your library into their applications.

Now imagine that you are a developer writing the next killer Web application and you want to incorporate the functionality provided by the open source library mentioned above. Using Maven, how would you do that and how would you do that using the Netbeans IDE?

Well, Netbeans provides excellent support for Maven based projects. In Netbeans v6.5, this support comes in the form of a Netbeans plugin. My understanding is that future versions of Netbeans will incorporate Maven directly and will not require a plugin to provide Maven project support.

&lt;span style="font-weight: bold;"&gt;Installing The Netbeans Maven Plugin&lt;/span&gt;
&lt;span style="font-weight: bold;"&gt;
&lt;/span&gt;If you haven't already installed the Netbeans Maven plugin, doing so is easy. Please follow the steps below:
&lt;ol&gt;&lt;li&gt;Open Netbeans v6.5.&lt;/li&gt;&lt;li&gt;Select Tools | Plugins from the main menu. This will open up the Plugins window. &lt;/li&gt;&lt;li&gt;Select the Available Plugins tab and type 'Maven' into the search text box which is located above and to the right of the Plugin window's main two pannels. &lt;/li&gt;&lt;li&gt;Select the Maven plugin and click the Install button located beneath and to the left of the Plugin window's main two pannels. &lt;/li&gt;&lt;/ol&gt;Follow the prompts. When all is completed you will have installed Maven project support into the Netbeans IDE.

&lt;span style="font-weight: bold;"&gt;Creating a Netbeans Maven&lt;span style="font-weight: bold;"&gt; Based Project
&lt;/span&gt;&lt;/span&gt;
I will use Netbeans' Maven project support to create a Web project based on the Apache Wicket framework. To create a Wicket application please follow the steps below:

&lt;ol&gt;&lt;li&gt;Open Netbeans v6.5.&lt;/li&gt;&lt;li&gt;Select File | New Project from the main menu. This will open the New Project window.&lt;/li&gt;&lt;li&gt;Select Maven from the Categories pannel and Maven Project from the Projects pannel and click the Next button on the bottom of the New Project window.
&lt;/li&gt;&lt;li&gt;In the Maven Archetypes list box select Archetypes from remote Maven Repositories. Notice that when you select this option that Netbeans goes out to the Maven Repositores and discovers all the Archetypes available there and presents these as available options for your selection. In the list of available Archetypes select Wicket Quickstart Archetype as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/ScuisImiZoI/AAAAAAAAADM/wH_BUxDikp4/s1600-h/3-26-2009+11-37-53+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 262px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/ScuisImiZoI/AAAAAAAAADM/wH_BUxDikp4/s400/3-26-2009+11-37-53+AM.png" alt="" id="BLOGGER_PHOTO_ID_5317522664148067970" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Click the Next button and then click Finish. Netbeans will now create a Maven based project based on your having previously selected the Wicket Quickstart Archetype and when it is done it will open the project in the Project window as pictured below: &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/Scul7NXuvaI/AAAAAAAAADc/hmcrwpOrJqE/s1600-h/3-26-2009+11-54-45+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 302px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/Scul7NXuvaI/AAAAAAAAADc/hmcrwpOrJqE/s400/3-26-2009+11-54-45+AM.png" alt="" id="BLOGGER_PHOTO_ID_5317526221661060514" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;You have now created an Apache Wicked Maven based application. Now lets explore some of the advantages that Maven provides to project management.

&lt;span style="font-weight: bold;"&gt;POMs&lt;/span&gt;

Maven projects in Netbeans do not use ANT build scripts. Instead, it uses a POM that it generates when the project is created. In our case, the POM it generated for our project was from the POM repository and because we selected Wicket Quickstart Archetype the POM it generated is specifc to Maven based Apache Wicket applications.

When you expand the Project Files folder in the Projects pane you can see 2 items there as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/ScuoX3VNEVI/AAAAAAAAADk/YTR78agcOCw/s1600-h/3-26-2009+12-06-51+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 302px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/ScuoX3VNEVI/AAAAAAAAADk/YTR78agcOCw/s400/3-26-2009+12-06-51+PM.png" alt="" id="BLOGGER_PHOTO_ID_5317528912984346962" border="0" /&gt;&lt;/a&gt;
If you double click on the pom.xml file, Netbeans will open it in its XML editor as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ScuqgLpXR3I/AAAAAAAAADs/fZ_lMjvJVaM/s1600-h/3-26-2009+12-16-00+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 288px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ScuqgLpXR3I/AAAAAAAAADs/fZ_lMjvJVaM/s400/3-26-2009+12-16-00+PM.png" alt="" id="BLOGGER_PHOTO_ID_5317531254899820402" border="0" /&gt;&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;POM dependency Tag&lt;/span&gt;

When viewing the pom.xml file in the editor, scroll down until you see the following:

&lt;div style="text-align: left;"&gt;        &amp;lt;!--  WICKET DEPENDENCIES --&amp;gt;

&amp;lt;dependency&amp;gt;
 &amp;lt;groupid&amp;gt;org.apache.wicket&amp;lt;/groupid&amp;gt;
 &amp;lt;artifactid&amp;gt;wicket&amp;lt;/artifactid&amp;gt;
 &amp;lt;version&amp;gt;${wicket.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;

The dependency tag above declares a project build dependency. In this case,  it represents a  dependency on Apache Wicket. The groupId and artifactId tags above serve to uniquely identify the target of the dependency, and the version tag above serves to identify the version of the dependency, which in this case is identified by a property declared as follows:

&amp;lt;wicket.version&amp;gt;1.4-rc2&amp;lt;/wicket.version&amp;gt;

Also notice that in the POM file there are numerous other dependency declarations including the following:
&lt;ul&gt;&lt;li&gt;slf4j - a  a simple   facade or abstraction for various logging frameworks such as Log4J&lt;/li&gt;&lt;li&gt;log4j - the actual logging implementation&lt;/li&gt;&lt;li&gt;junit - testing framework&lt;/li&gt;&lt;/ul&gt;The dependeny declarations in the POM declare all the dependencies for our project and are used when building the project.

&lt;span style="font-weight: bold;"&gt;Building POM Based Projects&lt;/span&gt;

Go ahead and build the project by right clicking the project node in the Project pane and selecting Build. The build process generates output in the Output window. Go ahead and take a look at the generated output by clicking the Output tab.

If you have never installed the Apache Wicket framework and specifically, never installed the specified version declared in the POM, you will notice that all the required jar files were downloaded for you. You didn't have to do anything like going to a web site and downloading the jars yourself. And this is true for all the other dependencies declared in the POM, too.

This is one of the great benefits of using Maven; declare a dependency in the POM and when the project is built dependencies that are not already located in in your local or other repository will  be downloaded onto your computer. Yes, this can add overhead to the build process but it only occurs when the required dependencies aren't already present in your local respository or some other repository that you can declare.

&lt;span style="font-weight: bold;"&gt;Selecting A Server For Deployment&lt;/span&gt;

Before we can run our application we have to tell Netbeans what server we want to deploy it on. Right click the project node in the Project folder and select Properties which will open the Project Properties window. Select Run from the Categories pannel which will display numerous runtime options, one of which is the Server option. From the Server drop down menu located on the right panel of the Project Properties window select a server of your choice such as GlassFish V3 Prelude as pictured below:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/Scu_P9hCM7I/AAAAAAAAAD8/SEK959UZgvc/s1600-h/3-26-2009+1-42-21+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 230px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/Scu_P9hCM7I/AAAAAAAAAD8/SEK959UZgvc/s400/3-26-2009+1-42-21+PM.png" alt="" id="BLOGGER_PHOTO_ID_5317554065973064626" border="0" /&gt;&lt;/a&gt;
Click OK. When we build and run our application, Netbeans will deploy it to the server we just selected.

&lt;span style="font-weight: bold;"&gt;Running A POM Based Project&lt;/span&gt;

Now run the application by right clicking the project node in the Project window and selecting Run. You should see the following rendered in your browser window:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ScvCXq-t3EI/AAAAAAAAAEE/oPBV5r9Tev4/s1600-h/3-26-2009+1-56-07+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 236px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/ScvCXq-t3EI/AAAAAAAAAEE/oPBV5r9Tev4/s400/3-26-2009+1-56-07+PM.png" alt="" id="BLOGGER_PHOTO_ID_5317557496971123778" border="0" /&gt;&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt;

Using Netbeans and Maven we were able to create a brand new project based on the Wicket Quickstart Archetype we selected. All the dependencies for the project were declared in the application's pom.xml file for us. When building the project, any dependency that couldn't be resolved locally was satisfied by downloading the dependency. This only took a few minutes. Imagine if you had to do all this manually. Netbeans with Maven support has taken the hassle out of working with open source. This will allow you to take better advantage of the many great open source products that are available when you create your next killer application.

&lt;span style="font-weight: bold;"&gt;URLs To Some Of The Items Mentioned&lt;/span&gt;

&lt;a href="http://www.netbeans.org/"&gt;Netbeans&lt;/a&gt;
&lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt;
&lt;a href="http://wicket.apache.org/"&gt;Wicket&lt;/a&gt;


&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-4072503693850759548?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/4072503693850759548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/03/netbeans-maven-projects.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/4072503693850759548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/4072503693850759548'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/03/netbeans-maven-projects.html' title='Netbeans Maven Projects'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_XzLrgIoZ_TU/ScuisImiZoI/AAAAAAAAADM/wH_BUxDikp4/s72-c/3-26-2009+11-37-53+AM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-8687188364578742926</id><published>2009-03-13T08:51:00.035-04:00</published><updated>2009-04-04T15:33:08.156-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wielenga'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='markup'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='Geertjan'/><title type='text'>Netbeans And Apache Wicket</title><content type='html'>Hi there,

Today I will introduce developing Apache Wicket applications using the Netbeans IDE v6.5. So lets get started.

&lt;span style="font-weight: bold;"&gt;Installing Netbeans IDE v6.5 and the Wicket v1.4 Plugin&lt;/span&gt;

First and foremost, if you haven't already, download and install Netbeans v6.5 which you can find &lt;a href="http://www.netbeans.org/"&gt;here&lt;/a&gt;. By selecting the 'All' bundle option you will download and install everything you need to follow along with the examples.

Once you have installed the Netbeans IDE, you should download and install the Wicket plugin for Netbeans v6.5 which you can find &lt;a href="http://plugins.netbeans.org/PluginPortal/faces/PluginListPage.jsp?search=wicket"&gt;here&lt;/a&gt;. As there are 2 plugins listed on this page, please make sure that you select, download and install the one for Wicket v1.4 which will install the v1.4 Wicket libraries. Follow the installation instructions as provided on the page.

This plugin was contributed by &lt;a href="http://blogs.sun.com/geertjan/entry/welcome_to_me"&gt;Geertjan Wielenga&lt;/a&gt;, a technical writer in the Netbeans Docs team who has contributed an amazing amount of material to the Netbeans community.

&lt;span style="font-weight: bold;"&gt;Creating a Wicket Application&lt;/span&gt;

With Netbeans and the Wicket plugin installed, now we can create our first Netbeans Wicket project. Start Netbeans and click File | New Project from the main menu. This will open the New Project window as pictured below:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SbpmfulSJLI/AAAAAAAAABc/CkBoc4Y3Huo/s1600-h/3-13-2009+9-51-58+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 279px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SbpmfulSJLI/AAAAAAAAABc/CkBoc4Y3Huo/s400/3-13-2009+9-51-58+AM.png" alt="" id="BLOGGER_PHOTO_ID_5312671405703308466" border="0" /&gt;&lt;/a&gt;
In the Categories list select Java Web and in the Project list select Wicket Application and then click Next. Accept all the default options in the Server and Settings window and click Next. In the Framework window, select Wicket 1.4 from the list of available Frameworks and then click Finish as pictured below:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SbpowFHLeZI/AAAAAAAAABk/cdyujGba4Vk/s1600-h/3-13-2009+10-07-17+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 277px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SbpowFHLeZI/AAAAAAAAABk/cdyujGba4Vk/s400/3-13-2009+10-07-17+AM.png" alt="" id="BLOGGER_PHOTO_ID_5312673885652220306" border="0" /&gt;&lt;/a&gt;
This will create a Wicket project which will be opened in the Netbeans IDE as pictured below:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SbpqYKoLLaI/AAAAAAAAABs/eu7un3lOUzQ/s1600-h/3-13-2009+10-12-28+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 239px;" src="http://4.bp.blogspot.com/_XzLrgIoZ_TU/SbpqYKoLLaI/AAAAAAAAABs/eu7un3lOUzQ/s400/3-13-2009+10-12-28+AM.png" alt="" id="BLOGGER_PHOTO_ID_5312675673839185314" border="0" /&gt;&lt;/a&gt;The plugin generates numerous files for you including the Server and Web descriptor files which are used to deploy and configure your web application on the application server, as well as basic Java, HTML and resource files that you can use as templates to start developing your application.

Select Run | Run Main Project from the main menu to build, deploy and run the application. You should see the following rendered in your client browser:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbqEfwDr9HI/AAAAAAAAAB0/NYn8XTIfbY0/s1600-h/3-13-2009+12-04-18+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 327px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbqEfwDr9HI/AAAAAAAAAB0/NYn8XTIfbY0/s400/3-13-2009+12-04-18+PM.png" alt="" id="BLOGGER_PHOTO_ID_5312704391448097906" border="0" /&gt;&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;The Structure of a Wicket Application&lt;/span&gt;

Wicket is different than most other Java Web frameworks that I have worked with or that I am  familiar with, in that Wicket's convention is that it expects Java and markup files to reside side-by-side in the same Java package. This can be seen in the above screenshot.

A rendered Web page in a Wicket application is implemented with at least 2 files, a Java Class file and a markup file. Both files must have the same names and are case sensitive. As we can see from the above screehshot, both HomePage.java and HomePage.html files are used when there is a request to render the HomePage html file to the client browser and they reside side-by-side to eachother.

&lt;span style="font-weight: bold;"&gt;Just Java and HTML

&lt;/span&gt;One of the advantages when working with Apache Wicket is that you create your application using just plain old Java, X/HTML, CSS, and resources. Another advantage is that you don't mix markup and scripting in your HTML files as is often the case in other frameworks. In other words, when you view a markup file in a Wicket application you will only see HTML. There is no spaghetti-code intermixed inside your markup.

This clean separation of code and markup helps when developing and maintaining your applications by making your applications easier to read and understand. It also allows programmers and designers/graphic artists to work together on the same pages. Designers and graphic artists shouldn't have to be programers in order to do their jobs so not having to work with markup files that have server-side scripting code in them can eliminate that problem.

Double click on the HomePage.html file located in the Projects window. It will open in the Netbeans HTLM editor window as pictured below:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbqGg67bnYI/AAAAAAAAAB8/EIKPaG3Y6oY/s1600-h/3-13-2009+12-14-28+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 267px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbqGg67bnYI/AAAAAAAAAB8/EIKPaG3Y6oY/s400/3-13-2009+12-14-28+PM.png" alt="" id="BLOGGER_PHOTO_ID_5312706610569387394" border="0" /&gt;&lt;/a&gt;What you see is what you would expect to see when viewing markup - HTML!

&lt;span style="font-weight: bold;"&gt;Extending Our Application

&lt;/span&gt;The rendered page in our new application isn't much to look at but it will serve as a foundation to demonstrate adding dynamic content to a web page using Wicket. For this demonstration we will add markup and Java code to render the ubiquitous "Hello, World!" message as well as the current date and time in the client browser.

But for the first crack at this, lets cheat and show how to do this by just adding static text to the HomePage.html file.

Double click HomePage.html in the Netbeans Project window. The file will open in the Netbeans HTML editor. Add the text as pictured below:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SbqPX0pazBI/AAAAAAAAACE/Yjy7ovlDxRg/s1600-h/3-13-2009+12-46-16+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 194px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SbqPX0pazBI/AAAAAAAAACE/Yjy7ovlDxRg/s400/3-13-2009+12-46-16+PM.png" alt="" id="BLOGGER_PHOTO_ID_5312716349869050898" border="0" /&gt;&lt;/a&gt;Select Run | Run Main Project from the main menu to build, deploy and run the application. You should see the following rendered in your client browser:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbqQuVoVGHI/AAAAAAAAACM/yxOF_hH6oHU/s1600-h/3-13-2009+12-55-36+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 327px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbqQuVoVGHI/AAAAAAAAACM/yxOF_hH6oHU/s400/3-13-2009+12-55-36+PM.png" alt="" id="BLOGGER_PHOTO_ID_5312717836191602802" border="0" /&gt;&lt;/a&gt;
&lt;span style="font-weight: bold;"&gt;Adding Dynamic Content&lt;/span&gt;

If all we want to do is to display static text then our job would be done, but static pages are boring. Lets add some code and markup to make this page display the current date and time as well when the page is rendered.

Double click HomePage.html in the Netbeans Project window. The file will open in the Netbeans HTML editor. Modify and add the text as pictured below:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/Sbqb9vTMvNI/AAAAAAAAACc/QbnllY2aLw4/s1600-h/3-13-2009+1-37-19+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 267px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/Sbqb9vTMvNI/AAAAAAAAACc/QbnllY2aLw4/s400/3-13-2009+1-37-19+PM.png" alt="" id="BLOGGER_PHOTO_ID_5312730195408239826" border="0" /&gt;&lt;/a&gt;Notice that we've added a span tag to the markup and that it has a wicket:id attribute whose value is lblDateTime. When we create a Wicket componet to contribute to the body of this span tag we will pass this same value to the component's constructor as its first parameter which is its id.

Double click HomePage.java in the Netbeans Project window. The file will open in the Netbeans Java editor. Modify the HomePage class as pictured below:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SbqecHV0lNI/AAAAAAAAACk/XG0cZKLOcX8/s1600-h/3-13-2009+1-56-14+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 284px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SbqecHV0lNI/AAAAAAAAACk/XG0cZKLOcX8/s400/3-13-2009+1-56-14+PM.png" alt="" id="BLOGGER_PHOTO_ID_5312732916281021650" border="0" /&gt;&lt;/a&gt;In the HomePage constructor we obtain and instance of a Calendar object which will be used to get the current date and time. Then we add a Label to the page. A Label is a Wicket component that adds its content to the body of any HTML element that it is associated with. The association between the HTML element and the component is made through the component's id value which we pass as the first parameter in the Label's constructor. The id value we pass is the same value that was assigned to the wicket:id attribute of the span tag in the HomePage.html file.

The second parameter we pass in the Label's constructor is the value of what we want to add to the body of the span element that the Label component is associated with. In this case, we will pass the current date and time as a string.

Select Run | Run Main Project from the main menu to build, deploy and run the application. You should see the following rendered in your client browser:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/Sbqjf971daI/AAAAAAAAACs/cpStmDLIFxI/s1600-h/3-13-2009+2-17-32+PM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 327px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/Sbqjf971daI/AAAAAAAAACs/cpStmDLIFxI/s400/3-13-2009+2-17-32+PM.png" alt="" id="BLOGGER_PHOTO_ID_5312738480033723810" border="0" /&gt;&lt;/a&gt;
Although this application is trivial, the principles used here are the same ones used when developing real world enterprise Wicket applications.

&lt;span style="font-weight: bold;"&gt;Synergy - Netbeans and Wicket&lt;/span&gt;

As demonstrated, Netbeans with the Wicket v1.4 plugin provide many features and services for creating, developing and maintaining your Wicket applications. It is a highly productive and intuitive environment. Wicket offers Java Web developers a simple, intuitive, and productive framework to create Web applications with. Now that Netbeans has solid support for Wicket, I believe both will continue to grow in popularity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-8687188364578742926?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/8687188364578742926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/03/introduction-to-using-netbeans-ide-and.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/8687188364578742926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/8687188364578742926'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/03/introduction-to-using-netbeans-ide-and.html' title='Netbeans And Apache Wicket'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_XzLrgIoZ_TU/SbpmfulSJLI/AAAAAAAAABc/CkBoc4Y3Huo/s72-c/3-13-2009+9-51-58+AM.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-7718774728045057053</id><published>2009-03-09T17:34:00.022-04:00</published><updated>2009-04-02T16:27:05.201-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='application'/><category scheme='http://www.blogger.com/atom/ns#' term='custom web control'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='netbeans'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Adventure With Wicket - Custom Controls</title><content type='html'>As I mentioned in my introduction, I am developing a web site and I am using Apache Wicket as my Java Web Framework.  Today I decided to tackle creating a custom web page control that would encapsulate a tabbed menu bar that you find frequently used on web pages.

The common method to implement a tabbed menu bar is through a combination of HTML, css and JavaScript on the client side and some server side scripting as well. As Wicket is often described as being just HTML and Java I thought this would be a good candidate to encapsulate into a Wicket custom component. So with my copy of "Wicket In Action" (a book by Martijn Dashorst and Eelco Hillenius, which is published by Manning and I highly recommend) in hand I set out to implement the control.

First, like any good developer, I came up with a number of requirements which I've identified as follows:
&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;The tabbed menu bar will be rendered in the browser using the ul and li tags&lt;/span&gt; &lt;span&gt;&lt;span&gt;which is a common practice employed by web page designers. When combined with the correct style sheet attributes the list can be rendered horizontally:&lt;/span&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SbZh0IdQx4I/AAAAAAAAAAs/u8cRsNR_iqA/s1600-h/HorizontalTabNavigationBar.html.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 325px; height: 400px;" src="http://1.bp.blogspot.com/_XzLrgIoZ_TU/SbZh0IdQx4I/AAAAAAAAAAs/u8cRsNR_iqA/s400/HorizontalTabNavigationBar.html.png" alt="" id="BLOGGER_PHOTO_ID_5311540358781388674" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbZiTsjoczI/AAAAAAAAAA0/N0nGRCarI3E/s1600-h/HorizontalTabNavigationBar.css.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 232px; height: 400px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbZiTsjoczI/AAAAAAAAAA0/N0nGRCarI3E/s400/HorizontalTabNavigationBar.css.png" alt="" id="BLOGGER_PHOTO_ID_5311540901047726898" border="0" /&gt;&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;The number of tabs displayed in the menu bar must be dynamic and defined by a model &lt;/span&gt;which in essence would consist of a list of menu tab items. Below is the MenuItem Java class that I defined to represent a single menu bar tab:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SbZYxNVBEmI/AAAAAAAAAAU/hurf6rm3ewg/s1600-h/MenuItem.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 616px; height: 438px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/SbZYxNVBEmI/AAAAAAAAAAU/hurf6rm3ewg/s400/MenuItem.png" alt="" id="BLOGGER_PHOTO_ID_5311530412944724578" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li style="text-align: left;"&gt;As for usability, &lt;span style="font-style: italic;"&gt;the control must be configurable and provide options that specify styling for the selected and non selected tabs, identity of the current tag, a model representing the list of MenuItems, and an id which will be used to render the html id attribute of the containing html div tag&lt;/span&gt; for the control's child html elements. The id is important because it will be used to customize the JavsScript that is rendered to provide client-side scripting of the control but more on that later. Here's the Java code for the custom control:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_XzLrgIoZ_TU/ScI0alNXfrI/AAAAAAAAAC8/sETtAJFwJS0/s1600-h/3-19-2009+7-58-39+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 146px; height: 400px;" src="http://2.bp.blogspot.com/_XzLrgIoZ_TU/ScI0alNXfrI/AAAAAAAAAC8/sETtAJFwJS0/s400/3-19-2009+7-58-39+AM.png" alt="" id="BLOGGER_PHOTO_ID_5314868141520027314" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;With the requirements identified and the implementation complete, all that is needed is a test. Here's a simple html snippet showing the tag that will be replaced by the Wicket panel hosting the control:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbZuGs7o4OI/AAAAAAAAABE/Iudx-aMFxH8/s1600-h/TestHorizontalTabNavigationBar.html.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 162px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbZuGs7o4OI/AAAAAAAAABE/Iudx-aMFxH8/s400/TestHorizontalTabNavigationBar.html.png" alt="" id="BLOGGER_PHOTO_ID_5311553871949652194" border="0" /&gt;&lt;/a&gt;
And here is the Java code to instantiate the control in the page:
&lt;div style="text-align: left;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/ScI3qCfOfFI/AAAAAAAAADE/Yi4zJUJYnEo/s1600-h/3-19-2009+8-15-47+AM.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 213px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/ScI3qCfOfFI/AAAAAAAAADE/Yi4zJUJYnEo/s400/3-19-2009+8-15-47+AM.png" alt="" id="BLOGGER_PHOTO_ID_5314871705612483666" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div style="text-align: left; font-weight: bold;"&gt;
&lt;span style="font-weight: normal;"&gt;And here is how the control appears when it is rendered in the client browser:
&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbZv29RDt3I/AAAAAAAAABM/4Yhn4EiMiZs/s1600-h/testrendered.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 26px;" src="http://3.bp.blogspot.com/_XzLrgIoZ_TU/SbZv29RDt3I/AAAAAAAAABM/4Yhn4EiMiZs/s400/testrendered.png" alt="" id="BLOGGER_PHOTO_ID_5311555800479807346" border="0" /&gt;&lt;/a&gt;
&lt;span style="font-weight: normal;"&gt;Overall, developing custom controls for Wicket applications isn't difficult and I find it much more intuitive than when I've done similar tasks with other frameworks . I use sort of a top-down approach to this kind of task, which allows for an iterative development process where each iteration adds more functionality and specificity.

There were a number of topics that I admitedly didn't touch on here such as the generation of the client-side JavaScript and the use of the AbstractReadOnlyModel class. I will discuss these in a future article.
&lt;/span&gt;&lt;span style="font-weight: normal;"&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-7718774728045057053?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jeff-schwartz.blogspot.com/feeds/7718774728045057053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/03/adventure-with-wicket.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/7718774728045057053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/7718774728045057053'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/03/adventure-with-wicket.html' title='Adventure With Wicket - Custom Controls'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_XzLrgIoZ_TU/SbZh0IdQx4I/AAAAAAAAAAs/u8cRsNR_iqA/s72-c/HorizontalTabNavigationBar.html.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2570247679477683751.post-5224474032946631387</id><published>2009-03-07T11:47:00.016-05:00</published><updated>2009-08-18T09:37:21.185-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Introduction'/><title type='text'>Introduction</title><content type='html'>Welcome! My name is Jeff Schwartz and this is my blog where I will be posting about software development. I'll assume that if you are following the articles that you too are either a software developer or that you are interested in software development. Occasionally, I may "speak my mind" on other issues, but this will be a place where I mostly discuss software development. So you wont get a large window into my personal life here other than what I feel comfortable divulging (see bottom of article for that little window).

&lt;span style="font-weight: bold;"&gt;What's wrong with Web application frameworks&lt;/span&gt;

Developing Web sites over the years has afforded me the opportunity to experience the good, the bad and the ugly of the development process. Part of that process has been having to deal with numerous Web frameworks with promising potential but that ultimately fail to live up to what can only be described as hype.

For the most part every framework that I have been exposed to have fallen far short of expectations for requiring far too much configuration and for failing to take into account established and best practices such as failing to implement the  MVC (Model View Controller) pattern and failing to provide a  component based architecture. In addition to these, the most egregious of their failings in my opinion is that they do not hide the fact that the Web is a stateless protocol.

This is most easily recognizable when studying how most Web frameworks deal or do not deal with session state. Those that do not deal with session state offload the responsibility to the developer by providing a hash (a mechanism to save a value and associate it with a name as well as to retrieve a value by its name) to save and retrieve string values and which is stored on the server and persisted over the life of a user's session while browsing a web site. This mechanism is perhaps the greatest single source of complexity,  frustration and errors that a developer will experience over the course of an application's lifetime.

All this lead me on the search for the Holly Grail, a Web application frameworks that didn't succumb to the same shortcomings as I perceived them. So I began looking for alternatives. I looked at Ruby On Rails but I hated the mixed markup/code pages. I wanted a framework that promoted a separation of concerns.

I looked at PHP but like ROR it also has mixed markup/code pages.

I looked at Java EE but I wasn't thrilled about the popular Java Web frameworks that seemed to be discussed the most; way too much XML configuration required to get even the simplest of web applications up and running in my opinion.

Then I heard of an open source, statefull, MVC, component based framework written in Java called Apache Wicket and it was like love at first sight. I read everything I could get my hands on about it and almost everything about it just seemed right to me. Most compelling is its non intrusive Ajax support. Wicket, it seemed to me, had to be written by people who actually have experience writing real world web applications, especially large applications.

Below I list the  strengths of the Wicket Web framework:
&lt;ol&gt;&lt;li&gt;It is a true MVC component based framework that allows me to do everything using just Java and HTML. &lt;/li&gt;&lt;li&gt;It is statefull. It hides the stateless nature of the HTTP protocol from the developer.&lt;/li&gt;&lt;li&gt;Its  Ajax support is excellent and unobtrusive.&lt;/li&gt;&lt;li&gt;It requires almost no XML configuration other than the typical Java application server and application descriptors which are minimal.&lt;/li&gt;&lt;/ol&gt;To be fair, Wicket isn't perfect. Its shortcomings, as I see them, are the following:
&lt;ol&gt;&lt;li&gt;Wicket can sometimes require more coding than some frameworks (ASP.net and JSF, for example) because there are no widget libraries that allow a developer to drag and drop controls off of a palette and onto an HTML page and gaining the benefit of the generated code behind the widgets.&lt;/li&gt;&lt;li&gt;A developer can easily abuse the statefull nature of the Wicket framework and overtax the server. Developers must learn to employ loadable and detachable data models to reduce the likelihood of this. Thankfully, Wicket provides its own LoadableDetachable abstract implementation. Developers just need to remember to use it as Wicket itself does not enforce its use.&lt;/li&gt;&lt;li&gt;Like many open source projects, Wicket sometimes suffers from poor or inadequate documentation.
&lt;/li&gt;&lt;li&gt;Wicket doesn't seem to get the tech press coverage that other Web frameworks seem to get so sometimes you as a developer may get that black sheep of the family feeling. &lt;/li&gt;&lt;/ol&gt;Warts and all, it should come as no surprise that Wicket has become my Web application framework of choice. It is my belief that most Web frameworks will follow the lead taken by Wicket and offer similar benefits to the developer.

&lt;span style="font-weight: bold;"&gt;Benefits of Java and open source&lt;/span&gt;

I have become a huge proponent of Java and open source. Of the many benefits they provide, here are a few I think are the most important :
&lt;ul&gt;&lt;li&gt;Java is open source and hence comes under the scrutiny of a large group of stake holders. These stake holders have a great deal of influence in ensuring that Java remains relevant and competitive with all the other options available such as DotNet, C/C++, PHP, Python, Ruby, etc.&lt;/li&gt;&lt;li&gt;Java is continuously evolving. Java EE, JavaFX, etc.
&lt;/li&gt;&lt;li&gt;Java supports both the client (Java SE) and the enterprise (Java EE).&lt;/li&gt;&lt;li&gt;There are numerous open source libraries available that provide pre-built solutions to common requirements so that as a developer I don't have to reinvent the wheel each time a new project is begun. I am a firm believer in the DRY principal.&lt;/li&gt;&lt;li&gt;Java supports write once, run almost everywhere via the Java run time.
&lt;/li&gt;&lt;li&gt;There are excellent open source development tools available,  IDEs such as Eclipse and Netbeans for example, that provide tooling that minimizes the implementation effort.
&lt;/li&gt;&lt;li&gt;Java and open source minimize the upfront costs to the developer as many of the tools and libraries are free.&lt;/li&gt;&lt;li&gt;Java plays well with other technologies such as numerous back-end databases.&lt;/li&gt;&lt;li&gt;Java is a a true object oriented language. I cannot over emphasize how important OO is to me. I think it just relates to how my mind works :). &lt;/li&gt;&lt;/ul&gt;My primary Java web development environment for the most part consists of the following:&lt;ul&gt;&lt;li&gt;Windows running either XP or Vista though I have Ubuntu as well and I have access to Mac OSX.&lt;/li&gt;&lt;li&gt;The open source Netbeans IDE.&lt;/li&gt;&lt;li&gt;MYSQL.&lt;/li&gt;&lt;li&gt;GlassFish Server.&lt;/li&gt;&lt;li&gt;FireFox with Firebug and JavaScript Debugger.&lt;/li&gt;&lt;li&gt;Apache Wicket Web application framework
&lt;/li&gt;&lt;/ul&gt;When developing Web applications I prefer to work with native XHTML and shy away from the WYSIWYG editors. I really like the HTML editor in Netbeans.

My javascript library of choice is JQuery. It is another one of those frameworks that just seems and feels right to me. I believe it, too, was written by people who have written a lot of code.

For entity persistence and database query services I use both JPA/EclipseLink and Hibernate . To tie the 3 tiers together in my enterprise applications I will use the Spring framework. Spring brings a lot of features to the table but I find it most useful for its IOC (Inversion Of Control) container.

Here are some links to some of the open source items that I mentioned were mentioned&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.netbeans.org/"&gt;Netbeanss&lt;/a&gt;&lt;a href="http://www.netbeans.org/"&gt; IDE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wicket.apache.org/"&gt;Apache Wicket Java Web Framework&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://http//www.mozilla.com/"&gt;&lt;/a&gt;&lt;a href="http://www.mozilla.com/"&gt;FireFox Web Browser and FireBug plugin&lt;/a&gt;
&lt;/li&gt;&lt;li&gt;&lt;a href="http://jquery.com/"&gt;JQuery JavaScript Library&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.springsource.org/"&gt;Spring&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mysql.com/"&gt;MySql Database Server&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;Oh, and here is a little window into my personal life. I have 5 cats and play the guitar. I am a slave to my cats and the guitar is my only passion other than developing great software.

Well, that's about it for now. In the future I will post articles that I hope you find interesting and possibly even educational. Since Wicket and Netbeans are 2 of my favorite technical subjects, I'll be writing a lot about them here. So please come back often to see what is new and feel free to comment on anything that you may read about here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2570247679477683751-5224474032946631387?l=jeff-schwartz.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/5224474032946631387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2570247679477683751/posts/default/5224474032946631387'/><link rel='alternate' type='text/html' href='http://jeff-schwartz.blogspot.com/2009/03/test.html' title='Introduction'/><author><name>Jeff Schwartz</name><uri>http://www.blogger.com/profile/02747605277666816054</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://1.bp.blogspot.com/-I0jqZgxMDpQ/TkfkBnEh3tI/AAAAAAAAAjc/mtsgDtcX24g/s220/2011-07-02-154408.jpg'/></author></entry></feed>
