Monday, 15 August 2011

Hazelcast, Distributed Data Grid


Being on the threshold of high computing decade, there is a growing demand for ultra fast computing and data access. Until recently it has been quite a tough task to accomplish distributed messaging and data processing solutions, particularly requiring C/C++ interactions over JNI for java applications.

Luckily java platform has been fortified for parallel computing after jdk 1.5 platform release which includes a new concurrency package and improved util.collections. Probably these new features and technology advancements, multi core processors, high speed networks, like InfiniBand, made possible developing java-native parallel computing and data grid solutions.

Hazelcast is one of the data grid innovations promoting itself as “open source clustering and highly scalable data distribution platform for Java” amongst these latest java platform enhancements.

Using Hazelcast is quite easy as it’s a single deployable jar and does not include any external dependency. It scales linearly as the number of nodes increases on the grid. Hazelcast can fit the following scenarios perfectly.
  • Share data/state among many servers (e.g. web session sharing)
  • Cache your data (distributed cache)
  • Cluster your application
  • Provide secure communication among servers
  • Partition your in-memory data
  • Distribute workload onto many servers
  • Take advantage of parallel processing
  • Provide fail-safe data management

There is a demo application presenting Hazelcast’s scalability on a 50-node grid processing Mozilla crash reports.

Wednesday, 10 August 2011

jaxws-maven-plugin

I like maven as a build management tool. It provides a predefined and flexible folder structure, a dependency management mechanism enabling using versioned dependencies, plugins, project organization as modules and profiles.
All these things nowadays are considered quite common for a java project, probably nobody wants to revert back to a manual build system.
Maven is so popular that there are hundreds of plugins of it, from unit test execution to stub/proxy generation. Having a huge availability of plugins may cause taking risk of unfound bugs in these plugins and having delayed delivery times. Generally plugins are contributed by open source committers so there isn’t any dedicated resource for most plugins to fix bugs found in a plugin.
One of these popular plugins is jaxws-maven-plugin generally used for java proxy creation from a wsdl file or vice-versa. It’s developed by java.net and including some bugs like all other plugins.
I was thinking of jaxws-maven-plugin as a high quality tool, at least expecting some dedicated support from java.net and Sun/Oracle guys. Apparently I was wrong as this tool includes a bug not fixed more than two years!.
The bug can be observed while trying to create proxy classes from two or more wsdl files by creating two execution sections, see below, inside the plugin configuration.
Second.wsdl file is not processed by the below plugin configuration, might cause us to spend time wondering why the second one is not processed.
Thanks to another guy for pointing out this issue and finding the actual underlying bug, I didn’t spend much time for a workaround.
But the main issue with that particular plugin is that this bug was reported in Jan’ 09 and it hasn't being fixed so far!.


Default jaxws configuration


<plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>jaxws-maven-plugin</artifactId>
 <version>1.10</version>
 <executions>
  <execution>
   <id>execution-one</id>
   <configuration>
    <wsdlDirectory>src/main/resources</wsdlDirectory>
    <wsdlFiles>
     <wsdllFile>First.wsdl</wsdllFile>
    </wsdlFiles>
    <packageName>tr.asahin.first.webservice</packageName>
    <keep>true</keep>
   </configuration>
   <goals>
    <goal>wsimport</goal>
   </goals>
  </execution>
  <execution>
   <id>execution-twot</id>
   <phase>generate-sources</phase>
   <configuration>
    <wsdlDirectory>src/main/resources</wsdlDirectory>
    <wsdlFiles>
     <wsdllFile>Second.wsdl</wsdllFile>
    </wsdlFiles>
    <packageName>tr.asahin.second.webservice</packageName>
    <keep>true</keep>
    <extension>true</extension>
   </configuration>
   <goals>
    <goal>wsimport</goal>
   </goals>
  </execution>
 </executions>
</plugin>



Applying a workaround

<plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>jaxws-maven-plugin</artifactId>
 <version>1.10</version>
 <executions>
  <execution>
   <id>execution-one</id>
   <configuration>
    <wsdlDirectory>src/main/resources</wsdlDirectory>
    <wsdlFiles>
     <wsdllFile>First.wsdl</wsdllFile>
    </wsdlFiles>
    <packageName>tr.asahin.first.webservice</packageName>
    <keep>true</keep>
    <staleFile>${project.build.directory}/jaxws/stale/first.txt</staleFile>
   </configuration>
   <goals>
    <goal>wsimport</goal>
   </goals>
  </execution>
  <execution>
   <id>execution-twot</id>
   <phase>generate-sources</phase>
   <configuration>
    <wsdlDirectory>src/main/resources</wsdlDirectory>
    <wsdlFiles>
     <wsdllFile>Second.wsdl</wsdllFile>
    </wsdlFiles>
    <packageName>tr.asahin.second.webservice</packageName>
    <keep>true</keep>
    <staleFile>${project.build.directory}/jaxws/stale/second.txt</staleFile>
    <extension>true</extension>
   </configuration>
   <goals>
    <goal>wsimport</goal>
   </goals>
  </execution>
 </executions>
</plugin>

Wednesday, 3 August 2011

Java Thread Deadlocks

Generally deadlocks occur when two threads try to lock an object held by the counterpart thread.
Java has some internal locking mechanism, one of them is using synchronized keyword. When a thread enters into synchronized method, thread acquires object's lock, and releases the lock after leaving the synchronized method.
I think the deadlock issue in java can be visualized as below to understand better the issue.

Thread Deadlock















Here is a junit code for generating  a java deadlock.
import junit.framework.Assert;
import org.junit.Test;

/**
 * @author asahin
 */
public class ThreadTests {

    @Test
    public void testDeadLock() throws InterruptedException {

        final Writer writer = new Writer();
        final Reader reader = new Reader();
        writer.setReader(reader);
        reader.setWriter(writer);

        Thread readerThread = new Thread(new Runnable() {
            public void run() {
                try {
                    reader.readerOperation();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread writerThread = new Thread(new Runnable() {
            public void run() {
                try {
                    writer.writerOperation();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        readerThread.start();
        writerThread.start();

        readerThread.join(5000);
        writerThread.join(5000);
        Assert.assertTrue("Expecting readerThread alive", readerThread.isAlive());
        Assert.assertTrue("Expecting writerThread alive", writerThread.isAlive());
    }

    public static class Reader {
        public void setWriter(Writer writer) {
            this.writer = writer;
        }

        private Writer writer;

        public synchronized void readerOperation() throws InterruptedException {
            //rest little bit
            Thread.sleep(1000);
            System.out.println("Thread using Reader is:" + Thread.currentThread());
            writer.writerOperation();
        }

    }

    public static class Writer {
        private Reader reader;

        public void setReader(Reader reader) {
            this.reader = reader;
        }

        public synchronized void writerOperation() throws InterruptedException {
            //rest little bit
            Thread.sleep(1000);
            System.out.println("Thread using Writer is:" + Thread.currentThread());
            reader.readerOperation();
        }
    }

}

Verification of deadlock

Thread[readerThread,5,main] inside Reader
Thread[writerThread,5,main] inside Writer
2011-08-03 13:28:26
Full thread dump Java HotSpot(TM) Client VM (19.1-b02 mixed mode, sharing):
....
....
....
Found one Java-level deadlock:
=============================
"writerThread":
  waiting to lock monitor 0x01b1d99c (object 0x23d51640, a tr.asahin.ThreadTests$Reader),
  which is held by "readerThread"
"readerThread":
  waiting to lock monitor 0x01b18cc4 (object 0x23d4f960, a tr.asahin.ThreadTests$Writer),
  which is held by "writerThread"

Java stack information for the threads listed above:
===================================================
"writerThread":
 at tr.asahin.ThreadTests$Reader.readerOperation(ThreadTests.java:57)
 - waiting to lock <0x23d51640> (a tr.asahin.ThreadTests$Reader)
 at tr.asahin.ThreadTests$Writer.writerOperation(ThreadTests.java:75)
 - locked <0x23d4f960> (a tr.asahin.ThreadTests$Writer)
 at tr.asahin.ThreadTests$2.run(ThreadTests.java:32)
 at java.lang.Thread.run(Thread.java:662)
"readerThread":
 at tr.asahin.ThreadTests$Writer.writerOperation(ThreadTests.java:73)
 - waiting to lock <0x23d4f960> (a tr.asahin.ThreadTests$Writer)
 at tr.asahin.ThreadTests$Reader.readerOperation(ThreadTests.java:59)
 - locked <0x23d51640> (a tr.asahin.ThreadTests$Reader)
 at tr.asahin.ThreadTests$1.run(ThreadTests.java:22)
 at java.lang.Thread.run(Thread.java:662)

Found 1 deadlock.