My blog has moved!

You should automatically be redirected in 6 seconds. If not, visit
http://blogs.i2m.dk/allan
and update your bookmarks.

Thursday, 8 January 2009

Another big shot goes bust

Another big shot goes bust! This time it's the Indian IT "giant" Satyam (http://www.computing.co.uk/vnunet/news/2233443/satyam-chairman-admits-seven). This is not long after the Danish company; IT Factory, pulled a similar stunt (http://politiken.dk/newsinenglish/article605506.ece). I'm starting to think that when all things are going well, it's just an illusion with a few puppet masters pulling all the strings. However, I just can't believe that in both cases it is claimed that the auditors and board didn't have any knowledge of the wrong doings. If this is true then we must be talking about the dumbest people in the world.

Friday, 2 January 2009

Christmas present from Sun

Just as the year was ended I got a great Christmas present from Sun Microsystems.

1) A cool NetBeans 10 year anniversary T-shirt for participating in the community acceptance test programme for NetBeans 6.5 (NetCAT)



2) A pass on my exam to become Sun Certified Specialist for NetBeans IDE

The exam was special to me as it was my first ever certification exam. My score was 82%, with the least score in questions about building Java SE applications. I guess it shows that I've never build Java SE applications on NetBeans. Otherwise I think the exam was great. Studying for the exam revealed a lot of useful features that I had never used before, but now wondering how I could ever live without. I can highly recommend doing the exam!

Thanks Sun!

Wednesday, 31 December 2008

Setting JAVA_HOME on Ubuntu

A thing that always annoys me about installing Java is that it doesn't automatically set up the JAVA_HOME environment variable after installation. I guess this is to avoid having problems when you have multiple virtual machines installed. Anyway, I use Ubuntu Linux to host the majority of my Java Application Server. It is easy install Java (sudo apt-get install sun-java6-jdk) but there always seems to be a debate about where to set the JAVA_HOME environment variable. Some instructions say you should add it to your personal profile (e.g. ~/.bashrc) others suggest adding it to the global profile (i.e. /etc/profile), some people even suggest adding it directly in the init script for the services that need the variable. My suggest is to add an executable shell script to /etc/profile.d/ called javahome.sh. The content of the file would be: export JAVA_HOME=/usr/lib/jvm/java-6-sun. All shell scripts (i.e. executable files with the extension .sh) located in the /etc/profile.d/ directory are loaded upon login and would therefore work for all users without having to change system files that may change upon the next O/S upgrade. To test the script simply type source /etc/profile This will reload the profile for the current user. To verify that the environment variable has been initialised type export|grep JAVA_HOME

Enjoy!

Monday, 24 November 2008

Getting value expressions from f:attributes

If you have a custom converter or validator you may provide these with the option of letting developers specify attributes. For example, let's say that we are creating a converter that will allow the formatting of a Calendar object. Note, that the <f:convertDateTime /> is for Date objects (which can be easily retrieved from a Calendar, but that is beside the point). So the custom converter I'll create here is for converting/formatting Calendar objects.


package com.blogspot.bigallan.converters;

import java.text.*;
import java.util.*;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;

public class CalendarConverter implements Converter {

/**
* Not implemented as the converter is one-way only.
*/
public Object getAsObject(FacesContext ctx, UIComponent component, String value) {
return null;
}

public String getAsString(FacesContext ctx, UIComponent component, Object value) {

// Get the Calendar to convert
Calendar calendar = (Calendar) value;

String pattern = "";

// Obtain attributes specified along with the converter
Map<String, Object> attributes = component.getAttributes();

// Check if the pattern attribute was specified
if (!attributes.containsKey("pattern")) {
System.out.println("pattern was not specified");
return "";
} else {
pattern = (String)attributes.get("pattern");
}

// Create a DateFormatter for the pattern
DateFormat outputFormat = new SimpleDateFormat(pattern);

// Format the calendar
try {
Date date = originalFormat.parse(calendar.getTime());
return outputFormat.format(originalDate));
} catch (ParseException ex) {
ex.printStackTrace()
return "";
}
}
}


In faces-config.xml you would declare the converter like this:


<converter>
<converter-id>calendarConverter</converter-id>
<converter-class>com.blogspot.bigallan.converters.CalendarConverter</converter-class>
</converter>


We can now use the converter in a view:


<h:outputText value="#{myBean.calendarObject}">
<f:converter converterId="calendarConverter" />
<f:attribute name="pattern" value="d. MMMM yyyy" />
</h:outputText>


When the code is rendered in the browser you'll get the calendar converter to something like this 24. November 2008. So far so good. However, what if we didn't specify the date pattern as static text, but rather bind it to a value. This technique is efficient when you reuse the pattern in many places and want to keep the pattern in a central place. So say that we had a managed-bean called common with a method getDateFormat() : String that would provide the pattern. The code would look like this:


<h:outputText value="#{myBean.calendarObject}">
<f:converter converterId="calendarConverter" />
<f:attribute name="pattern" value="#{common.dateFormat}" />
</h:outputText>


When the code is rendered in the browser you'll get a blank response and see the following in the log, "pattern was not specified". The log statement is generated from out code above where we check for the attribute named "pattern". This is because of a requirement in the JSF 1.2 specification (JSR-252) that states (Section 9.4.2) that literal (static) text should be stored in the attribute map of the component and non-literal texts should be stored in the value expression map of the component. So to get the pattern from the value expression map we modify the getAsString method as follows:



public String getAsString(FacesContext ctx, UIComponent component, Object value) {

// Get the Calendar to convert
Calendar calendar = (Calendar) value;

String pattern = "";

// Obtain attributes specified along with the converter
Map<String, Object> attributes = component.getAttributes();

// Check if the pattern attribute was specified
if (!attributes.containsKey("pattern")) {

ValueExpression ve = component.getValueExpression("pattern");
if (ve == null) {
System.out.println("pattern was not specified");
return "";
} else {
pattern = (String) ve.getValue(ctx.getELContext());
}
} else {
pattern = attributes.get("pattern");
}

// Create a DateFormatter for the pattern
DateFormat outputFormat = new SimpleDateFormat(pattern);

// Format the calendar
try {
Date date = originalFormat.parse(calendar.getTime());
return outputFormat.format(originalDate));
} catch (ParseException ex) {
ex.printStackTrace()
return "";
}
}


The difference is that we now first check to see if there is a literal value specified. If not, we check if there is a value expression, and if there is no value expression either we will fail. If there is a value express we evaluate it and use it as our pattern.

Tuesday, 28 October 2008

Open Source vs. Commercial Software

Today I stumbled upon the following article about Open Source vs Commercial Software. It's quite entertaining and shows may of the pros and cons for both open source and commercial software licensing.

http://www.isitedesign.com/insight/08_07/open-source-versus-commercial-web-software.cfm

Enjoy!

Friday, 24 October 2008

Replacing TopLink Essentials with OpenJPA as my persistence provider

During the development of my latest pet project I decided to go head-on with many of the latest Java Enterprise APIs. One of these was the Java Persistence API (JPA), which I had already used in a handful of projects before. On previous projects the persistence requirements were very simple. I could use JPA out-of-the-box with TopLink Essentials which is the standard set-up for a JPA project in NetBeans/GlassFish. However, for this new pet project of mine I was in need of storing large binary objects (BLOBs). I was shocked to discover that TopLink Essentials doesn't support the Fetching configuration for relationships and properties. Instead it will Fetch.EAGER everything in a relationship and property. This made my application crash hard (OutOfMemoryException) when ever I would query for all entities containing the BLOB. So, I set out to replace the persistence provider. First I looked at Hibernate. I used Hibernate before JPA was released and never had much trouble with it. Unfortunately I found that Hibernate also doesn't support the fetching configuration (in JPA mode). That lead me to OpenJPA which really surprised me. It is well documented, clean, easy to use, and support the fetch configuration. I've now replaced the persistence provider on two projects with OpenJPA and the performance has increased significantly. However, here are a few gotchas that you have to look out for:


  • Auto-generated identity fields must not have a preset value in your JavaBean (hence, this would give you problems:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id = 0L


    Instead you should write

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


  • Collections are Fetch.LAZY by default, so if you got an existing using TopLink Essentials, you have to double check that your relations are not throwing LazyInitializationException upon fetching outside the transation.

  • Remember to specify the Fetch depth (openjpa.MaxFetchDepth) in persistence.xml for using the Fetch.EAGER configuration

  • TopLink Essentials compiles named queries when your application is deploy on the application server, OpenJPA on the other hand compiles the named queries upon first usage.

  • When enabling SQL DDL on OpenJPA it doesn't generate foreign key constraints, unlike TopLink Essentials



That's all for now. I'd love to hear about your experiences with OpenJPA or any other persistence provide you find suitable for your need.

Friday, 10 October 2008

Cycling

For the past week I've been cycling to and from work. That might not sound like a big deal to you, but it has certainly been a challenge for me. In the past it has been all to easy to jump into the car and head off for work. No more, I've decided. The distance to work is very do-able, 5.5 KM each way. It's better for me and it's better for the environment. The biggest problem so far has been the uphill route on my way back. Nevertheless, I've made great progress already. The first day was absolutely hell! When I got to work I could barely breathe and I had to spend several minutes in the bike shed to compose myself. On the third day I managed to cut off 5 minutes from the ride, and today I was only plagued by fatigue in my joints. I'm looking forward to seeing how I'll be feeling on Monday and if I can take another week.

Thursday, 9 October 2008

MyFaces and Facelets - The Definitive Guide

For the past five months or so, I've had the pleasure of participating as a contributing author and editor of the recently released Apress publication, "MyFaces and Facelets - The Definitive Guide".



It was a great experience that I hope that I'll be able to relive in the near future on other book writing projects. What I liked about the book was the focus on the array of JSF components under the MyFaces Apache project. Most people seem to think that MyFaces is simply an implementation of the JavaServer Faces specification. MyFaces is an umbrella project for JavaServer Faces related technologies. The most famous of the sub-projects is the Tomahawk components project which provides a lot of useful JSF component that I certainly couldn't live without.

The focus of the book is on technologies under the Apache MyFaces project as well as the Facelets technology. Facelets is another very important JSF technology that deserves more attention from the community. There are lots of people using Facelets, but little development is going on to make it truly professional.

The book is not for newcomers to JSF, but for programmers already familiar with the basics of JSF. If you are looking to get familiar with JSF I can highly recommend JSF In Action by Kito D. Mann published by Manning.

Thanks to Zubin Wadia and Hazem Saleh for making the project a great experience!