Thursday, 31 March 2011

Portable Global JNDI Names and Maven

With the advent of the EJB 3.1 specification, the JNDI names for session beans have become portable via the java:global namespace.

As described on the Glassfish EJB FAQ page (http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#What_is_the_syntax_for_portable_global_) the syntax for the global namespace is:

java:global[/<app-name>]/<module-name>/<bean-name>

where the app-name is the ear name (if the app is deployed as an ear), the module-name the ejb jar or war name and the bean-name the session bean name. Note that names are unqualified and minus the extension.

Given the syntax an example of using the portable JNDI name using the @EJB annotation would be:

@EJB(lookup=
    "java:global/customer-ear/customer-1-0-0/CustomerServiceBean")

The JNDI name may now be portable but the above code would not be reusable if the customer jar name changed. It is quite often the case that jars will have versions in their name eg customer-1-0-0.jar and you would not want to change your code everytime there was a new release of the customer jar so you need to change the module name in the lookup.

One option would be to rename the jar when building the ear file so the module name defaults to the jar name. To do this in Maven would be to explicitly add the ejbModule to the ear plugin as shown below. The name of the jar is what is specified in the bundleFileName tag.

    <plugin>
        <artifactId>maven-ear-plugin</artifactId>
        <version>2.4</version>
        <configuration>
            <generateApplicationXml>true</generateApplicationXml>
            <archive>
                <manifest>
                    <addClasspath>true</addClasspath>
                </manifest>
            </archive>
            <version>6</version>
            <defaultLibBundleDir>lib</defaultLibBundleDir>
            <earSourceDirectory>resources</earSourceDirectory>
            <modules>
                <ejbModule>
                    <groupId>com.mybank.customer</groupId>
                    <artifactId>customer-server</artifactId>
                    <bundleFileName>customer.jar</bundleFileName>
                </ejbModule>
            </modules>
        </configuration>
    </plugin>


The lookup would then be as below:

@EJB(lookup=
    "java:global/customer-ear/customer/CustomerServiceBean")

This means the code containing the injection point doesn't have to change with the names of the jars.

Java Collections and Threading

In the java.util.concurrent package, there exist several collection classes which aid the development of thread safe code. Below is a brief overview of the five most useful classes and a comparison of them with the some collection that exist in the java.util package.


ConcurrentHashMap<K,V>

java.util.HashMap is a collection which holds key value pairs but it is not synchronised. If multiple threads are accessing such a collection, the keys and values being put into the collection may not be visible to those threads calling get. A solution would be to create a synchronised version by calling the static method Collections.synchronizedMap() but this would 'lock' all operations on the Map.

Another solution would be to use ConcurrentHashMap<K,V>. The idea behind this class is that only the bucket that holds the data being accessed is 'locked'. This allows (more often than not) the get operation to work without blocking. Note that using an iterator obtained from the ConcurrentHashMap will not reflect map modifications since getting the iterator. Therefore the iterator will not throw ConcurrentModificationException.


ConcurrentSkipListMap<K,V>

java.util.concurrent.ConcurrentSkipListMap offers similar functionality to the above class but it maintains a sorted order (either the natural order or the order based on using a Comparator.) It also provides methods like ceilingKey, lowerEntry and tailMap. Because of the ordering, insertion can be slower than that of a ConcurrentHashMap but iterating over the collection would be faster.


ConcurrentSkipListSet<E>

Similar to the above but is a NavigableSet.


CopyOnWriteArrayList<E>

java.util.ArrayList is a collection which holds a resizable list of entries but it is not synchronised. As with ConcurrentHashMap, a solution would be to create a synchronised version by calling the static method Collections.synchronizedList() but this would 'lock' all operations on the List. Another solution would be to use CopyOnWriteArrayList<E> and this is best suited to lists where reads are frequent and writes are infrequent. It works by making a change to a copy of the list and then replacing the existing list with the modified copy..


CopyOnWriteArraySet<E>

Similar to the above but is a Set.

Friday, 25 March 2011

Thread-safe and lock free variables

The java.util.concurrent.atomic package contains classes which aim to ease concurrency concerns in multithreaded applications. They offer better performance than using synchronisation because its operations on fields do not require locking.

The classes AtomicBoolean, AtomicInteger, AtomicLong and AtomicReference enable the primitives boolean, int, long and an object reference to be atomically updated. They all provide utility methods like compareAndSet which takes an expected value and the update value and returns false if the expected value doesn't equal (==) the current value. The AtomicInteger and AtomicLong classes also provide atomic pre and post decrement/increment methods like getAndIncrement or incrementAndGet.

An example use of one of the 'scalar' atomic classes is shown below:

public class IdentifierGenerator {

    private AtomicLong seed = new AtomicLong(0);

    public long getNextIdentifier() {
        return seed.getAndIncrement();
    }

} 


The int and long primitives, and also object references can be held in arrays where the elements are atomically updated namely AtomicIntegerArray, AtomicLongArray and AtomicReferenceArray.

There also exists field updater classes namely AtomicIntegerFieldUpdater, AtomicLongFieldUpdater and AtomicReferenceFieldUpdater. With these classes you can still use the methods on the class but use the updater class to manage the field that requires atomic access via methods like compareAndSet. Note that because of this, atomcity isn't guaranteed.

These are abstract classes and the below (contrived!) example shows how an instance would be created:

    public void setBalance(Customer customer, int exisitngBalance, 
        int newBalance) {

        AtomicIntegerFieldUpdater<Customer> balanceAccessor 
            = AtomicIntegerFieldUpdater.newUpdater(
        Customer.class, "balance"); 
        balanceAccessor.compareAndSet(customer, exisitngBalance, newBalance);

    }

Thursday, 24 March 2011

Weak and Soft References and the Garbage Collector

Java uses the Garbage Collector to manage memory. It does this by freeing up memory no longer needed by the application ie memory used by objects that are not referenced anymore, in other words, objects that are ‘unreachable’.

Typically, objects are strongly referenced so they remain in memory until no longer reachable,

Customer customer = new Customer();

but there are certain scenarios where you’d want to keep references to objects and also allow them to be garbage collected if needs be eg when memory is at a premium. A solution to this problem is to use Reference Objects.

There are three concrete implementations of the java.lang.ref.Reference<T> class: WeakReference, SoftReference and PhantomReference.

Objects held only by a WeakReference are deemed to be weakly reachable and are therefore eligible for garbage collection. An example of creating a WeakReference is below:

WeakReference<Customer> weakCustomer = new
    WeakReference<Customer>(customer);

To obtain the customer object held by the weak reference, you would call weakCustomer.get(). This will always return the customer object unless the garbage collecter has deemed the object to be weakly reachable and therefore has freed it from memory. In that case, calling the get method will return null;

If you want to hold a collection of the objects that can be garbage collected, then you can use a WeakHashMap. This collection uses weak references as keys, so when the key becomes garbage collected, the entry for that key in the WeakHashMap gets removed. This collection class isn’t synchronized so use Collections.synchronizedMap for a synchronized version, but be beware that whether synchronized or not, the size of the Map may decrease over time as the garbage collector removes entries, so an iterator may return ConcurrentModificationException.

A SoftReference holds onto the object more strongly than a WeakReference and if memory is not a problem the garbage collector will not free up the memory used by objects held by a soft reference.

You can also create another type of reference to an object, a PhantomReference. Calling the get method on such a reference will always return null though thereby preventing you from ‘resurrecting’ the object.  It’s only real use is when you pass a ReferenceQueue into the PhantomReference constructor.

You can pass a ReferenceQueue into the constructor of all the Reference types. It enables you to keep track of objects which have been garbage collected. When the object’s finalize method is called, the object will be placed on the reference queue. This process is called ‘enqueuing’. You then know when it was removed from memory.

In the case of a PhantomReference, passing in a null ReferenceQueue would be a pointless exercise, rendering the creation of the PhantomReference useless.


Tuesday, 8 March 2011

Testing JPA Entities using DBUnit

DBUnit is a powerful testing tool that allows you to put your database into a known state in between tests. A common problem (and one of poor test design) is where a test changes the state of an object and this state affects the testing of objects in later tests. Each test should be independent and tests within a suite should be able to run in any order. This post will aim to describe the code needed to setup a database before each run of a JUnit test method.

The below class has three key methods:
  • initEntityManager() - this method is annotated with @BeforeClass so will only be called once for this test and called before any tests are run. The method will create an entity manager, get a connection to an instance of the in memory Java database HSQL and then populate it by reading in the flat xml database record structure that is contained in the file test-dataset.xml. For alternative dataset formats please visit http://www.dbunit.org/apidocs/org/dbunit/dataset/IDataSet.html
  • closeEntityManager() - this method is annotated with @AfterClass so will only be called once for this test and called after all the tests have been run. The method will close down the entity manager and the entity manager connection factory.
  • cleanDB() - this method is annotated with @Before and will be called before every test method call. The call to  DatabaseOperation.CLEAN_INSERT.execute will clean the database tables and insert the records from the dataset xml file. Database operations other than CLEAN_INSERT are described below:
            UPDATE        updates the database using the data in the dataset.
            INSERT         inserts the data in the dataset into the database.
            DELETE         deletes only the data in the dataset from the database.
            DELETE_ALL deletes all rows of tables present in the specified dataset.
            TRUNCATE   truncate tables listed in the dataset.
            REFRESH     refreshes the database using the data in the dataset.
            NONE           does what it says, nothing.

import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.ext.hsqldb.HsqldbDataTypeFactory;
import org.dbunit.operation.DatabaseOperation;
import org.hibernate.impl.SessionImpl;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.junit.Test;

public class JPATest {

    protected static EntityManagerFactory entityManagerFactory;
    protected static EntityManager entityManager;
    protected static IDatabaseConnection connection;
    protected static IDataSet dataset;

    @BeforeClass
    public static void initEntityManager() throws Exception {
        entityManagerFactory = Persistence.createEntityManagerFactory("PersistenceUnit");
        entityManager = entityManagerFactory.createEntityManager();
        connection = new DatabaseConnection(((SessionImpl)(entityManager.getDelegate())).connection());
        connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory());

        FlatXmlDataSetBuilder flatXmlDataSetBuilder = new FlatXmlDataSetBuilder();
        flatXmlDataSetBuilder.setColumnSensing(true);
        dataset = flatXmlDataSetBuilder.build(
        Thread.currentThread().getContextClassLoader().getResourceAsStream("test-dataset.xml"));
    }

    @AfterClass
    public static void closeEntityManager() {
        entityManager.close();
        entityManagerFactory.close();
    }

    @Before
    public void cleanDB() throws Exception {
        DatabaseOperation.CLEAN_INSERT.execute(connection, dataset);
    }

    @Test
    public void testAUsefulMethod() throws Exception {
        // .... test code
    }

}


An example structure of the dataset.xml is shown below:

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
    <customer id="1" surname="SURNAME" firstName="FIRSTNAME" middleName="MIDDLENAME" personalAccount="true"/>
    <customer id="2" surname="SURNAME" firstName="FIRSTNAME" personalAccount="true" balance="100000.00/>
</dataset>


One point of note is that when deleting database records using DBUnit the same rules apply as if you were using SQL. You will not be able to delete a record if its primary key is a foreign key on another table. An example in Flat XML for a Customer class that has many Addresses would be:

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
    <customer/>
    <address/>
    <customer_address/>
</dataset>


Finally, there are many useful methods on IDataSet and ITable interfaces. An example being to obtain the number of records of a particular table:

int customerRecordCount = dataset.getTable("Customer").getRowCount();

Monday, 7 March 2011

Useful JMS-related Glassfish and OpenMq commands

Below are a few Glassfish JMS admin commands and some useful OpenMQ commands (to query, purge and list) which can be be used in scripts to perform tasks as opposed to performing the same procedures via the Glassfish or OpenMQ admin consoles:


Glassfish JMS Commands

To clear previous JMS setup

asadmin delete-jms-resource <JMS_TOPIC_RESOURCE_NAME>
asadmin delete-jms-resource <JMS_TOPIC_CONNECTION_FACTORY_NAME>


To create the JMS Topic Connection factory

asadmin create-jms-resource --restype=javax.jms.TopicConnectionFactory --property transaction-support=LocalTransaction --description="JMS Topic Connection Factory." <JMS_TOPIC_CONNECTION_FACTORY_NAME>


To create the JMS Topic resource

asadmin create-jms-resource --restype=javax.jms.Topic --description="JMS Topic" <JMS_TOPIC_RESOURCE_NAME>


To list JMS resources

asadmin list-jms-resources


OpenMQ Commands

Query the JMS resources

imqcmd query bkr  -b <host>:<port> -passfile <password file> -u <user name>

Purge the Topic (or Queue)

imqcmd purge dst -f -passfile <password file> -n <topic name> -t t -b <host>:<port> -u <user name>

List the message rate and packet flow

imqcmd list dst -passfile <password file> -b <host>:<port> -u <user name>

An example output from the list command would be:

Listing all the destinations on the broker specified by:

-------------------------
Host         Primary Port
-------------------------
localhost    7676

-----------------------------------------------------------------------------------------------------------------
             Name                Type    State      Producers        Consumers                  Msgs             
                                                 Total  Wildcard  Total  Wildcard  Count  Remote  UnAck  Avg Size
-----------------------------------------------------------------------------------------------------------------
JMSTopic                         Topic  RUNNING  0      0         1      0         0      0       0      0.0
mq.sys.dmq                       Queue  RUNNING  0      -         0      -         171    0       0      5273.322

Thursday, 3 March 2011

Pessimistic and Optimistic Locking in JPA 2.0

A most welcome addition to JPA 2.0 was the introduction of pessimistic locking. This allows the entity manager (or query) to lock a database record thereby preventing other transactions from changing the same record. This will ensure data consistency but at a performance cost so for each entity you need to ask yourself what is the chance of contention?

Let's look at the two approaches in more detail:

Optimistic Locking

Optimistic locking is the preferred approach when modifying entities that are infrequently updated. Optimistic locking can be explicit as will be shown later or implicit by using a version attribute. A version attribute is an attribute which has been annotated with @Version. This attribute will then get incremented when the transaction commits. The below class shows an example of its usage:

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EntityManager;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.PersistenceContext;
import javax.persistence.Version;
 

@MappedSuperclass
public abstract class BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final int ID_LENGTH=36;

    @Id
    @Column(length = ID_LENGTH)
    private String id;
    @Version
    private int versionNumber;

    // etc ...

}
 
There are two optimistic lock modes:

  • OPTIMISTIC or READ - locks the entity when the transaction reads it for entities wit a version
  • OPTIMISTIC_FORCE_INCREMENT or WRITE - locks the entity when the transaction reads it for entities with a version and increments the version attribute

Pessimistic Locking

Pessimistic locking can be applied to all entities regardless of whether they have a version attribute or not.
 
There are three pessimistic lock modes:

  • PESSIMISTIC_READ - locks the entity when the transaction reads it and allows reads from other transactions
  • PESSIMISTIC_WRITE - locks the entity when the transaction updates it but does not allow reads, updates or deletes from other transactions
  • PESSIMISTIC_FORCE_INCREMENT - locks the entity when the transaction reads it and increments the version attribute (if present)

There are many different ways to implement a pessimistic or optimistic lock using the Entity Manager and Query interfaces as shown in the example classes below:

import java.io.Serializable;
import java.util.List;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;


@Named("customerManager")
@ApplicationScoped
public class CustomerManager implements Serializable {


    private static final long serialVersionUID = 1L;

    @PersistenceContext
    private EntityManager entityManager;


    public void setName(String id, String name) {

        Customer customer = 

            entityManager.find(Customer.class, id);
        entityManager.lock(customer,

            LockModeType.OPTIMISTIC_FORCE_INCREMENT);
        customer.setName(name);
    }


    public Customer findCustomer(String id) {

        return entityManager.find(Customer.class, id, 

            LockModeType.OPTIMISTIC);
    }


    public Customer 

        applyBankCharges(String id, Double charges) {
 
        Customer customer = 

            entityManager.find(Customer.class, id);
        customer.setBalance(customer.getBalance() - charges);
        if (customer.getBalance() < 0.0) {
            // overwrite changes and return the refreshed 

            // and locked object
            entityManager.refresh(customer, 

                LockModeType.PESSIMISTIC_WRITE);
        }
        return customer;
    }


    public List<Customer> 

        findCustomerByPartialName(String partialName) {
 
        Query query = entityManager.createQuery(
                "SELECT c FROM Customer c WHERE c.name" + 

                " LIKE :partialName").
                setParameter("partialName", partialName);
        query.setLockMode( 

            LockModeType.PESSIMISTIC_FORCE_INCREMENT);
        return query.getResultList();
    }
}



import javax.persistence.Entity;
import javax.persistence.LockModeType;
import javax.persistence.NamedQuery;


@Entity

@NamedQuery(name = "findByNameQuery",
    query = "SELECT c FROM Customer c WHERE c.name LIKE :name",
    lockMode = LockModeType.PESSIMISTIC_FORCE_INCREMENT)
public class Customer extends BaseEntity {


    private String name;

    private Double balance;

    public void setName(String name) {

        this.name = name;
    }
    public Double getBalance() {

        return this.balance;
    }
    public void setBalance(Double balance) {

        this.balance = balance;
    }
}

 

Finally, a word on exceptions. If a PessimisticLockException or an OptimisticLockException are thrown then the transaction is rolled back as they are both RuntimeExceptions.