David R. Heffelfinger
How do kids these days get started in programming?
Back in the 80's, when I was growing up, all personal computers would come with a BASIC interpreter which you could use to write your own software. As a matter of fact, it was expected for end users to write their own applications.
My very first personal computer was an Atari 800, I was in my early teens when I got it, it was a hand me down from my uncle, who had gotten himself a shiny new IBM PC.

During that time, computer magazines came with games and applications in source code form that you had to type into your computer in order to "install" them. A lot of us didn't know exactly what all these lines of code meant, but we wanted the game or application so we typed away, unfortunately typos were an issue, since we were just blindly copying what seemed like greek into our BASIC prompt. Fortunately BASIC was interpreted, so it would catch syntax errors immediately, but many times the syntax was correct, but there was still a typo in the line, making the program not run as expected. It could be frustrating at times, but it was very satisfying to finally get the code to work exactly right. You could also experiment and make little changes here and there to see if you could change the behavior of the software. I remember eagerly waiting for the next issue of A.N.A.L.O.G magazine to arrive in the mail every month to see what goodies it would bring.
It is worth mentioning that at this time there wasn't yet a dominant computer architecture for personal computers. Some of us had Ataris (8 bit and/or ST), others had Commodores (PET, Commodore 64 or 128, Amiga), others had IBM PCs, other architectures existed as well. What all of these architectures had in common was that they all came with a BASIC interpreter. As a matter of fact, in most cases, the machine would boot directly into a BASIC prompt. The BASIC versions of the machines were not 100% compatible across one another, since vendors modified them to highlight specific features of their own products, but in general your BASIC skills could be used across architectures.
I remember been amazed at the wonderful things you could make these machines do, it got me really motivated to learn to write my own software, not simply blindly typing code listings from magazines. A lot of software developers from that era got our start that way, at the time, the barrier of entry for software development was very low. I derived a lot of satisfaction in creating software, I would proudly show my creations to my friends and relatives. All of these got me motivated to pursue a career in software development, which is what motivated me to major in computer science when I went to college.
Somewhere in the 90's most of these various architectures disappeared, and the one true personal computer platform emerged, the IBM PC, or what we simply call a PC today. Just like all the platforms of the time, the IBM PC came with a BASIC interpreter, but unlike the others, BASIC wasn't built into the operating system, it was something you had to look for if you wanted to use it. When the PC became the de facto standard, the focus of having end users as programmers started to decline. Magazines stopped coming with BASIC listings for you to type in. When DOS 6.0 came out, PCs even stopped coming with a BASIC interpreter altogether. Now if you wanted to develop software, you had to install a compiler or interpreter yourself, which, sadly, is still the case today.
So I wonder, how do new generations of software developers get their start? It is not as easy to "get your feet wet" these days like it was back in the day. I wonder if they pick computer science without knowing exactly what they are getting into? It's a shame that software development is not as accessible as it once was.
Posted at 08:40AM Mar 15, 2009 by David R. Heffelfinger in General | Comments[53]
OpenOffice.org Document Version Control With Mercurial
I've always wanted to put my documentation under version control, just like I do with my source code. However, word processor files are binaries, therefore not that well suited for version control (track changes aside). Of course, they can be committed, however, being binaries they can't be diffed very easily.
Standard OpenDocument Text (the default format for OpenOffice.org Writer since version 2), are nothing but zipped XML files. I searched around for an easy, automated way to unzip them and zip them "on the fly" as necessary, thinking that i could put the "raw" XML files under version control. However, I couldn't find anything that would help in that regard. Manually zipping and unzipping files seemed like more trouble than it's worth.
OpenOffice.org's word processor, Writer, allows us to save in formats that are text based, such as Docbook XML, Microsoft Word 2003 XML, and OpenDocument Text Flat XML (.fodt). I figured I could try to use one of these formats internally, since they are text based they would be "diffable" by Mercurial (or any other version control tool), then when I needed to distribute the document I could export to Word format, PDF or what have you.
I haven't had the opportunity to work with DocBook in the past, and I admit I've been kind of curious about it, so I tried this option first. Unfortunately it turned out I couldn't use this format since I frequently work with Word templates (even though I work with OpenOffice.org, word templates work fine in Writer) and it doesn't seem like DocBook supports them.
I then turned my attention to the OpenDocument Flat XML (.fodt) format, this format can work with word templates, and it is saved as a plain text (XML) file. It looked like the perfect solution. To test it out, I created a simple document, saved it as OpenOffice Flat XML, and committed it to a Mercurial repository. I then made a simple change to this document, and did an hg diff on it.
To my dismay, this very simple change (I just added a new paragraph with a single sentence on it) resulted in quite a number of diffs between the two versions. Apparently this format contains a bunch of metadata such as creation time, creator, the time the file was saved, etc. This metadata was creating a number of diffs that were irrelevant to the task at hand, which is to find out what change I actually made to the file.
At this point I considered using the Handling OpenDocument Files oodiff trick described in the Mercurial site, however this trick seemed to me more like a hack than a proper solution. When using this approach, files are checked in as binary, then when diffing, a tool called odt2txt to convert the document to plain text "on the fly" then diff the plain text version. The problem with this approach is that the files are still commited to version control as binary, and most version control tools are not very efficient in storing binary files.
At this point started using the above trick, however recently I found the color extension for Mercurial, which allows diffs to be color coded. After I installed this extension, I gave the .fodt format a try again, and I started to notice patterns of what to look for when looking for diffs. For example, paragraphs are nested inside a <text:p> tag, this makes it easy to find text changes. Images are stored inside a <draw:image> tag, which makes it straightforward to see if an image was added, deleted or moved. Tables use the <table:table>, <table:column> and <table:cell> tags, making it fairly easy to identify them. This seemed like a good solution, however after a while I noticed that sometimes making a simple change in the document (for example, adding a heading somewhere in the middle), created a bunch of diffs on the document again, for example, lines that were now farther down in the document were being reported as deleted from one place and added in another, which is inaccurate.
For now, I went back to the oodiff trick, even though it bothers me a bit that I am checking in binary files to the repository, however this approach results in sane diffs that actually allow me to track what was changed in the document.
Posted at 11:29AM Mar 08, 2009 by David R. Heffelfinger in General | Comments[2]
Excluding directories from zip files on Linux
I frequently have to turn in source code to one of my customers in zip files (not fancy nor sophisticated, but that's life).
Lately, I've been working on a project that uses good old plain ANT build files. I load this project into NetBeans as a free form project so that I can have a decent working environment. NetBeans of course creates its own folders and files so that it can open the project. I am also using Mercurial for version control, which creates an .hg folder that I don't want to distribute.
I wanted to zip up the code, while excluding the directories and files that were not meant to be distributed (.hg and the NetBeans specific files and folders). I'm on Linux, therefore I usually use file roller, a graphical archive management tool for the GNOME desktop, to create my zip files. File roller is very easy to use, just right click the directory to be archived and select "create archive".
Unfortunately there is no way to easily exclude files or directories from the zip file, I thought I could zip up the whole thing, then delete the unwanted files and directories. This worked fine for files, but for directories it deleted the files in the directory, but left the directory in the zip file.
Obviously file roller wasn't meeting my needs here, it was time to go to the good old command line. Most Linux distributions come with a command line zip utility appropriately named "zip". I read the man page and found a way to tell zip to exclude files and directories from the created archive, all that needs to be done is use the -x switch and list the files and directories to be excluded, separated by spaces, for example:
zip -r filename.zip directoryname/* -x directoryname/.hg\* directoryrname/nbproject\* directoryname/catalog.xml
The above command will do exactly what I needed, which is to create a zip file without the Mercurial and NetBeans specific files and directories. Of course any file or directory name can be passed as a parameter to the -x switch.
Posted at 11:43AM Mar 01, 2009 by David R. Heffelfinger in Linux |
Thoughts on Distributed Version Control
Nowadays, distributed version control systems such as Mercurial, Git and Bazaar are all the rage. Lately, for a couple of my projects I have been using Mercurial.
Some frequently mentioned advantages of distributed version control are that it is not necessary to be connected to the network to commit your changes, and that all repositories are "equal".
Now that I've been using Mercurial for a while, I don't care that much about these advantages, however, there is one thing in Mercurial that I really, really like and that I miss very much when using other, centralized version control systems. What I love about Mercurial is that branching and merging is very simple and trivial (other distributed version control systems like Git and Bazaar probably share this advantage, however I don't have any experience with them).
When using traditional, centralized version control systems such as Subversion or CVS (or, $DEITY forbid, Harvest), many times I have found myself making some changes that will potentially introduce major breakage to the project. In cases like this I am "forced" to work without version control until all the kinks are ironed out, since committing my changes would prevent my coworkers from having a buildable source tree to work from.
The ideal solution for these cases is to create a branch in which I would make my changes safely, without affecting other developers, then when my changes are done merge my branch into the trunk. The problem with this is that for some reason branching and merging are not something "mere mortals" can do with centralized version control system. In order to do this, I would have to talk to a "CM" person to create the branch for me, which would probably take at least a few hours (if not days), then when I'm done the procedure to merge my changes would be just as painful.
When using Mercurial (and, I assume, other distributed version control systems as well), I can create a branch with ease, in Mercurial, all I have to do is use the hg clone command, passing the path of the repository to clone as a parameter. After doing this I would have my own, private branch that I can work with, without fear of breaking the build and preventing anyone else from making progress.
When I am done, all I have to do is an hg push to merge my changes back into the "trunk" (or my main branch).
If it turns out that I don't want to make the changes after all, all I need to do is delete my cloned repository using standard operating system commands (rm -rf in Linux/Unix), and the branch "never existed". This capability of easily making branches for experimental features and simply "nuking" them if it turns out to be a bad idea is what really makes Mercurial great for me. It is a very liberating feeling that I don't think can be expressed in words, you need to experience it to know what I mean.
Posted at 02:03PM Feb 28, 2009 by David R. Heffelfinger in Software Development |
Solving JasperReports Dependencies with Ivy
Lately, I've been doing some work with JasperReports. On my previous JasperReports projects, I've either used Maven, which automatically takes care of resolving dependencies, or I have simply downloaded the project's dependencies by hand.
Using Maven is nice, since it resolves dependencies, however, JasperReports comes with a series of useful ANT tasks to compile reports, preview them etc. I wanted access to these tasks and I also wanted dependency management.
There were a couple of ways I could achieve both. I know ANT targets can be called from Maven, this could be one approach. Also, there is a dependency manager for ANT called Ivy. I had briefly used Ivy before, I thought I would try this approach.
Ivy works by adding a series of custom ANT tasks, installing Ivy is very simple, all that needs to be done is to copy the Ivy jar file to ${ANT_HOME}/lib. Once Ivy is installed, custom Ivy tasks are available in our ANT build files.
Some additional configuration needs to be done in an Ivy specific XML file, named ivy.xml. In this file is where we actually specify our dependencies.
I set up my project to depend on JasperReports and tried to have Ivy automatically download all of JasperReports dependencies, unfortunately the build failed, complaining about some missing dependencies, specifically mondrian and commons-javaflow.
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve] :: UNRESOLVED DEPENDENCIES ::
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve] :: commons-javaflow#commons-javaflow;20060411: not found
[ivy:retrieve] :: mondrian#mondrian;2.3.2.8944: not found
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve]
[ivy:retrieve] :: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS
After some googling, some head scratching (and some hair pulling and banging on the table for good measure), I found out what was going on.
JasperReports has some optional dependencies declared in its pom.xml, these dependencies are not downloaded by default when using Maven, however Ivy attempts to download them. For some reason these dependencies do not exist in the repository, because of this the ANT build fails.
After some research, I found out the necessary modifications to ivy.xml to make the build succeed:
<ivy-module version="2.0">
<info organisation="ensode" module="mymodule"/>
<dependencies>
<dependency org="jasperreports" name="jasperreports" rev="3.1.2" conf="*->default"/>
</dependencies>
</ivy-module>What I had to do was to use the conf attribute of the <dependency> tag to specify that I wanted that configuration for this particular dependency. The *-> default means that all your module configurations depend on the 'default' configuration of JasperReports, as explained by Xavier Hanin in this message of the Ivy users mailing list.
After making this change, Ivy was able to successfully download all JasperReports dependencies.
[ivy:retrieve] commons-beanutils#commons-beanutils;1.8.0 by [commons-beanutils#commons-beanutils;1.7.0] in [runtime]
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| runtime | 14 | 12 | 12 | 2 || 11 | 11 |
---------------------------------------------------------------------
I figured I would document this procedure in case others are having similar issues.
Posted at 11:04PM Feb 26, 2009 by David R. Heffelfinger in Java |
Yet another "My Favorite Firefox Extensions" Post
It seems like every other day there is a link on DZone about someone listing their own favorite Firefox extensions.
Well, I didn't want to be left out, so here are mine:
- Web Developer, provides a lot of functionality useful when developing web applications. One of my favorite features is the ability to outline elements on the page, very useful.

- Firebug, I can't live without the ability to edit Javascript in real time, and see the results on the page immediately. Also, the Firebug console is invaluable when debugging Javascript, freeing us from the awful alerts(); we used to have to use all the time in the past. Working with Javascript without firebug is like working with a hand tied behind your back.

- iMacros, when developing web applications, we often have to go through tedious, repetitive steps to get to the page we are developing. iMacro allows us to record macros to go through the repetitive boring stuff for us, a real time saver and sanity preserver.

Posted at 11:24AM Feb 22, 2009 by David R. Heffelfinger in Software Development |
Common JPA Questions
- How can I have a composite primary key in JPA?
There are several ways to do it, this page explains them.
- How can I prevent users from overwriting each other's changes to the database?
Use the @Version annotation.
- Is there a way to do bulk updates and/or deletes with the Java Persistence Query Language (JPQL)?
Yes.
Posted at 01:30PM Feb 21, 2009 by David R. Heffelfinger in Java |
Upgraded to Roller 4.0.1
Since I just upgraded JavaDB, I figured this was a good time to upgrade to the latest version of roller as well. I was using roller 4.0, which is fairly up to date, but I figured it wouldn't hurt to upgrade to the latest, 4.0.1.
I simply downloaded roller 4.0.1, created a war file from the roller directory and deployed it to GlassFish, but for some reason the upgrade didn't go smoothly, I kept getting a "Roller Weblogger has not been bootstrapped yet" error.
I tried various ways of deploying, using asadmin, copying the war file to the autodeploy folder, etc, but I kept getting the same error. I restarted GlassFish several times, I restarted the database (JavaDB/Derby) several times, nothing seemed to solve the problem.
I then decided to reinstall roller 4.0 (thank goodness I made a backup), and it came back up successfully. After doing this, I then redeployed roller 4.0.1 using a different temporary context root, and this time, it installed successfully, asking me to upgrade the database. I did upgrade the database (the only thing that needs to be done when going from roller 4.0 to roller 4.0.1 is change the version number), and I had both roller 4.0 and 4.01 running in parallel with different context roots.
I then undeployed roller 4.0, and changed the context root of 4.0.1 to match the one I had in 4.0 (/roller), I am now in business.
Why wouldn't roller 4.0.1 just install over 4.0 is anyone's guess, however I was glad I was able to work around the issue.
Posted at 11:29AM Feb 21, 2009 by David R. Heffelfinger in Java |
Java DB / Apache Derby Upgraded
Like I mentioned in My very first entry in this blog, I am running Apache Roller to run this blog.
I'm using GlassFish and Java DB, which isn't much more than a rebranded version of Apache Derby.
The setup was working OK, but every now and then Roller would throw some weird errors, valid URLs would 404, and sometimes it would go completely "out to lunch", generating error 500's.
I started looking through the GlassFish logs and noticed some entries similar to the following:
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at org.apache.derby.client.net.NetCursor.findExtdtaData(Unknown Source)
at org.apache.derby.client.net.NetCursor.getClobColumn_(Unknown Source)
at org.apache.derby.client.am.Cursor.getString(Unknown Source)
I googled around and found out this issue is caused by a bug on JavaDB/Derby version 10.3.2.1 and earlier. I happened to be running 10.3.2.1. I just upgraded to version 10.3.3.0 of JavaDB/Derby. I expect the weird errors I've been seeing to go away now.
Posted at 09:27AM Feb 21, 2009 by David R. Heffelfinger in GlassFish |
Running Graphical Applications on a remote server
Like many, I host my web site on a remote server, it is a Virtual Private Server, running Linux (Cent OS 5).
I have full SSH access to my server, which provides me with full access to the bash shell to do anything my heart desires, well, almost anything, or so I thought.
One thing I couldn't do was to run graphical applications on the server, since it doesn't have an X server such as X.org. This didn't bother me too much, since there weren't too many graphical applications there I wanted to run remotely, with one exception, the GlassFish update tool.
I remember back in the good old days when Unix ruled, you could set the DISPLAY environment variable to run an application on one workstation or server while displaying it on another, I tried setting the DISPLAY variable to the display of my local Linux laptop, but it didn't work.
A few days ago while browsing Slashdot, I ran into a comment that explained how to achieve this:
ssh -YtC user@myserver.com /path/to/graphical_app
I tried the above with the correct credentials, server and path and lo and behold, I was able to run the GlassFish update tool on my server while displaying it on my laptop.
Thanks Doug!
Posted at 07:02PM Feb 20, 2009 by David R. Heffelfinger in Linux |
Installing Ubuntu Intrepid Ibex in an old laptop
I have an old Averatec 3250H1 laptop that is still being used (2200+ 32 bit AMD processor, 60GB hard disk, 512MB RAM). This laptop was running Ubuntu 5.04 (Hoary Hedgehog).
I wanted to upgrade the version of Ubuntu to a more modern version. I downloaded the 32 bit version of the Intrepid Ibex install ISO, burned it into a CD and got to work.
Unfortunately the installer CD wasn't running properly, early into the install process it would just dump me into a command line and the install would abort.
I tried googling around but most information out there for this laptop is from around circa 2005, seems like nobody is trying to install a modern version of Linux on this specific laptop model.
After some messing around, I started to suspect that what was making the install abort was lack of drivers for the video card on this machine (S3 Unichrome Integrated Graphics with 64MB Shared Memory). I tried looking for an alternate way to install, the only way I could find was to download an alternate install ISO. So I downloaded this alternate install CD and proceeded to install Ibex on this "classic" laptop, unfortunately, the installer froze again at 25% of the "Select and Install Software" stage, in the "Preparing gnome-icon-theme" step. At this point I had to abort the installation, by forcibly turning off the laptop, which became unbootable after this mishap.
At this point I tried the Ubuntu alternate install CD once again, this time choosing the "command line system" (or something along those lines) option. I figured I could try and hack my way into installing X later, after all, it was running when the laptop had Hoary Hedgehog. This time, the install finished successfully, and I had a fully functional (albeit text only) system.
I booted up to my new install and upgraded all the software by running "apt-get update", followed by "apt-get upgrade" (thank goodness I am a Debian veteran and a few years of graphical only package management in Ubuntu didn't make me forget how to update software from the command line). At this point I had a fully updated, command line only system.
After some more googling around, it became obvious that I wasn't the only one having problems with the included Unichrome integrated video card included in the laptop. Thankfully, I was able to figure out that I needed the "openchrome" X driver, and I found a usable xorg.conf that I could just download and use.
After figuring out how to configure the video card, I was able to successfully run X, however saying that it was ugly doesn't even begin to describe it, all I had was a terminal window and a gray background, of course, GNOME wasn't yet installed.
I did an "apt-get install gnome", which resulted in approximately a million packages being downloaded and installed, after a very long wait I tried to boot to X again, this time running GNOME, but for some reason it seemed to be running a Debian theme, as opposed to the default Ubuntu "brown" theme.
At this point I have the laptop almost fully functional. The only thing that is not working yet is the wireless. I'm pretty sure I'll be able to get it to work, after all it was working in Hoary, however life got in the way and I had to stop setting it up. To be continued, I guess.
Posted at 08:22AM Feb 16, 2009 by David R. Heffelfinger in Linux |
Java EE 5 Reference Material
My Books
Two of my books cover Java EE 5, one focuses on GlassFish deployment, the other focuses on developing using NetBeans.
Java EE
The Java EE 5 Tutorial covers most aspects of Java EE 5. Examples can be downloaded as NetBeans projects.
JSF
JavaServer Faces is the standard component framework for Java EE 5.
JPA
The Java Persistence API is the standard Object Relational Mapping (ORM) tool for Java EE 5. It takes the best ideas from Hibernate and other ORM tools and incorporates them into the standard.
@Version annotation
Posted at 12:29PM Feb 15, 2009 by David R. Heffelfinger in Java |
NetBeans in an Old Clunker
For the past few months I've been working with a new client that does not allowed personal hardware to be plugged into their network. They provide the hardware for their consultants and employees to use.
The only computer they had available for me was a laptop with great specs (five years ago), 1 GB of RAM, and a 1.6 Gz (single core, but I think it goes without saying) processor.
On this laptop I've had to run NetBeans, alongside with JBoss or GlassFish (one of the projects I'm working on uses JBoss another one uses GlassFish).
I've always had the fortune of having access to fairly modern hardware, and although I had heard complaints about NetBeans performance, it was always good on the hardware I had available. This situation gave me an opportunity to use NetBeans in, let's just say, "less than ideal" hardware.
What I have noticed is that NetBeans takes a very long time to initialize, but once it does, it works fine, for the most part. The most noticeable annoyance I have seen is that opening files via the "SHIFT+ALT+O" shortcut is slow, many times I finish typing the file name before the list to pick from pops up.
Even with substandard hardware, for the most part I've found that NetBeans performs fairly well.
Posted at 06:53PM Jan 15, 2009 by David R. Heffelfinger in NetBeans | Comments[1]
New Version of IceFaces NetBeans Plugin Out
A couple of days ago I noticed that the NetBeans IceFaces plugin had been updated. I wrote my initial impressions about the plugin a while back.
I've been wanting to take the updated version for a spin, but other commitments have been preventing me from trying it out. Today I had a few minutes to spare so I gave it a try.
I am happy to report that most of the issues I found with the plugin are now fixed.
Pages developed with the plugin now work with GlassFish 3 effortlessly.
Additionally, I can drop components into the navigator view to avoid the CSS absolute positioning that happens when dropping components directly in the page, please note that I only tried this under Linux, which wasn't broken to start with; in my previous test I used both a Windows and a Linux box, and only under Windows I wasn't able to drop components in the navigator.
I was also very glad to be able to change the default package where the automatically generated JSF managed beans get created, it was awful having all of these classes in a package named "WebApplication5" or something along those lines before.
There are a couple of issues that still persist.
The "label" attribute of IceFaces components is still ignored. The weird thing is, it works fine when using Facelets (without visual editing, of course) why doesn't it work with JSPs with Visual Web is anyone's guess. When JSF 1.2 came out, I was so glad that we had an easy way to display user friendly error messages, it has been frustrating not to be able to easily use this feature, first with Woodstock and now with IceFaces
Another issue that is still present is that ctrl+shift dragging from a label or message component into an input component does not yet set the "for" attribute like it was possible with Woodstock. The mouse pointer changes into a crosshair when doing this, also the target component is highlighted when hovering over it, therefore I believe this issue is a bug and not an omission of the feature.
It looks like the folks at IceFaces are making some progress getting this plugin up to speed. Hopefully in the near future the remaining issues will be addressed.
Posted at 01:10PM Jan 10, 2009 by David R. Heffelfinger in NetBeans |
NetBeans IceFaces Plugin First Impressions
Recently Sun announced that there will be no further development for Project Woodstock. Some maintenance will be done in the project, but no new features are planned.
This announcement affects NetBeans Visual Web projects, since they use Project Woodstock JSF components behind the scenes.
Sun is now recommending that current Woodstock applications be migrated to IceFaces. An IceFaces plugin has been available for a while to develop JSF applications visually using the IceFaces components, the plugin works in a way that is very similar to the standard Visual Web JSF NetBeans plugin.
Since Woodstock will no longer be developed, I figured now is a good time to take the NetBeans IceFaces plugin for a spin, to see how well it works, turns out, it doesn't work very well, at least the current version available from the NetBeans Plugin Manager.
The first issue I ran into is that the Java package for managed beans defaults to the project name and cannot be changed. The project name never adheres to standard Java package naming conventions (i.e. com.mycompany.packagename), therefore we end up with classes in nonstandard packages.
Under Windows, I wasn't able to drag components from the palette into the navigator page, this it is possible using NetBeans standard Visual Web JSF functionality (oddly enough, I was able to do this under Ubuntu Linux). I prefer dropping the components in the navigator page instead of directly in the JSP design view, since dropping the components in the design view results in CSS absolute positioning. I'd rather use the JSF standard way of placing components, which is using a panel grid for layout right inside a JSF form component. This issue can be worked around, by placing a grid in the design view then manually removing its "style" attribute, but it feels cleaner to just drop components in the navigator page.
Also, applications developed using IceFaces cannot be run under GlassFish 3. Maybe there is some faces-config.xml or web.xml incantation that needs to be done in order to make this work, I didn't try and didn't research it, all I did was develop a simple test application and try to deploy it.
Here is a partial stack trace from the GlassFish 3 log when attempting to deploy an IceFaces application developed using the NetBeans Plugin:
SEVERE: Can't find TLD for location [http://java.sun.com/jsf/core]. JAR containing the TLD may not be in the classpath
SEVERE: Can't find TLD for location [http://java.sun.com/jsf/html]. JAR containing the TLD may not be in the classpath
SEVERE: Failed to execute JSP lifecycle.
java.lang.IllegalStateException: ICEfaces parser unable to determine JSF implementation ViewTag class.
at com.icesoft.faces.webapp.parser.Parser.parse(Parser.java:152)
at com.icesoft.faces.application.D2DViewHandler.renderResponse(D2DViewHandler.java:528)
at com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:159)
Additionally, when working with standard Visual Web JSF, the "for" attribute of labels and message components can be set by ctrl+shift dragging from the label or message component to the target component. This functionality is not available in the IceFaces visual plugin.
One thing I was looking forward to was finding out if IceFaces wouldn't suffer from my Woodstock pet peeve. In JSF 1.2, the "label" attribute was added to all standard JSF input components. This attribute results in user friendly error messages. The JSF message and messages components by default use the component id to identify a validation error in a component, which is meaningless to the user. The label attribute allows the error message to use a user friendly label, as opposed to the component ID.
Woodstock components have a label attribute that, in addition to enabling user friendly error messages as described in the previous paragraph, actually adds a label to the component. Kind of neat, but it also makes it very difficult to right align all the components and left align all the labels like it is usually done in web applications. Therefore, when using Woodstock, there was always this catch-22 between user friendly error messages and ease of component alignment.
One of the first things I tried when testing the IceFaces NetBeans plugin was to set the "label" attribute on an input text component, and set the component's "required" attribute to "true". I ran the application, submitted the page (purposefully leaving the required input field blank) braced myself and bam! The component id is still shown in the error message, as opposed to my user friendly label, bummer!
I googled a bit and read some people had success with the label attribute using Facelets. I installed the NetBeans Facelets plugin and redid my simple application using Facelets. This time the label attribute "kicked in" and worked as expected.
Although I am not afraid to code things by hand, especially with excellent code/tag completion support like the one found in NetBeans, Visual web provides a nice way to preview a page while working with it, this functionality is lost when using Facelets with NetBeans.
I guess the plugin is "almost there", but the fact that the "label" attribute is ignored is a big bummer. Also, I miss the ability to drop components from the palette into the navigator window, bypassing CSS absolute positioning.
Other functionality we are used to from Visual Web JSF is still there. A request scoped managed bean is created for each IceFaces visual page we create (one caveat, the default package for these managed beans can't be changed, it defaults to the project name, which does not adhere to standard java package naming conventions). Also, double clicking on a command button automatically creates a method on the managed bean to handle its action event.
Although I don't have a lot of experience with this plugin, my impression is that it is better than coding JSF applications by hand, but I really miss some of the missing features from the standard Visual Web JSF functionality.
I would also like to clarify that this entry is not meant to knock IceFaces. I've seen the IceFaces demo apps and I can see that it eases creation of very sophisticated and elegant web applications, I just found some issues with the IceFaces NetBeans plugin that I hope will be addressed in the near future.
Update: a new version of the plugin came out, I tested the new version and wrote my thoughts here.
Posted at 06:56PM Dec 18, 2008 by David R. Heffelfinger in NetBeans | Comments[5]




