This is my blog in English, about the stuff I do for a living, and about the stuff I read about the stuff I do for a living - when I am not working.

Saturday, October 10, 2009

Wicket wicket wicket!

The folks at my current company were stuck with Struts 1.2, as was I. I never used Struts 2, so I really cannot say anything about it, but Struts 1 was great a while ago.

But, man, all that XML to add validation to your pages, complicated JSP files - either with the JSTL library or with embedded code, all those small pieces when you use tiles...

Anyway, we got this product where we had complex JSP pages and not-so-complex action pages. There was a lot of input fields but no validation - and the developer in charge decided to use JavaScript to add these validations, forgetting about the server-side of things, and we had a stream of endless problems:

. The validations started growing more and more complex - for example, the field "C" would be disabled if "A" > "B" but only if "D" = "E";
. This field is to be disabled with JavaScript, so when the user enters a value in "A", the field "C" is disabled;
. If the field "C" is disabled, then any values entered by the user have to be discarded, for that field - so the same rules that were created in JavaScript have to be added on the server.

I got really upset with that. Most times, we end up chasing our own tails in poor decisions like that, and all that trouble could be avoided by doing some research before starting. So I talked to management and I did some research on which web frameworks are being used right now - and I've found Wicket. We got the book (Wicket in Action), and I got a very simple page to build.

So, I start. I read the first chapters of the book, which are well written, and I understand the main bullet points of Wicket:

. Everything in Wicket is based in pages - you have a pair MyPage.html and MyPage.java, similar to what you would have in .Net, and far away from the concept of action classes/ JSP pages that you have in Struts;
. The "MyPage.html" is a HTML page where you add a wicket attribute (wicket:id) to each of the components that you will also add to the Java class of that page;
. One of the things I first learned is that the page class is constructed only once for each user that is accessing it - much like a desktop application. Wicket will keep the state of that page automatically and you don't need to worry about it; And, because of that, if you have a component that holds a list (like a tree or a SELECT component), and that list may change according to what the user does, you need to provide the list of items from a model and not simply send it to the constructor of the component you are creating;
. Validation is so easy it almost feel like cheating; Really. You create the text component, and then you write "component.setRequired(true)", and there you go. You can create your own custom validators, you can run your validation in the model class after the basic validation went ok.

Wicket is shipped with Ajax features. It's really easy to use - everything around Wicket can be made with no much effort. You just have to take care with your code when using lists, otherwise it can really have a lot of nesting levels.

So far, so good. I am creating a second application, bigger, and I am planning on using it from now ow.

PS: I would put code samples in here but it's Saturday morning and I have errands to run.

Interesting articles:

http://ptrthomas.wordpress.com/2007/03/02/wicket-impressions-moving-from-spring-mvc-webflow/;
http://www.infoq.com/news/2006/12/wicket-vs-springmvc-and-jsf

Friday, May 29, 2009

About java exception handling

These days I started working with Java Desktop, Swing, JTables and similar components. I have done a lot of things using Java, but they were either console apps or web apps - so it was already time I started working with Desktop applications.

There are some problems with the model that they use to build the dialogs and applications, some of the components have lots of deprecated methods, the dialog class is not responsible for its events (you have to define it yourself), but the worst thing I noticed is that exceptions that are not catched in methods that are called in response to events are silently ignored, completely swallowed. During some research I found this page that describes a way to add an uncaught exception handler, but it's some sort of workaround.

So, when I work with dialogs, I try to make the dialogs just part of the flow of the application, but in a way that each dialog is responsible for collecting some user data or outputting some information, but never being responsible for complex business logic or by important application flow.

For example:


public static void main(String[] args) {
  try {
    final LoginDialog loginDlg = new LoginDialog();
    final LoginCredentials loginCredentials = loginDlg.getLoginCredentials(); // Displays the login dialog and will return only when the user presses the "ok" button or close the dialog
    if (loginCredentials == null) {
      return; // The user cancelled the login - we should just leave the app
   }

    // Depending on how the login is performed some sort of user message has to be displayed here

    final LoginToken loginToken;
    try {
      loginToken = performLogin(loginCredentials);
    }
    catch(CannotLoginException ex) {
      GUIUtils.messageBox("Cannot perform login (" + ex.getMessage() + ")");
      return; // More friendly would be to try again
   }

    // We are authenticated. Let's collect user data
    final UserDataEntryDialog dataEntryDialog = new UserDataEntryDialog();
    final UserData userData = dataEntryDialog.collectUserData();

    // Do something with the user data
    final SomeBusinessLogic someBusinessLogic = new SomeBusinessLogic();

    // It would be nice to display some sort of progress information - that can either be achieved through the last dialog displayed, or through some sort of progress window
    someBusinessLogic.doYourStuff(userData);
  catch(Exception unexpected) {
    GUIUtils.displayErrorMessage("Unexpected error (sorry buddy)", unexpected);
    loggerInstance.error("Unexpected error", unexpected);
  }
}


The "progress window" is rather important, that can either be obtained by using a "global progress window" (it's the easiest approach), or by defining an interface that will be implemented by all dialogs:


public interface ProgressDisplayDialog {
  void display(String msg);
}

(the user should always know that something is happening and that the application hasn't simply died)

The important thing about the example above is the fact that there's no dialog chaining. Each dialog only knows about itself and is responsible for retrieving some sort of data that will be used by the business class or the main method, or whoever needs it. It's some crude form of MVC. The main advantage of this approach resides on the fact that dialogs do not invoke business methods. So, if in the action method of some dialog there's an exception that was not catched (or catched and ignored, something not so hard to do on UI classes as they tend to have a lot of boilerplate code), then the damage will be restricted to that dialog only - probably some event will not be completed - something like changing the selected index of a drop down list or coloring a cell in a table. In UI classes, the right thing to do in event methods is to catch the exceptions and tell the user about it.

It also makes the navigation on the application very clear and it makes it easy to replace blocks of code if you need to.

Also about exceptions, in my current company we use this API where almost every method on every class throws 3 or 4 checked exceptions, which is a pain in the butt. When I am working with this API, I make all my private methods throw an Exception (so whatever happens will be propagated to the caller), and I make my public methods either throw Exceptions, RuntimeExceptions, or some Exception class that is related to the business purpose of the class that contains the method being executed. At least by making your private methods throw Exception, your free yourself from a lot of boilerplate code. Alternativelly, if you're not too lazy or if you use some smart IDE, you can add 5 or 6 exceptions to the method signature and let other deals with that.

I don't like checked exceptions :-).

Thursday, March 19, 2009

I learned a new thing today...

I finally understood what weak references are for:

http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html

Simply put, the referenced object (by one of the reference classes) can be claimed by the garbage collector at any time, and you wouldn`t have that object anymore. Why the hell would I want to use that, then?

The answer is simply: caching.

By doing some hack around the class SoftReference, you could have a caching mechanism that would delete objects from the cache when the Java VM needs more memory. Instead of crashing, you would lose some objects from the cache, which would have to be obtained later, but no big deal - that`s just a small performance penalty.

I would like to have that knowledge 5 years ago. It would have been useful.

Friday, March 13, 2009

8 rules to discourage your employees

If you are committed to pissing off your employees, but can’t quite find the way to do so, you can follow these rules and achieve success...

read more | digg story

Monday, March 9, 2009

LINQ

Pretty interesting stuff.

Too bad I am not working with C# anymore :-(.

Thursday, March 5, 2009

Why does Google messes up with my iGoogle page?

Every now and then I open my homepage (which is an iGoogle page), and everything is messed up - ugly frames, ugly check-boxes, and now tabs on the side of the page instead of the top.

Is it beta, is it lab or is it just an annoyance?

EDIT: Add the gl=all parameter to your home page URL, such as in: http://www.google.com/ig?gl=all.

That should solve this annoyance.

Stack Overflow and the human developers

We are all human! We all like to be recognized.

In my humble opinion that's why Stack Overflow is such a huge success.

I am leaving, I am leaving

Today it's being announced that I am going to leave my current company to work on a different company. From Voice applications in Java using Eclipse to Corporate applications in Java using IntelliJ. It's going to be fine as well, closer to home, probably not as challenging as Voice but still a programming job with all the perks that it brings.

Wednesday, March 4, 2009

Maven with Eclipse, not anymore...

I am a happier person now. I've disabled Maven + Eclipse integration in my current Eclipse installation and I went a little bit further - I haven't installed the Maven plugin in my current Eclipse installation.

How is that possible? Here is the answer: http://maven.apache.org/plugins/maven-dependency-plugin/

I associated the plugin execution with the phase "validate" in Maven, so every time I run the targets "validate" or "generate-sources" (or with the compilation targets "compile" or "build"), all the maven dependencies are copied to an output folder inside the "target" folder. After that, I can add these copied dependencies statically to the Eclipse project from Eclipse. And here you go, no Maven + Eclipse integration is needed anymore.

Advantages:

. Eclipse works better - the ammount of annoyance generated by eclipse is directly related to the number of plugins that are installed on it;
. It's common that all the versions of a dependency are include in the classpath when running a project with Maven integration enabled - for example, commons-lang-2.1 and commons-lang-2.4. When the dependencies are copied to the target folder, only the resolved dependencies are copied (in that case, it probably will be commons-lang-2.4);
. Less heuristic, more deterministic - things magically start happening in the way there are supposed to.

Disadvantages:

. You have to remember to invoke the "mvn validate" or "mvn generate-sources" on the command-line before trying to compile your project inside Eclipse.

So far, it's paying off. I have way less bugs to worry about and a lot of "down-time" was saved after I started using Eclipse without Maven.

Eclipse for software development...

...is a good tool, but with a lot of bugs (particularly if using WTP).

I started playing with IntelliJ now - a good tool, but with a weird "feeling" after working for so many years with Visual Studio and Eclipse.

This is going to be...

... a blog of short posts about technical stuff and not much yada-yada-yada. I am not good at that.