Entries Tagged 'java6' ↓

Frame2 and MacOS X

Currently, Frame2 does not work on Macs. This, of course, is due to the fact that there is no (easily) available Java 6 implementation for MacOS. I’ve been trying to decide if this is an issue or not.

Reasons why it might be an issue:

  • I use a Mac for most of development, and I hate having to drop into an emulator to work on Frame2
  • I really would like Frame2 to run on the Mac, if just for completeness.

Reasons why it probably doesn’t matter:

  • Who really runs Java webapps on Macs? Tomcat on Windows or Linux is OK, but it just feels dirty to me on the Mac.

Hopefully, there will be a version of Java 6 available for the Mac soon. At that point, I’ll probably make the necessary updates to make everything work. Until then, if you’re writing a web app and using a Mac – go with Rails.

Adding Features Uncovers Old Bugs

This seems to happen to me no matter what project I’m on. I try to implement a simple (or not so simple) feature and end up exposing at least one bug that’s been hiding around for quite some time.

As an illustration, I was adding a feature to Frame2 today to allow some parameters to be passed between events within a mapping – without making developers use the HttpSession. After a couple of false starts, I had a pretty good idea of how to make the changes and starting ripping out code. I came up with several unit tests, and modifying code to make the tests pass. Pretty standard Test Driven Development…until I wrote the test that made sure event chain validation was working.

Before I explain the bug, I’ll give a high level description of how Frame2 works when submitting form data:

  1. Form is filled out by user and submitted.
  2. Frame2 looks up the appropriate event from the form action.
  3. An instance of the appropriate event is created and populated by the introspector.
  4. Based on the mapping for the event, Frame2 will then validate the event. This may involve the Commons Validator if it is enabled and/or overriding the Event.validate() method.
  5. If validation fails, the mapping must specify a location for the framework to forward back to. This is usually the same page where the data was entered.
  6. If validation passes, the framework then iterates through the list of event handlers, calling the handle() method. If handle() returns null, the framework continues to the next handler. A non-null result usually indicates an error, and the framework will forward to the location named by the result.
  7. Once all of the handlers have been invoked, the framework will default to the view specified in the mapping. Usually this is just a JSP, but Frame2 supports forwarding to events – called “chaining”.
  8. For the chained event, Frame2 is supposed to start back at step 2 and continue processing until it gets to the end of the chain.

Notice how I say “supposed to” in step 9? The framework was actually only going back to step 6, bypassing validation for all events except the first in the chain. Subtle, yes, and unlikely to be noticed by most users – but it’s still a bug. The bug has now been fixed so that the framework goes back to step 2 like it’s supposed to.

In case you’re wondering what use event chaining is, here’s an example:

  1. User enters a blog entry and submits the form.
  2. Frame2 validates the form data and begins invoking handlers.
  3. The blog entry handler persists the data, perhaps to a database.
  4. The default view for the event mapping tells the framework to forward to the “View All Blog Entries” event.
  5. The framework creates the appropriate object and begins invoking the handlers in the “View All” mapping.
  6. The “View All” handler populates all of the blog entries into the “View All” event.
  7. The default view for the “View All” mapping is a JSP page, which renders the blog entries using JSTL.

Chaining allows the “View All” event to remain its own entity that can be invoked separately, while allowing the same functionality to be used in other places where appropriate.

By way of comparison, the feature I added allows the above sequence to be reworked like this:

  1. User enters a blog entry and submits the form.
  2. Frame2 validates the form data and begins invoking handlers.
  3. The blog entry handler persists the data, perhaps to a database.
  4. The blog entry handler sets an attribute with the new entry id into the context.
  5. The default view for the event mapping tells the framework to forward to the “View Specific Blog Entry” event.
  6. The framework creates the appropriate object and uses the context value(s) with the introspector to set some values in the event.
  7. The framework then begins invoking the handlers in the “View Specific” mapping.
  8. The “View Specific” handler looks up the entry with the specified id and sets its data into the event.
  9. The default view for the “View Specific” mapping is a JSP page, which renders the blog entry using JSTL.

FindBugs Is Even Cooler Than I Thought

I’ve mentioned before that I’m using FindBugs to help make sure that the Frame2 code is up to snuff. The Eclipse compiler can catch a lot of things, bug FindBugs has some neat tricks up its sleeve to find things that Eclipse can’t. FindBugs uses static analysis of the code to search for patterns that indicate possible issues. Being the Type A person that I am, I always turn on all of the possible matches and whittle the list down. Quite often, however, FindBugs will find a false positive or two. Up until now, I’ve either tried to rework the code to avoid the warning or disabled the category altogether. I’ve never liked the approach of turning off a whole category just to avoid seeing a warning or two, so I spent the morning muttering to myself how useful it would be if FindBugs allowed me to ignore certain warnings like I can do with @SuppressWarnings.

Then I went and RTFM.

FindBugs has a filtering system that makes @SuppressWarnings look amateur. Here’s an example: in the SoapRequestProcessor, FindBugs marked a warning that an Exception was being caught when no Exception was being thrown. After looking at the code and verifying that the try block in question throws several different exceptions, I created a filter entry. The entry looks like this:

<Match>
<Class name="org.megatome.frame2.front.SoapRequestProcessor"/>
<Method name="getEvents"/>
<Bug pattern="REC_CATCH_EXCEPTION"/>
</Match>

This tells FindBugs to match a specific bug type in a specified method in a desired class. This entry can be used in both an inclusion or exclusion filter – I use it to exclude that warning from the results.

Here’s a more complex example:

<Match>
<Class name="~.*introspector\.Bean\d+" />
<Bug pattern="EI_EXPOSE_REP,EI_EXPOSE_REP2"/>
</Match>

There are some test classes that don’t exactly follow good rules of programming when it comes to dealing with mutability. Since they are test classes, I don’t really care to fix them. Instead I set up the filter to match all classes in an introspector package named Bean1, Bean2, etc. Simple as can be!

If you aren’t using FindBugs, you should be. Go check it out.

Moving Into the Modern Age

The last official release of Frame2 happened in January of 2006, and was Java 1.4 specific. I am currently making changes to the codebase to take advantage of all of the improvements that Java 5 and 6 brought. The process is roughly this:

  1. Configure Eclipse with the latest available JDK.
  2. Turn on all compiler warnings.
  3. Eliminate some warnings.
  4. Rerun all unit tests.
  5. GOTO 3 until warnings are gone, or at least only in the generated JAXB code.
  6. Run FindBugs.
  7. Eliminate issues found by FindBugs.
  8. Rerun unit tests.
  9. GOTO 6 until FindBug issues are minimized.

At least, that’s the plan. Reality usually has different plans – so far they’ve mostly involved obtaining new versions of required libraries and watching the failed unit test count skyrocket. On the plus side, Java 6 has made JAXB significantly less painful – more on that later.