My blog has moved!

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

Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

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!

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.

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!

Wednesday, 6 August 2008

Project-based formatting in NetBeans 6.5

Being part of the NetBeans Community Acceptance Testing (NetCAT) Programme has definate advantages. For one, you get to try out all the new features planned and influence how they will work before being released to the general public (that is not quite true....anyone can download the daily development builds).



One of the features in the upcoming NetBeans 6.5 that I'm particularly happy about is Formatting by project. In NetBeans it has always been one configuration for all projects. This is slowly changing. During NetCAT for 6.1 the "Shared Library" feature was implemented to detach library management from NetBeans and thereby making projects more portable. So, this time the brilliant guys on the NetBeans development team implemented a feature making it possible to do project-based formatting. This is a great feature when you work on many different projects with different formatting requirements. Way to go! My hope is that for the next version of NetBeans they will also have made template management project-based.

Friday, 18 April 2008

Creating a generic error page for JSF

Sometimes using FacesMessages is not sufficient for reporting errors. For example, if you have a runtime error (invalid JSF mark-up or NullPointerExceptions) it is difficult to report them using FacesMessage.

Creating a generic error page for JSF is similar to creating a generic error page for plain JSP applications. You'll need a configuration in web.xml to tell the servlet container to redirect errors to a given page. Then you'll need to create that page as well as a backing bean that can show you the stacktrace or error message.

web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

... markup for your web app ...

<error-page>
<error-code>500</error-code>
<location>/Error.jsp</location>
</error-page>

</web-app>


With that we will get the servlet container to forward any Internal Server Errors (HTTP 500) to the page Error.jsp.

Okay, now we need to create a bean that will prepare the error message based on the exception that was thrown:

Error.java

package bigallan.beans;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;

public class Error {

public Error() {}

public String getStackTrace() {

// Get the current JSF context
FacesContext context = FacesContext.getCurrentInstance();
Map requestMap = context.getExternalContext().getRequestMap();

// Fetch the exception
Throwable ex = (Throwable) requestMap.get("javax.servlet.error.exception");

// Create a writer for keeping the stacktrace of the exception
StringWriter writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);

// Fill the stack trace into the write
fillStackTrace(ex, pw);

return writer.toString();
}

/**
* Write the stack trace from an exception into a writer.
*
* @param ex
* Exception for which to get the stack trace
* @param pw
* PrintWriter to write the stack trace
*/
private void fillStackTrace(Throwable ex, PrintWriter pw) {
if (null == ex) {
return;
}

ex.printStackTrace(pw);

// The first time fillStackTrace is called it will always be a ServletException
if (ex instanceof ServletException) {
Throwable cause = ((ServletException) ex).getRootCause();

if (null != cause) {
pw.println("Root Cause:");
fillStackTrace(cause, pw);
}
} else {
// Embedded cause inside the ServletException
Throwable cause = ex.getCause();

if (null != cause) {
pw.println("Cause:");
fillStackTrace(cause, pw);
}
}
}
}


Now that we have the Backing Bean we need to register it in faces-config.xml:


.. usual faces-config stuff ..

<managed-bean>
<managed-bean-name>Error</managed-bean-name>
<managed-bean-class>bigallan.beans.Error</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>


And lastly the JSP page (Error.jsp) displaying the error:

.. usual JSP header stuff ..

<h:panelGrid>
<h:outputText value="The follow error occured:" />
<h:inputTextarea style="width: 100%;" rows="20" readonly="true" value="#{Error.stackTrace}" />
</h:panelGrid>


That's all!

Enjoy.

Saturday, 29 March 2008

Using my Nokia 6120 for presentations

Today I noticed a cool feature of my new Nokia 6120 mobile phone. From it's download menu I was able to download a presentation tool from Nokia that turns the phone into a remote control for my PC. I've been thinking about getting a separate presentation device as I do a fair share of presentations and hate having to walk back to my PC everytime I want to move to the next slide. So, the way it works is by having a java application on the phone that emulates the mouse and an application on the PC that turns the keypresses on the phone into mouse movesments on the PC. I've tried it out with PowerPoint and works great. The tool also supports other applications out of the box such as Winamp and Media Player. The desktop tool can futhermore configure the remote control for other programs as well by specifying what should happen when each individual key on the phone is pressed.



The application (containing both the desktop application and the Java ME application) can be downloaded from the Nokia Community Portal: Mosh.

Links:

Wednesday, 19 March 2008

Shared libraries finally made it to NetBeans

Today I installed NetBeans 6.1 beta. I've always been a great fan of NetBeans and participated in the Community Acceptance Testing programme (NetCAT) for version 4.0 and 6.0.

I haven't had time to go through all the changes yet, but one thing caught my attention immediately, the "Shared Library" functionality. It has always amazed me that this feature was not implemented way sooner. I have never used the built-in library manager for third-party libraries as the information about the libraries were not included with the projects, i.e. when I create a third-party library in the Library manager for say Apache Commons Configuration and use that in my project, it will break the built for not only other developers by also my continuous integration server. The alternative is to simply add the third-party library directly to the project as jars. The downside about that is that you can't attach the source and JavaDocs, so the inline code completion becomes almost useless. A third alternative is to manage dependencies completely outside of the IDE using Ant and Maven build scripts. I use to do this when using Eclipse, however then you have to update the dependencies in both the IDE and the build script = twice the work.

Back to NetBeans 6.1. When creating a project you now get the offer to enable "sharable libraries". When enabling this feature you are asked to specify the location where the libraries should be saved. By default it will suggest ..\libraries, which is a bit strange considering that it is outside the project folder. I guess it depends on the configuration management practices used on the project. Personally I always check in third-party libraries (as long as there are no licensing issues preventing it). In that way I alaways know that I can build the software anywhere on any machine (that includes my CI box).



After having enabled sharable libraries, NetBeans will automatically copy library to the specified folder when you add dependencies to your project. Furthermore, if you find out that you'd rather have your sharable libraries in a different location, you can simply change the location click "Save" and it will re-create the sharable libraries. Very neat!

I can imagine that they will continue working on the feature at NetBeans and this feature will become even better before the next release.

Tuesday, 18 March 2008

Example of using custom facelet tags

Rather than using includes when creating templates you can create your own custom facelet tags without the husle of creating a JSF component from scratch. As an example, I'll create a menu tag that can be used to switch a selected menu item on and off.

Here is the menu (save it as /WEB-INF/facelets/tags/menu.xhtml):


<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<h:panelGrid columns="10">
<h:outputText styleClass="menuItem" value="Home" />
<h:outputText styleClass="menuItem" value="Some page" />
<h:outputText styleClass="menuItem" value="Another page" />
<h:outputText styleClass="menuItem" value="Third page" />
</h:panelGrid>
</ui:composition>


Here is the cascanding style sheet:

.menuItem {
border: 1px solid black;
}

.menuItemSelected {
background: red;
color: white;
font-weight: bold;
}


To make the menu into a tag you create a facelets tag library. I'll call it mytags.taglib.xml and place it in /WEB-INF/facelets/:


<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://bigallan.blogspot.com/mytags
<tag>
<tag-name>menu</tag-name>
<source>tags/menu.xhtml</source>
</tag>
</facelet-taglib>


To make the web application recognise your tag library you need to update add the following context parameter to web.xml:

<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/facelets/mytags.taglib.xml</param-value>
</context-param>


If you have more than one custom tag library you can separate them with semicolons (;)

On your pages you can now include the menu tag:


<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:mytags="http://bigallan.blogspot.com/mytags">
<head>
<title>My page</title>
<link href="css/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<mytags:menu home="true" />
</body>
</html>


All we need to do now is to look out for the attributes of the custom tag. Attributes are automatically turned into variables on the tag pages, so we simply make the following changes to /WEB-INF/facelets/tags/menu.xhtml:


<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<h:panelGrid columns="10">
<h:outputText styleClass="menuItem #{home == 'true' ? 'menuItemSelected' : ''}" value="Home" />
<h:outputText styleClass="menuItem #{somePage == 'true' ? 'menuItemSelected' : ''}" value="Some page" />
<h:outputText styleClass="menuItem #{anotherPage == 'true' ? 'menuItemSelected' : ''}" value="Another page" />
<h:outputText styleClass="menuItem #{thirdPage == 'true' ? 'menuItemSelected' : ''}" value="Third page" />
</h:panelGrid>
</ui:composition>


To turn all menu items on you code do the following:


<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:mytags="http://bigallan.blogspot.com/mytags">
<head>
<title>My page</title>
<link href="css/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<mytags:menu home="true" somePage="true" anotherPage="true" thirdPage="true" />
</body>
</html>


Enjoy!

Suggested reading on the subject:

Monday, 17 March 2008

Creating timers in EJB3

While the EJB 3.1 expert group is working on the improved timer service using annotations (See New Features in EJB 3.1) I thought that I'd just bring a small entry on using the timer service in EJB 3.

The timer service works by telling the service when it should timeout (i.e. when shall the "alarm" go off). You can add to this by telling it when it should timeout the first time, and how often (in ms) it should timeout after that. You define which methods on the bean that should be invoked upon timeout by annotating them @Timeout. The timer service is initialised by annotating a TimerService object as a @Resource.

Okay, before I show the code, these are the methods that we need:


  • A method for starting the timer

  • A method for stopping the timer

  • One or more listener methods that will be invoked when the timer has timed-out




@Stateless
public class MyTimerBean implements MyTimerLocal {

/** Service used for scheduling tasks. */
@Resource private TimerService timerService;

/**
* Starts the scheduler.
*
* @param startDate
* Start date
* @param interval
* Interval at which the timeout shall repeat
* @param timerName
* Timer to start
*/
public void startTimer(Date startDate, Long interval, String timerName) {
this.timerService.createTimer(startDate, interval, timerName);
}

/**
* Stops a given scheduler.
*
* @param timerName
* Timer to stop
*/
public void stopTimer(String timerName) {
for (Timer timer : (Collection) this.timerService.getTimers()) {
if (timer.getInfo() instanceof String) {
if (((String) timer.getInfo()).equals(timerName)) {
timer.cancel();
return;
}
}
}
}

/**
* {@link Timeout} event handler for generating a report.
*
* @param timer
* Timer that timed out
*/
@Timeout
public void generateReport(Timer timer) {
if (timer.getInfo() instanceof String) {
if (((String) timer.getInfo()).equals("Generate Report")) {
... do some processing ...
}
}
}

/**
* {@link Timeout} event handler for cleaning the cache.
*
* @param timer
* Timer that timed out
*/
@Timeout
public void cleanCache(Timer timer) {
if (timer.getInfo() instanceof String) {
if (((String) timer.getInfo()).equals("Clean Cache")) {
... do some processing ...
}
}
}
}


Right, so we have a method for starting a timer (startTimer). This method needs to be invoked in order to start the timer. This is one of the drawbacks of the TimerService, you cannot tell it to just start when the application is deployed (will be there in EJB3.1). Instead I use a Servlet Context Listener to invoke the startTimer method when the accompaying webapplication is deployed:


public class TimerInitialisationListener implements ServletContextListener {

/** Local interface for {@link MyTimerBean}. */
@EJB private MyTimerLocal myTimer;

/**
* Initialises the timer service.
*
* @param event
* Event that invoked the listener
*/
public void contextInitialized(ServletContextEvent event) {
Calendar now = Calendar.getInstance();
now.set(Calendar.HOUR_OF_DAY, 0);
now.set(Calendar.MINUTE, 0);
now.set(Calendar.SECOND, 0);
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH);
int dayOfMonth = now.get(Calendar.DAY_OF_MONTH);
int hourOfDay = now.get(Calendar.HOUR_OF_DAY);
int minute = now.get(Calendar.MINUTE);
Long repeat = 60000L * 60L * 24L;
LogFactory.getLog(TimerInitialisationListener.class).info("Start time: " + now.getTime());
LogFactory.getLog(TimerInitialisationListener.class).info("Repeat every: " + repeat + " ms (" + (repeat / 3600000L) + " hrs)");

myTimer.startTimer(new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute).getTime(), 60000L * 60L * 24L, "Generate Report");
}

/**
* Context is uninstalled from the servlet container.
*
* @param event
* Event that invoked the listener
*/
public void contextDestroyed(ServletContextEvent event) {
LogFactory.getLog(TimerInitialisationListener.class).info("Stopping timer");
myTimer.stopTimer("Generate Report");
}
}


When you deploy the enterprise application you will see that the timer is set to start at midnight and execute every 86400000 ms (i.e. every 24 hours). What you will notice is that it is only the generateReport method that is executed fully at every timeout as I've put in a check to ensure that it is the correct action being executed. Instead of using a String as the identifier of the Timer you can create create your own custom objects as pass them instead (just remember to make it serializable).

That's all for now. I'll bring another entry when EJB3.1 has been released and the new timer service annotations have been implemented.

On a side note, I've used Quartz before and it's great - I just like to stick to the standards if it can do the job.

Checkout the JavaDocs for the TimerService for more information.

UPDATE: 6. May 2008: Yesterday I was preparing some code using the timer service and I noticed that only the first method annotated with @TimeOut is executed upon timeout. Therefore, use only one @TimeOut method per SessionBean.

Saturday, 15 March 2008

Yippiee my new phone arrived

For a long time my old phone has been way past retirement. It was a Qtec 2020 (I believe). I've always loved smartphones and hated the glorified music players (e.g. Sony Ericsson). I don't see the point in the fancy music player phones, but that is probably because I'm perfectly happy with my iPod and have no plans of replacing it for something less cool.

Anyways, the Qtec acted up a long time ago. I used it as my organiser, phone and GPS for the car. When it suddenly started losing all its memory and at the same time I misplaced my stylus, I thought that it was high time to get a new phone. So this time I decided not to get a smartphone (mostly because the complete lack of market for smartphones in Denmark - this makes it very expensive!). Instead I got myself a Nokia 6120 with all the latest services provided on the 3G network (Skype, MSN, MobileTV, etc).

From the End-to-End Web Service Tutorial on NetBeans.org So far I'm loving the phone! It is fully compatible with Java MIDP 2.0 - so I'll have to get cracking with Java ME to make some applications soon. Can anybody recommend a good starting point for Java ME programming? My background in Java is purely enterprise and web. NetBeans got some cool mobile development aids that I'll be trying out - but I'd really like to know the basics before I start all the dragging and dropping. In anycase I think this is a good place to start: NetBeans 6.0 Mobility Documentation. It's got a pretty good tutorial for creating a mobile Dilbert browser.

Ordered the certification books

I've finally ordered the certification books that I mentioned in a previous post (SCJP Sun Certified Programmer for Java 5 Study Guide (Exam 310-055): Study Guide Exam 310-055 and Sun Certified Enterprise Architect for Java EE Study Guide (Exam 310-051): Study Guide Exam 310-051).

It is my personal goal to have taken both certifications before the end of April. I was tempted to also get the Certification Press book about Sun Certified Business Components Developer, but it got such bad reviews on Amazon that I didn't dare to get it. Unfortunately it seem to be the only study guide for Business Components Development.

Anyways, I'm looking forward to the books getting here so that I can get started!