"I Find Your Lack of Ant Disturbing"

Posted on June 24, 2005 by Scott Leberknight

Yes I have been watching Star Wars IV: A New Hope lately in case you are wondering about the reference to Vader's "I find your lack of faith disturbing" comment. Anyway, recently I've come across a couple of situations where I was doing some consulting work and found that people were using -- no, relying completely -- on their IDE to perform builds of J2EE applications. One even included an EAR, EJB-JAR, and WAR file all being built exclusively by the IDE. Then Novajug launched a poll yesterday on what people were using as their build tool. As of about 10 minutes ago people using their IDE stood at 20%. Now granted the number of people who have voted thus far is small and the 20% only translates to 11 people. But I find even that number of people using only an IDE to build applications alarming and disturbing. As for my recent consulting, I won't mention the IDE by name, but it is a commercial IDE that allows you to define, using mounds of dialog boxes, in excruciating detail everything about your build, which is where they had put everything! And all of those settings were checked into version control no less.

The reason I was helping them out was because one developer's IDE would simply not build the WAR file, instead giving a single one line error message: java.lang.ArrayIndexOutOfBoundsException. Nice. Well, with this amount of detail I naturally was unable to help him out, and suggested in passing that they try switching their build system to Ant rather than the IDE. And there really isn't much more to say in this paragraph about it either, so I'll continue to the next one.

I suppose the reason I thought about writing this is because I pretty much assumed everyone nowadays uses Ant to build J2EE applications. Apparently I am wrong. Not the first time. Anyway, another tidbit about that project I was helping -- they had no "test" tree in their project, thus no, nada, zero unit tests. Maybe bad practices run amuck and are concentrated on a small set of projects, such that if someone is using only their IDE to do builds, perhaps it's not all that surprising they aren't unit testing either. But that's just random speculation.

No More Struts?

Posted on May 24, 2005 by Scott Leberknight

At this past weekend's No Fluff conference one thing was missing that has been at every conference I've been to for as long as I can remember...a session on Struts. There was not a single session on Struts, unless you count the session on Shale which I suppose is possibly the last gasp for Struts before it completely succumbs to JSF. Well, I suppose I don't really know enough (or anything) about Shale nor am I enthralled about learning, since I think most people will use straight JSF or Spring MVC or perhaps even Tapestry or WebWork. Though, other than Erik Hatcher I don't personally know anyone using Tapestry on a production project and I know only one person using WebWork. Erik loves Tapestry and though it looks pretty cool I am much more interested in Spring MVC simply because I am already a heavy Spring user. Everyone else is still on Struts it seems and a select few people I have talked to are using Spring MVC.

Spring 2005 No Fluff Just Stuff

Posted on May 23, 2005 by Scott Leberknight

Just attended the Reston, VA No Fluff Just Stuff conference this past weekend. As usual there were lots of high-quality speakers and content. This time around there were a bunch of new sessions to choose from and I attended a bunch of sessions on topics that I don't know very much about like Swing GUI development, cryptography, Java Security and JAAS, even a session delving into the depths of JavaScript. I never knew how dynamic JavaScript actually is and some of the basic rules it uses when it parses and executes code. I plan to document all the sessions I attended over (hopefully) the next week or three.

JSF Conversion Oddities?

Posted on April 14, 2005 by Scott Leberknight

Suppose you have a web application with a field named "amount" on a form. Suppose also the field should convert its input to a number with at least 2 fractional digits. Ok, JSF provides a <f:convertNumber> tag that provides an attribute minFractionDigits. So far so good. We could put the following code in our JSF page:

<h:inputText id="amount" value="#{payment.amount}">
    <f:convertNumber minFractionDigits="2"/>
</h:inputText>

Makes some degree of sense. Whether I want to place this conversion directly in the view layer is debatable. Actually not really. I don't want to put it there but that's what JSF wants you to do, so for my example I did just that. Then I started playing around, submitting the form with various values. Entering valid numbers works fine, e.g. 75.00, 45, 21. So let's see what it does with something that is not a number. Entering 'abcd' produces a conversion error which gets output to the screen. The default error message is 'Conversion error occurred' and changing it to something like 'The amount could not be converted to a number' turns out to be exceedingly difficult in JSF on a per field basis, but that will have to wait for another blog. Ok, what about a mixture of numbers and letters? Entering '50xyz' produces...50.00. Um, wait a second. Apparently the invalid trailing letters are ignored. Last time I checked, if you try to feed that number to the standard factory method Double.valueOf() you get a NumberFormatException as you would expect. Why would JSF accept that value and convert it as a valid number? That just doesn't seem to make any sense at all.

Oh but wait. Before assuming this is purely the fault of JSF, I did a little more and wrote a JUnit test to test out parsing numbers using the NumberFormat.parse() class. The string "50xyz" is successfully parsed using this method. The JavaDoc for NumberFormat.parse() actually states "Parses text from the beginning of the given string to produce a number. The method may not use the entire text of the given string." That last sentence tells the story. The method doesn't necessarily use all of the input string, which I think is a bit odd. What if the input string were "50?75"? The parsed value is 50! This is not only odd, it seems just plain wrong to me. What if someone meant to type in "50.75" but typed "50?75" (since the "?" is next to "." on the keyboard? The parse does not flag an error and would then cause a wrong input value to be accepted. So apparently the culprit here is actually the JDK, not JSF. So this just illustrates that you need to thoroughly test your applications using many different forms of invalid data to ensure your application actually considers it invalid. But since JSF (apparently) uses NumberFormat during its conversion phase, this type of data will be converted successfully and not flagged as erroneous input.

Note that NumberFormat.parse() is not the only method with a lenient parse policy. The SimpleDateFormat.parse() method also does. For example, the string "4/2005edfnnas", when parsed with the pattern "MM/yyyy", is parsed successfully to the date 4/1/2005. And, the JSF <f:convertDateTime> tag probably uses SimpleDateFormat as well, since the above input string converts to "4/1/2005" in JSF. So if you are using JSF and its converter tags, be aware of the leniency during parsing.

onclick versus onchange in IE and Firefox

Posted on April 09, 2005 by Scott Leberknight

So I deployed one of the Core JSF examples to Tomcat and tested it out. In case anyone actually cares, it is the "Deleting Rows" example in chapter five. Anyway, since I normally use Firefox that is what I was using and the example worked as advertised. I have no idea why, but I opened up Internet Exploder and tried the example. It didn't work properly. The example basically has several checkboxes that, when changed as detected by a JavaScript onchange event, called submit() to submit the form. (Whether clicking a checkbox should cause a round trip to the server is a different matter altogether, but that is what this example does.)

So in Firefox this worked great. When a checkbox was clicked, the onchange even handler fired and submitted the form. but in IE what happened was quite different...nothing at all actually happened when I clicked the checkbox. That is, until the checkbox lost focus by tabbing away or mouse clicking somewhere else. The solution is relatively simple. Just change the onchange event handler to onclick. When a checkbox is clicked, the handler fires and the form is submitted. This works in both IE and Firefox.

My initial reaction was to praise Firefox and then to curse IE, but I wondered whether what the HTML specification said about onchange. Here's what the HTML 4.01 specification has to say about onchange event handlers:

"The onchange event occurs when a control loses the input focus and its value has been modified since gaining focus. This attribute applies to the following elements: INPUT, SELECT, and TEXTAREA."

Well, well, well. Apparently I needed to check (no pun intended) that initial reaction and in this case state that it is IE that is following the specification to the letter, not Firefox. IE does in fact wait until the checkbox has lost focus and that its value has changed. Prior to posting this, I submitted the "fix" of changing to use onclick to the Core JSF website. Using that method works in both IE and Firefox, and therefore probably Mozilla and Netscape as well. Anyway, the point here is simply that not everything is as it seems: in this case IE and Microsoft got it right, and Firefox has added extensions or at least "enhancements" to the way onchange is supposed to work.

Stuff like this is incredibly annoying, though; you cannot simply take the specification at face value because different vendors have slightly different implementations. This is one reason I dread having to test web applications in every single browser. And it goes to show why having specifications that are followed and that you can count on is very important. After all, how much time and money has been wasted over the years on getting web interfaces to work properly in all browsers, and even different versions of the same browser? Even on my current project at work we found a difference in the way Netscape 7 and IE 6 handle a certain thing in JavaScript and had to write different code for Netscape and IE. This should not be required but apparently is still an issue. Not as much as several years ago to be sure, but it is still not perfect.

Cuneiform or JSF?

Posted on April 05, 2005 by Scott Leberknight

So if JSF forms only permit POST requests, how would you go about creating a link to submit your form instead of a button? Whereas you use the <h:commandButton> tag to create an HTML submit button, you use <h:commandLink> to create a link that will submit your form. So far so good, right? Not so fast. Because JSF only permits forms to be POSTed, the JSF generates an HTML link with an onclick even handler that sets some hidden form variables and then submits the form. Lots of magic incantations going on here that are out of your control. Check out the following example code.

Suppose you have a form whose id is "registerForm." Also suppose you want to have several text fields and a "register" link to submit the form. In your JSF page, you write this code:

<h:commandLink value="register"/>

I deployed the JSF page containing this code to Tomcat and then viewed the generated source code. Here it is:

<a href="#" onclick="document.forms['registerForm']['registerForm:_idcl'].value='registerForm:_id6'; document.forms['registerForm'].submit(); return false;">register</a>

In addition to the above, a hidden field was added:

<input type="hidden" name="registerForm:_idcl" />

Is this the kind of code you want your web framework generating? I think I'll pass.

Another fun thing about JSF's generated HTML code is the way it names HTML form fields. It uses the format formName:componentName where formName is the name of the form and componentName is the name of the HTML form control. So in my "registerForm" the code <h:inputText id="password"/> generates the following:

<input id="registerForm:password" type="text" name="registerForm:password">

This code has the nice little side effect that it cannot be accessed in JavaScript in a simple manner. You cannot simply write document.forms.registerForm.password. Instead, due to the colon in the element name you are forced to write the following:

document.forms.registerForm["registerForm:password"].value

This seems par for the course so far while learning JSF. Every time you turn around there is some other gotcha or misuse of technology or artificial restriction being placed upon you the developer. Have fun!

No GET Requests! Are You Serious?

Posted on April 02, 2005 by Scott Leberknight

I managed to read a couple more pages of Core JavaServer Faces today and couldn't believe it when I read that JSF only supports POST requests for forms because apparently you can store session state on the client in a hidden field; this is apparently done automatically by JSF. Therefore since the contents of that field "can be quite large" you could possibly "overrun the buffer for request parameters." Are you serious? So for every form you create in JSF you must POST the submission? That is simply unbelievable. There is a reason there are both GET and POST requests - they are for different types of actions. Why in the world a framework would force you to (mis)use POST for every form submission is utterly beyond me. Then again, I suppose if you buy into the whole "JSF applications should be created using specific tools like Sun Studio Creator" model, then you probably either don't care what code is generated, wouldn't understand it anyway, or don't even realize there is a difference between GET and POST requests. If there weren't any difference, then why do Servlets have both doGet() and doPost() methods?

I would have thought the people designing JSF would know better than this. Spring MVC for example recognizes the distinction between GET and POST requests, and its AbstractController permits disabling GET and POST requests via a supportedMethods property, which by default supports HEAD, GET, and POST methods. In addition, Spring's AbstractFormController defines separate lifecycles for GET and POST requests, taking the viewpoint that GET requests typically correspond to "edit" operations while POST requests correspond to "save" or "delete" operations.

Finally, the fact that JSF doesn't even give the developer a choice just seems to be more evidence that it was designed for tools and not with developers in mind. And the implementation of storing client state in some gigantic hidden field seems ludicrous. That would mean you would need to have a form on every single page of a web application in order to carry that state around. To me that is just a poor design decision; it is certainly possible (and preferred) to design web applications with a minimum amount of session state. About the only things I ever store in session are User objects representing who the logged on user is. Sometimes I'll simply store the user's database id. Everything else that the view needs can be setup per request and set as request attributes. The only caveat is that I often store global data, e.g. for drop-down select lists and other rarely-changing reference data, in application scope. But seriously, is this really going to be the way the standard J2EE web framework works?

First Real Python Script

Posted on April 01, 2005 by Scott Leberknight

Yesterday I completed my very first real, though very novice, Python script at work. We were creating a "commons" project for several projects past and present that I am working on that combines utility classes created over the pasts few years. We merged the codebase from the projects and needed to go through all the Java source files and modify headers, Javadoc tags, and footers to be consistent. I wrote a relatively short Python script to do this, and found it was pretty easy. Despite the fact that I have barely started to learn Python I was able to use the os module to work with files and directories, and to use the re module to use regular expressions to match various strings.

Definitely the coolest thing was the walk() function which (from the Python documentation) "generates the file names in a directory tree, by walking the tree either top down or bottom up. For each directory in the tree rooted at directory top (including top itself), it yields a 3-tuple (dirpath, dirnames, filenames)." For example, suppose you wanted to find all Windows .bat files starting from the c:\projects directory. The following script does just that. I am sure an expert Python developer could do it in fewer lines, but I am just starting out with Python so I'm sure it's not the best code.

import os
import re

for root, dirs, files in os.walk('c:\projects', topdown=False):
  for file in files:
    match = re.compile('.*bat$').match(file)
    if match != None:
      print 'Found file: ' + file + ' in dir ' + root

Pretty cool. I am not even going to bother seeing how many more lines of Java code this would take, but I'm sure it would be a lot more. Anyway, the way the walk() method returns a "3-tuple" is just plain cool, and it's even cooler how you can just define them in the for loop. I definitely plan to continue learning Python and keep this snake in my software tool garden. Ok, I cannot believe I just wrote that. Must be getting old if the cheesy and sucky jokes are starting already.

JSF Designed For Tool Support

Posted on April 01, 2005 by Scott Leberknight

After a month hiatus from blogging in which we took a week snowboarding at Whistler/Blackcomb and my time seemed to get sucked down the drain, I've started reading Core JavaServer Faces. Mind you, it is not because I am enthralled with JSF or that I really want to use it on any future projects. I am learning it because I am sure that in the near future I will have to explain to a client why I don't want to use it on a project right now.

I've read a lot of people's opinions on JSF on various places like TheServerSide, SYS-CON, IBM developerWorks, and another one at SYS-CON.

Obviously there's no shortage of opinions both ways. One of the things that annoys me is how JSF was designed for tools. There are some people who I've argued with and others whose articles I read who try to dispel this "myth" and say its not true. Well, it is true. In the preface to Core JSF, David Geary explains the JSF "framework was designed for tool support". Not designed with tools in mind, not designed so tool vendors can provide tooling, but designed purposely and specifically for tools. Now I am not against tools per se; in fact I use them all day long every day, e.g. IDEs, build tools, test tools, etc. But I am little skeptical of a framework designed and targeted for tools. Since David is a member of the JSF expert committee, and because I have now heard him say that in person and now in print, I believe it.

Yes, you can build JSF application by hand in vi if you like, but since JSF was designed for tools, it would be common sense to think that using a tool to build JSF applications would make it easier. One of the great things about the Java and open source worlds is that most things are first designed and used by people hand-coding everything, and then tools are built to support things that are tedious and repetitive. JSF inverts this by beginning with tools. Therefore from what I have seen (I'm only a 100 pages into the 600 pages of Core JSF) the JSF expert committee wasn't really too worried about those people who actually are more productive hand-coding or are experts and therefore can be slowed down by some tools.

Another thing about JSF is that it seems to force developers to build JSF applications, not HTML-based web applications or any other view technology. In other words, JSF strives to be completely agnostic of the specific view technology. That is fine in principle and might even work itself out to be a good choice, but for now it seems you have almost zero control over the HTML generated in your web application. Contrast the JSF style with all custom JSF tags with Spring which completely separates the view from the controller in its MVC framework, and does so with a minimal amount of coding and intrusion. It was designed for different view technologies to be plugged into the web framework, and actually supports multiple view technologies out of the box - JSP/JSTL, Velocity, Freemarker, XSLT, PDF, and Excel to name some. JSF on the other hand supports only JSP out of the box as a view technology. It seems that JSF pages are a morass of custom JSF tags, with very little HTML at all. Thus without a tool that explicitly supports JSF, a web developer who only knows things like HTML, CSS, graphics, etc. is going to have a tough time! In addition, this model makes it hard to customize the generated HTML since it is generated for you.

Having been to JavaOne the past two years where Sun has repeated how they want to make Java/J2EE development easier and lure masses of Visual Basic developers to Java. A noble goal but it could backfire if it actually succeeds. I say "backfire" because that means the Java world would all of a sudden have a group of developers who can use a tool, but have no idea what's going on underneath. That is always a recipe for problems, because there always are unique problems you run into during every single project you work on., and which require a deeper level of understanding than someone who only understands how to point-and-click. Anyway, I digress.

The point is I will get through Core JSF, building the sample applications by hand in Eclipse and UltraEdit, and perhaps I'll later blog about how I was wrong. But right now I'm not counting on that outcome; we'll see what happens. Perhaps as I go further with JSF I'll change my mind. Most times my first impression has been about right, but I definitely have misjudged things before. The worst one was my initial impression of Spring. After the first article I read, I wasn't really interested. But now I am a huge Spring user and advocate.

Date Handling in Java Revisited

Posted on February 23, 2005 by Scott Leberknight

After writing last week about how horrendous date handling in Java can be, apparently the developers who just released version 1.0 of Joda Time agreed. But they actually did something about it by creating a Java library that seems to address many of the shortcomings in the default JDK date classes. Pretty cool.

So using Joda Time you can implement the example from my date handling rant as:

DateTime start = new DateTime(2004, 2, 17, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 2, 17, 0, 0, 0, 0);
Period period = new Period(start, end, PeriodType.weeks());
int numberOfWeeks = period.getWeeks();
System.out.println("numberOfWeeks = " + numberOfWeeks);

Well, that's a lot better than using the JDK date classes and close to the simplicity of the Python example. And it prints the correct answer, 52.

I did run into a slight issue at first. Notice in the above example I am using the version of the Period constructor that takes two ReadableInstants and a PeriodType. In this case I wanted to compute weeks so I used PeriodType.weeks() as the value of the argument. There is a constructor that takes only the two ReadableInstants which, according to the JavaDoc, is supposed to use the "standard" PeriodType and should include the "standard set of fields". The standard fields defined in PeriodType include: years, months, weeks, days, hours, minutes, seconds, and millis. Good enough, right?

Well, when I run the following sample code it prints out zero not 52 as I initially expected:

DateTime start = new DateTime(2004, 2, 17, 0, 0, 0, 0);
DateTime end = new DateTime(2005, 2, 17, 0, 0, 0, 0);
Period period = new Period(start, end); // uses standard PeriodType
int numberOfWeeks = period.getWeeks();
System.out.println("numberOfWeeks = " + numberOfWeeks); // prints zero!

In fact, the value of millis, seconds, minutes, hours, days, weeks, and months are all zero. Only year has a value and its value is one. Hmmm. After some more playing around I found out that the way Joda Time computes the period is actually pretty intelligent. Check out the following slightly modified example, which contains dates with different months, day, hour, minute, etc.

DateTime start = new DateTime(2004, 2, 17, 16, 30, 10, 546);
DateTime end = new DateTime(2005, 5, 10, 17, 45, 7, 344);
Period period = new Period(start, end);
System.out.println("period = " + period);

When run this prints: period = P1Y2M3W2DT1H14M56.798S. So it actually is smart enough to break apart the period into years, months, weeks, days, etc. That is pretty cool. And if you query the individual methods such as getDays() you get the values shown in the output string - 1 year, 2 months, 3 weeks, 2 days, 1 hour, 14 minutes, 56 seconds, and 798 milliseconds. So the values in Period must be taken together as defining a period, which makes sense since that is really how people tend to think about dates.

Joda Time also provides Interval and Duration classes in addition to Period. They all do slightly different things. But overall there are a ton of useful utilities in Joda Time and I plan to start using it straightaway on projects.