Wednesday, January 26, 2011

Experimenting with JPA 2.0 and Spring 3.0.x. A libraries nightmare.

I was making JPA samples while I was reading Spring Persistence with Hibernate. I started to make everything from scratch. The book uses Maven to manage the sample project, but I'm not a Maven person, so I decided to leave Maven and do it the good old way : compile, see a ClassDefNotFoundException raised, find out which library I have to add to the classpath, download it, extract it, sometimes figure out which extracted libraries are not necessary, adding the necessary ones to my project... It sounds like Daft Punk's Technologic ! (compile it, break it, find it, get it, extract it, guess it, add it...) I finally made it, but I can't remember how long it took me to do all these steps. Too long for sure.

Which is why I started studying Maven ! Although I knew about Maven's dependencies management, I never actually used it. There are some good online books at Sonatype. I went straight to the Maven by Example book. This is a good book. I discovered that Maven is much more than a dependencies management tool !

From there, I made a new JPA/Spring project from scratch, using Eclipse's Maven plugin, and while looking at Spring Persistence with Hibernate's xml, I added the necessary dependencies. No effort. Maven did it all.

Here is my pom.xml, using Hibernate JPA, Spring 3.0.5(using transactions without aspectj) and H2Database. It looks big, but it's just a bunch of dependencies declarations, which are made even easier via Eclipse's plugin.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>springwithmaven</groupId>
  <artifactId>springwithmaven</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>springwithmaven</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

    <repositories>
        <repository>
            <id>JBoss Repo</id>
            <url>http://repository.jboss.com/maven2</url>
            <name>JBoss Repo</name>
        </repository>
        <repository>
            <id>ibiblio mirror</id>
            <url>http://mirrors.ibiblio.org/pub/mirrors/maven2/</url>
        </repository>
        <repository>
            <id>jboss-public-repository-group</id>
            <name>JBoss Public Maven Repository Group</name>
            <url>https://repository.jboss.org/nexus/content/groups/public/</url>
            <layout>default</layout>
            <releases>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
            </releases>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
            </snapshots>
        </repository>
    </repositories>

  <dependencies>
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-core</artifactId>
     <version>3.0.5.RELEASE</version>
 </dependency>  
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context</artifactId>
     <version>3.0.5.RELEASE</version>
 </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>3.4.0.GA</version>
    </dependency>
    
    <dependency>
     <groupId>org.hibernate.javax.persistence</groupId>
     <artifactId>hibernate-jpa-2.0-api</artifactId>
     <version>1.0.0.Final</version>
    </dependency>
    <dependency>
     <groupId>com.h2database</groupId>
     <artifactId>h2</artifactId>
     <version>1.3.149</version>
    </dependency>
    <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-tx</artifactId>
     <version>3.0.5.RELEASE</version>
     <type>jar</type>
     <scope>compile</scope>
    </dependency>
    <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-orm</artifactId>
     <version>3.0.5.RELEASE</version>
     <type>jar</type>
     <scope>compile</scope>
    </dependency>
    <dependency>
     <groupId>commons-dbcp</groupId>
     <artifactId>commons-dbcp</artifactId>
     <version>1.3</version>
     <type>jar</type>
     <scope>compile</scope>
    </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.0</version>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>1.6.2</version>
        </dependency>    
  </dependencies>
</project>

Tuesday, January 25, 2011

Book review: Pro Git

Pro Git

I've been using both CVS and SVN at work, and never had the chance to try Git. I decided to learn about Git, so I looked for a book. I found Pro Git's homepage, with the book fully readable online, in several languages. We don't often have the chance to read free quality books online, but this one is 100% free. After spending some time on the train enjoying the first three chapters of the book, I decided to buy it. It's well worth it. The author did a great job presenting Git's functionalities, and the major differences with other version control systems.

The main chapters on Git basics and branching are very easy to follow. The author explains all the major commands, showing the command line and the execution result. You can read the book without even trying anything (although I would recommend to download Git and try as much as possible). The chapter on distributed workflows is particularly interesting. It shows you how Git is used in a project, depending on the size (and other factors) of the project. Finally, the author presents the major Git tools, explains how to customize Git, how to use it with Subversion (would you do that?), and how Git works internally, which is very instructive.

The book is thin, and easy to read, so anybody can finish it in a short time. If you want to get started with Git, you can pick up this book without hesitation.

I have one minor complaint : the book size is a bit different from other Apress books I have (may depend on the print ?). It breaks the balance of my beloved book shelf :)

Friday, January 14, 2011

Confirming Quartz Trigger firing times (especially cron expressions)

The Quartz Scheduler is very useful when it comes to scheduling jobs. It offers a wide range of trigger options, including cron-like expressions. Cron-like expressions are a bit obscure to read, unless you use them often. These expressions are explained in the CronExpression and CronTrigger classes API, and in the online tutorial. I sometimes need to make sure that the triggers will get fired at the proper time. The TriggerUtils class allows to output all firing dates of a trigger between two dates : TriggerUtils#computeFireTimesBetween(Trigger, Calendar, Date, Date). The Calendar parameter here is not a java.util.Calendar, but a org.quartz.Calendar, which can be annoying when using both java.util.Calendar and org.quartz.Calendar in the same class.

Making a sample program to output all firing times between two dates is rather simple :

import java.text.ParseException;
import java.util.List;

import org.quartz.CronTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.calendar.AnnualCalendar;


public class ConfirmTriggerFireTimes {

 public static void main(String[] args) throws ParseException {
  new ConfirmTriggerFireTimes().showTriggerFireTimes();
 }
 
 public void showTriggerFireTimes() throws ParseException {
  CronTrigger trigger = new CronTrigger();
  // Fire at 10:15am every Monday, Tuesday, Wednesday, and Thursday 
  trigger.setCronExpression("0 15 10 ? * MON-THU");
  java.util.Calendar startDate = java.util.Calendar.getInstance();
  startDate.set(2011,java.util.Calendar.JANUARY, 1);
  java.util.Calendar endDate = java.util.Calendar.getInstance();
  endDate.set(2011,java.util.Calendar.JANUARY, 31);
  outputFireTimeList(trigger, startDate, endDate);
 }
 
 @SuppressWarnings("rawtypes")
 private void outputFireTimeList(Trigger trigger, java.util.Calendar from, java.util.Calendar to) {
  List fireTimeList = TriggerUtils.computeFireTimesBetween(trigger, null, from.getTime(), to.getTime());
  for ( int i = 0; i < fireTimeList.size(); i++ ) {
   System.out.println(fireTimeList.get(i));
  }
 }
}
In this example, I want to confirm the firing dates of a trigger set to fire at 10:15am every Monday, Tuesday, Wednesday, and Thursday in January. The resulting output is :
Mon Jan 03 10:15:00 JST 2011
Tue Jan 04 10:15:00 JST 2011
Wed Jan 05 10:15:00 JST 2011
Thu Jan 06 10:15:00 JST 2011
Mon Jan 10 10:15:00 JST 2011
Tue Jan 11 10:15:00 JST 2011
Wed Jan 12 10:15:00 JST 2011
Thu Jan 13 10:15:00 JST 2011
Mon Jan 17 10:15:00 JST 2011
Tue Jan 18 10:15:00 JST 2011
Wed Jan 19 10:15:00 JST 2011
Thu Jan 20 10:15:00 JST 2011
Mon Jan 24 10:15:00 JST 2011
Tue Jan 25 10:15:00 JST 2011
Wed Jan 26 10:15:00 JST 2011
Thu Jan 27 10:15:00 JST 2011
Mon Jan 31 10:15:00 JST 2011
This looks good. We can see that any jobs associated to this trigger will be executed at 10:15am every Monday, Tuesday, Wednesday, and Thursday.

Sunday, January 9, 2011

Book review : The Android Developer's Cookbook : Building Applications with the Android SDK

The Android Developer's Cookbook is a recipe-styled book, where each recipe shows how to use a particular feature of the Android SDK. Each recipe is more or less independent of the others. It's not a classical beginners book, but I think it can still be used to start learning about Android development. It starts with an overview of the Android platform, then presents various recipes in a logical order. First, the most basic recipes : activities, intents, threads, services, alerts, widgets and other ui, events like key presses and Touch events. Then recipes explaining how to use specific functionalities : multimedia, hardware (sensors), networking, data storage, location services like Google Maps, and many more advances recipes. Finally, recipes on debugging.

The authors are using Eclipse and its Android plugin to create sample applications. The book is very easy to follow. There are a lot of code snippets, and some pictures to illustrate their execution. Anybody with some basic UI understanding (e.g. Swing experience) should easily read through the content. It's the kind of book you'd keep on your desk for further reference. It's not a complete reference book though. Explanations and samples are short, so you may still have to look for more detailed information in the online documentation. It's a nice cookbook. Not complete, but well worth reading.

Tuesday, January 4, 2011

Book review : Spring Persistence with Hibernate(Apress)

Spring Persistence with Hibernate (Beginning)

If you are looking for a book to learn about Spring and Hibernate, pass your way. If you are looking for a reference, pass your way. So who is this book for ? I think it is aimed at people who want to try a simple application using Spring3 and Hibernate 3.x (JPA2). It is fast paced, straight to the point. If you know what you are doing, it's a fun book. You'll start by setting your development environment (authors use Maven), configure Spring and Hibernate, make some domain classes, make some DAOs... Very fun. But don't expect to find answers if you're stuck somewhere.

There are some interesting explanations about persistence optimization like caching and lazy-loading, as well as a chapter about integration of frameworks like Dozer and Lucene. It also mentions REST and Spring MVC, and concludes with Grails and Spring Roo. These last two might be out of topic, but they have their own merit. I think they are worth reading.

I didn't notice many typos. Source snippets are neither too short nor too big. They illustrate well the explanation they are attached to. I already know about Spring3 and JPA2, but I never used Hibernate as my persistence provider. This book provided me a chance to try it. I felt it was not like any other technical books. Very enjoyable.