Tuesday, 24 March 2009

Moving to Kenai

Well having tried various PHP content management systems on retep.org I’ve just about had enough. I was trying Liferay as well (and that was looking good), but in the end I was spending way too much time on getting things working rather than getting down to coding I’ve decided to move back to using one of the “forges” out there.


The other reason was cost - running a dedicated server was just costing too much each month.


Anyhow I’ve going to move everything over to Project Kenai provided by Sun. It’s supports Mercurial, Forums a Wiki and more importantly Jira.


RetepTools is now over and it’s project page is now http://kenai.com/projects/reteptools, and Jira is now up to date with what was in Mantis.


I’ll be moving the MicroKernel over later tonight and I’ll be deciding on how to migrate the other projects over with the intention of shutting down the old site at the weekend. The one thing I have left to sort is getting a working Maven repository working. I’m not the only one using that site and want Maven so hopefully it wont be long (the main requestors are the ODFToolkit team).


Anyhow one this process is complete then this blog will be moving to become the main retep.org homepage.


Thursday, 12 March 2009

retepTools Concurrency Support

retepTools Concurrency Support


The retepTools library provides additional concurrency support to that provided by the java.util.concurrency package of JDK 1.5 or later.


The core component of the concurrency support provided by retepTools is the locking. By utilising a set of annotations, it is possible to mark a method so that the entire body of that method is bound to the scope of that Lock.


For example, we have a bean with a property. The properties value can be read by any number of Threads, but it can be set by only one at a time. In the normal java.util.concurrent.lock way you would write something like this:


import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;


public class MyBean

{

  private final ReadWriteLock lock = new ReentrantReadWriteLock();

  private int value;


  public int getValue()

  {

    lock.readLock().lock();

    try

    {

      return value;

    }

    finally

    {

      lock.readLock().unlock();

    }

  }


  public void setValue( int newValue )

  {

    lock.writeLock().lock();

    try

    {

      value = newValue;

    }

    finally

    {

      lock.writeLock().unlock();

    }

  }

}


Now imaging doing that on an object with dozens of properties... a lot of boiler plate code which is prone to typing errors. retepTools removes this boiler plate code by using a set of thee annotations: @Lock, @ReadLock and @WriteLock.


All three annotations follow a simple contract:


    * your object must implement a corresponding method for each annotation.

    * the associated method is named as it’s annotation, i.e. @ReadLock expects readLock(), etc.

    * that method must be declared either private or “protected final”.

    * the Lock object returned by those methods must also be final - specifically it must be the same object returned for every invocation of that method on that instance.


For convenience the class uk.org.retep.util.collections.ConcurrencySupport implements this contract for objects using @ReadLock and @WriteLock.


So here’s the above code rewritten to use the annotations:


import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

import net.jcip.annotations.ThreadSafe;

import uk.org.retep.annotations.ReadLock;

import uk.org.retep.annotations.WriteLock;


@ThreadSafe

public class MyBean

{

  private final ReadWriteLock lock = new ReentrantReadWriteLock();

  private int value;


  protected final Lock readLock()

  {

    return lock.readLock();

  }


  protected final Lock writeLock()

  {

    return lock.writeLock();

  }


  @ReadLock

  public int getValue()

  {

      return value;

  }


  @WriteLock

  public void setValue( int newValue )

  {

      value = newValue;

  }

}


Now thats alot cleaner, less error prone and yet easier to see what the business logic is rather than having it obscured by the locking mechanism.


retepTools also provides several concrete base classes to make this even easier. The main one is uk.org.retep.util.concurrent.ReadWriteConcurrencySupport which provides concrete implementations of readLock() and writeLock(). So the above example can be made even simpler by extending ReadWriteConcurrencySupport:


import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

import net.jcip.annotations.ThreadSafe;

import uk.org.retep.annotations.ReadLock;

import uk.org.retep.annotations.WriteLock;

import uk.org.retep.util.concurrent.ReadWriteConcurrencySupport;


@ThreadSafe

public class MyBean extends ConcurrencySupport

{

  private int value;


  @ReadLock

  public int getValue()

  {

      return value;

  }


  @WriteLock

  public void setValue( int newValue )

  {

      value = newValue;

  }

}


Now thats alot cleaner, less error prone and yet easier to see what the business logic is rather than having it obscured by the locking mechanism.


Footnotes


  1. I originally started to write this article back in February however since retepTools 9.2 a new annotation processor was added which performs additional sanity checks.
  2. Project Coin is currently taking proposals for small changes to the Java Language. One of those proposals was Automatic Resource Management and during the debate about that proposal Lock’s were brought up. Now locks are out of scope for that proposal and there is an additional one which now looks like it’s not going to be accepted. I’ll be writing another article about that one later.


Implementing custom types within JAXB

With JAXB it does a pretty good job in mapping between XML and Java Objects. In normal use this is fine but what happens when you need to use a custom data type for an attribute? Well JAXB supports this in binding so this article will describe this.


The originating issue that’s caused this article to be written cropped up at work earlier today where we had an issue with currency values. Over time the various programmers had naturally used a Java double to represent them but problems started to appear when some testers started to use amounts equivalent to €1.2 Billion and things started to fall apart.


Now obviously it’s bad practice to use double for monetary values (we’ve all done it at some point) due to the fact that specific values cannot be represented accurately (eg 39.995 is represented as 39.9949989[1]), it gets worse when dealing with large values. With large amounts you start to loose precision at the milli and penny levels, so adding 1¢ to the amount will fail because the double cannot handle it because of rounding errors.


So the solution is to use BigDecimal as it has arbitrary precision. With JAXB this is not a problem as it supports BigDecimal when defining an attribute with type xsd:decimal - as long as you own the xsd then it’s simply a case of changing it from xsd:double. The problem is when you don’t own the xsd, i.e. it’s an external specification. In this case you cannot change it as you would break other implementations. This is exactly where JAXB bindings[2] come into play.


Changing the object used in an attribute


In this first example taken from my xmpp project we have a series of xsd files and a single xjb file containing the bindings.


From client.xsd which defines the “jabber:client” namespace[3]:


<xs:element name='message'>

     <xs:complexType>

        <xs:sequence>

          <xs:choice minOccurs='0' maxOccurs='unbounded'>

            <xs:element ref='subject'/>

            <xs:element ref='body'/>

            <xs:element ref='thread'/>

          </xs:choice>

          <xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>

          <xs:element ref='error' minOccurs='0'/>

        </xs:sequence>

        <xs:attribute name='from' type='xs:string' use='optional'/>

        <xs:attribute name='id' type='xs:NMTOKEN' use='optional'/>

        <xs:attribute name='to' type='xs:string' use='optional'/>

       <xs:attribute ref='xml:lang' use='optional'/>

     </xs:complexType>

  </xs:element>


Now here the from and to attributes represent not just a string but a Jabber IDentifier JID which within the project is represented by the class uk.org.retep.xmpp.JID. This class ensures it’s both syntactically correct and provides access to the various components within the JID.


For JAXB to use this JID class instead of String we can either add the bindings into the original xsd or into a separate xjb file. I prefer the latter as it keeps the originals untouched so that if someone updates them then the bindings are not lost:


So to add the bindings for JID into the above message element we have the following bindings.xjb file:


<?xml version='1.0' encoding='UTF-8'?>

<bindings

    xmlns=”http://java.sun.com/xml/ns/jaxb”

    xmlns:xsd=”http://www.w3.org/2001/XMLSchema”

    xmlns:retep=”http://retep.org/xml/ns/retepTools”

    version=”2.0”>

   <bindings schemaLocation="client.xsd" node="/xsd:schema/xsd:element[@name='message']/xsd:complexType/xsd:attribute[@name='from']">

        <property>

            <baseType>

                <javaType name="uk.org.retep.xmpp.JID" parseMethod="uk.org.retep.xmpp.JID.parse" printMethod="uk.org.retep.xmpp.JID.print" />

            </baseType>

        </property>

    </bindings>

    <bindings schemaLocation="client.xsd" node="/xsd:schema/xsd:element[@name='message']/xsd:complexType/xsd:attribute[@name='to']">

        <property>

            <baseType>

                <javaType name="uk.org.retep.xmpp.JID" parseMethod="uk.org.retep.xmpp.JID.parse" printMethod="uk.org.retep.xmpp.JID.print" />

            </baseType>

        </property>

    </bindings>

</bindings>


Here we define the attributes we want to change using an XPath expression and then the object we want to bind to that attribute. We also provide two methods to parse the attribute from a String to the object and to print it (from the object to a String). In this case those two methods are provided by the JID class itself but they don’t have to be.


Implementing the parse and print methods


The main things to watch out with the parse and print methods is that they have to be public static and they must handle null values. If the attribute is not present or should be a default value then they will be passed nulls:


From JID.java (abridged):


    public static JID parse( final String jid )

    {

        return jid == null ? null : new JID( jid );

    }


    public static String print( final JID jid )

    {

        return jid == null ? null : jid.toString();

    }


Back to the currency issue


Now with the currency issue which initially started off this rambling, there’s one more complication. In the specific DB the currency values are not actually stored as floats but in a custom SQL Type which I’ll call Money to protect the innocent. On the Java side there’s a similar object which uses a BigDecimal for the storage but also handles things like null’s etc. Anyhow in this case all that is required is to add a parse and print method into that class and add the equivalent bindings to the xjb file.


References

  1. Round and Round on the Daily WTF 
  2. Customising JAXB Bindings on sun.com
  3. jabber-client.xsd on xmpp.org