DZone

Friday, May 6, 2011

Groovy Builders and Modularity

Groovy Builders are a very nice way for hiding 3rd-party APIs complexity, and help you cleaning up a lot your code, but when the thing to be built is large, the method where the builder is used gets really huge. In this post I will explain you the way to split the builder block and make it modular.

Let's start analyzing how Builders work commonly. The builder uses to have an entry-point method which takes a closure as parameter, within the closure you can invoke any builder method to start configuring the target artifact.

Let me show it with an example, I'll use Grails' HibernateCriteriaBuilder and a well know domain for us (developers) which is Issue Tracking:

We have a Map populated from a form holding filtering values:

def filter = fromFilterForm()

def criteria = Issue.createCriteria()

def issues = criteria.list {

  if(filter.author) {
    eq('author', filter.author)
  }

  if(filter.title) {
    like('title', "%${filter.title}%")
  }

  if(filter.description) {
    like('description', "%${filter.description}%")
  }

  if(filter.priority) {
    ge('priority', filter.priority)
  }

  if(filter.created) {
    between('created', filter.created.from, filter.created.to)
  }

  if(filter.statuses) {
    inList('status', filter.statuses)
  }

}

It is not the case for a huge building closure, but you can figure out where I'm pointing to.

So now, I will change it to achieve the same result but in a modular way. For it, I will move all the builder related lines to separate closures held by a map which shares the same keys than the filter map. And I will use a very helpful method in Closure called delegate(Object) so I can propagate the same behavior in HibernateCriteriaBuilder#list(Closure) to all the tiny closures.
If a key is not present in filter map, because it's not desired to filter by it, the closure under the same key in the closures map won't be invoked so we can avoid using that much if statements.

void initClosures() {
  this.closures = [
    author: { eq('author', it) },
    title: { like('title', "%${it}%") },
    description: { like('description', "%${it}%") },
    priority: { ge('priority', it) },
    created: { between('created', it.from, it.to) },
    statuses: { inList('status', it) }
  ]
}

void buildCriteria(def criteria, def filter) {
  filter.each{
    if(it.value){
      def c = this.closures[it.key]
      c.delegate = criteria
      c(it.value)
    }
  }
}

void filterIssues() {
  def filter = fromFilterForm()

  def criteria = Issue.createCriteria()

  criteria.list {
    buildCriteria criteria, filter
  }
}

This is just an example for showing you up how to write a more modular builder code, but you can apply this approach everywhere you need it.

Questions, comments and corrections are welcome.
Good coding to everyone.

Gaston.

Monday, January 24, 2011

Bash Script to launch Java Application

If you develop or just use any Java standalone application, you may know it is not comfortable at all to launch it from a linux console. You have to invoke it with the java command this way.

user@host:~$ java -cp myapp.jar:any-thirdparty-lib.jar com.myapp.MainClass some parameters

You can simplify it a lot packaging your application as an executable jar. The file structure should be something like this.

app_home
  lib
    any-thirdparty-lib.jar
  myapp.jar

myapp.jar must contain the special file META-INF/MANIFEST.MF with the following content.

Manifest-Version: 1.0
Class-Path: . lib/any-thirdparty-lib.jar
Main-Class: com.myapp.MainClass

There are a lot of tools to auto-generate it, such as Eclipse export Wizard, Ant task and Maven jar plugin just to mention some.

Last step has reduced a lot the verbosity of the java command. You can invoke an executable jar this way

user@host:~$ java -jar myapp.jar some parameters

It is much better. Isn't it? but still has some problems. Firstly, it is path-dependent, you must be placed at app_home folder for it to work since in the manifest file the dependencies are listed in a relative to the main jar form. Secondly it is not that natural for linux command-line users, it should be much better to just invoke it this way

user@host:~$ myapp some parameters

So, in order to achieve it we will create a really simple yet useful bash script to launch our java app ala linux. I googled it for a while to find an example but without any luck, so I did it myself.
You will need to create a file called myapp in app_home folder with execute permission and with the following content

#!/bin/sh
SCRIPT_PATH=$(readlink -fn $0)
APP_HOME=$(dirname $SCRIPT_PATH)
java -jar $APP_HOME/myapp.jar $@

The first thing to do is to know the real path for the app_home, this way we will be able to invoke it even if we are not placed in the app_home folder. It is the preferred way for invoking a command which works with files, we go to the folder were the files are and it will be more comfortable for passing the file names as parameters.

So, thanks to the especial bash argument $0 we know the path which the script was invoked with. But it is not enough to use it directly, since another nice thing to do with scripts is to create a symbolic link in any folder included in the PATH environment variable, such as ~/bin or /usr/bin so we can just type the script name without including any folder. This way, if we create such link for our app, $0 will be /usr/bin/myapp and we cannot use it for getting the app_home real path. But we solve it with readlink, this way we resolve the link and we get the physical path the link points to.

Once we have the real script path, we use dirname to get the folder it is placed in. Finally, we use the APP_HOME variable to construct the absolute path to our app jar, it will let java to resolve all relative paths in the manifest Class-Path header.

Done. It is just a 3 lines bash script but it let invoke our java applications in a linux-like  manner. I don't know if it is the best solution, but it works, and it can be improved for sure.

Hope it helps you.
Gaston.

Wednesday, January 19, 2011

A Better Iterator

I've implemented an Iterator, which is a little better than the standard, in a way that it keeps reference to the last returned element.

So it can be used as a regular iterator since it implements java.util.Iterator<E>, but it adds a new method "public E current()", which returns the last element returned by the next() method.

The way it works is by wrapping any given iterator. It can be useful, for instance, when you work with the GoogleCollections API (now called Guava), since internally it is implemented with lazy iterators.

You can pass just this iterator as a parameter to other methods which may collaborate in the process while iterating the elements in a collection. Any method knows and can work with the current element, and also can move the iterator forward, in this case when it returns, the calling method will know the new current element.

Maybe you need it sometime, maybe not. I just want to share it.

Here is the class:


package org.lalala;

import java.util.Collection;
import java.util.Iterator;

public class ImprovedIterator<E> implements Iterator<E> {

 private Iterator<E> delegate;
 private E current;
 private boolean nextCalled;

 public ImprovedIterator(Iterator<E> iterator) {
  this.delegate = iterator;
  this.current = null;
  this.nextCalled = false;
 }

 @Override
 public boolean hasNext() {
  return this.delegate.hasNext();
 }

 @Override
 public E next() {
  this.current = this.delegate.next();
  this.nextCalled = true;
  return this.current;
 }

 @Override
 public void remove() {
  this.current = null;
  this.nextCalled = false;
  this.delegate.remove();
 }

 public E current() {
  if (!this.nextCalled) {
   throw new IllegalStateException("next() was never called or not called again after a remove().");
  }
  return this.current;
 }

 public static <E> ImprovedIterator<E> iteratorFor(Collection<E> collection) {
  return new ImprovedIterator<E>(collection.iterator());
 }

 public static <E> ImprovedIterator<E> iteratorFor(Iterator<E> iterator) {
  return new ImprovedIterator<E>(iterator);
 }

}

Gaston.

Thursday, November 18, 2010

Better support of java.util.UUID for Db4o

If you are using Db4o for persistence and you have to identify your objects using UUIDs, currently you have two possible choices.
  • Use db4o UUID
  • Use java.util.UUID


Db4o UUID
The first alternative is to use db4o's own solution, it is easy, doesn't need extra effort since it is all done by db4o out-of-the-box. The main drawback is that it is ugly from a design point of view.

Here is an example provided by Db4o.

As you can see, it is not comfortable at all, you need extra db4o methods invocations such as container.ext().getObjectInfo(obj).getUUID() and container.ext().getByUUID(idForObject). Also the objects are not activated so you have to do it manually.
Another thing I don't like about it, is the fact that you have to import a db4o-specific class in core classes which have to deal with uuids, and it is not acceptable.
Finally your persistent classes are not unit-testable outside the persistence context since Db4o is which generates the uuids at store-time.

For all the disadvantages pointed out above it is not a suitable solution.

java.util.UUID as String
So we have the second alternative, to use java.util.UUID.
It is an utility class for working with UUIDs which is included in the Java runtime, therefore, it is ok to import it everywhere you need, such as having an id field in your persistent objects.
But the bad news are that Db4o lacks native support for java UUIDs.
Here in this example they propose to hold the UUID as a String field, so you can index it for speed up querying. It is a bad idea, since UUID in String format takes too much space and it is not nice to treat UUIDs as strings everywhere when you have a specialized and optimized class for it.
However, it is even worst to hold it in an UUID field, since it is a regular object for Db4o and if you want to query by it, Db4o will populate all UUID instances to compare them against the desired value using the equals method. An as you can imagine, it is terrible for performance.


java.util.UUID with custom type handling
This one is the best choice, and is what this post is all about. A very powerful feature (although very hard to work with) is the TypeHandlers mechanism. The main idea is, by implementing a couple of interfaces, to control the way in which Db4o handles the persistence (writing, reading, indexing, etc) of objects of certain classes for which you want special treatment.

In my current project, I use UUIDs a lot, it is a main feature for me to find an element by its id (UUID), in some cases even without knowing the concrete class, so I have to query by id all the elements in the database. But lately I have experienced some performance issues all related to this key ability.
For solving it I decided to improve the UUID handling in my project. I searched a lot in the Db4o Developer's site and in the internet in general, but without any luck. So I opted for implementing my own type handler.

This time, with a little bit of better luck, I found an abstract class from which to extend mine. It is com.db4o.internal.handlers.BigNumberTypeHandler. Don't stop in the name, it is called this way because Db4o uses it as base class for BigDecimal and BigInteger handlers, but it could be renamed in the future.

This abstract class gives you a couple of hooks for you to convert your class to and back again from byte array, then it takes care of everything, writing, reading, indexing, comparing, etc. So it could be named ByteArrayTypeHandler or something similar.

Let's see how the type handler looks like
public class UuidTypeHandler extends BigNumberTypeHandler<UUID> {

 @Override
 protected int compare(UUID uuid1, UUID uuid2) {
  return uuid1.compareTo(uuid2);
 }

 @Override
 protected UUID fromByteArray(byte[] bytes) {
  ByteBuffer buffer = ByteBuffer.wrap(bytes);
  LongBuffer longBuffer = buffer.asLongBuffer();
  return new UUID(longBuffer.get(0), longBuffer.get(1));
 }

 @Override
 protected byte[] toByteArray(UUID uuid) {
  byte[] byteArray = new byte[(Long.SIZE / Byte.SIZE) * 2];
  ByteBuffer buffer = ByteBuffer.wrap(byteArray);
  LongBuffer longBuffer = buffer.asLongBuffer();
  longBuffer.put(new long[] { uuid.getMostSignificantBits(),
      uuid.getLeastSignificantBits() });
  return byteArray;
 }

}
As you can see I'm using ByteBuffer for doing the conversion, I create a byte array which size is the bytes needed to represent 2 Longs (Long.SIZE / Byte.SIZE) * 2), in Java a Long is represented using 64 bits and a byte uses 8 bits, so our array will be of size 16, 8 bytes per each Long. Finally I write first the most significant bits of the UUID and then the least significant bits.

Converting from byte array to UUID back again is just a matter of reading the two Longs in the right order.
I have only one more method to mention, compare, which is pretty trivial, I just delegate on UUID.compareTo(other).

Now I'll show you how to start using it. You will need to register the type handler in the Db4o configuration like this:
EmbeddedConfiguration configuration = Db4oEmbedded.newConfiguration();
// Simple predicate for matching all UUID instances
TypeHandlerPredicate predicate = new SingleClassTypeHandlerPredicate(UUID.class);
// Register the type handler for handling all UUID.class objects
configuration.common().registerTypeHandler(predicate, new UuidTypeHandler());

Firstly you have to create a new configuration instance. You will need a TypeHandlerPredicate as well, it is used to know when to used the TypeHandler we are registering, you can create your own implementation if the matching logic is not that simple, but for this case it is enough with SingleClassTypeHandlerPredicate. Finally, you have to invoke registerTypeHandler(...) method to in commonConfiguration.

Now that you have registered the TypeHandler you are able to index all UUID fields for better query performance. For trying it you can download the example project. You will find the UuidTypeHandler class, as well as a dummy class which has an UUID field called id. Here you have it:
public class UniversalUniqueElement {

 private static int COUNTER = 1;

 private UUID id;
 private String name;

 public UniversalUniqueElement() {
  this.id = UUID.randomUUID();
  this.name = "Element #" + UniversalUniqueElement.COUNTER++;
 }

 public UUID getId() {
  return this.id;
 }

 public String getName() {
  return this.name;
 }

 @Override
 public String toString() {
  return String.format("UniversalUniqueElement [id=%s, name=%s]", this.id, this.name);
 }

}

You can create the index for id field this way:
// Now we have registered the handler we are able to index the id field
configuration.common().objectClass(UniversalUniqueElement.class).objectField("id").indexed(true);

The example project also contains a test for you to try it in action. It runs two methods, with and without the type handler, with the very same loop which creates 1000 elements and then queries them by their ids. The test writes to console the spent time for each method, so you will see the huge difference.

Here you have an Eclipse/Maven project for trying it all together. Download