Wednesday, August 28, 2013

Json conversion: Convert one of the fields of the object as binary data

Json conversion: Convert one of the fields of the object as binary data

Problem statement: I had an object that I wanted to convert to JSON. However, one of the fields of this object was a serializable-blob and hence I wanted to save it in binary/byte-array format instead of String format.

Solution:
1.     Write a custom JsonSerializer and JsonDeserializer as shown below
2.     Annotate the getter/setter of the blob-field with this custom serializer/deserializer respectively.

Object:
public class TestObject {
      private String name = null;
      private MyBlob data = null;
      public TestObject() {
            super();
      }
      @JsonSerialize(using=ByteArraySerializer.class)
      public MyBlob getData() {
            return data;
      }
      @JsonDeserialize(as=MyBlob.class, using=ByteArrayDeserializer.class)
      public void setData(MyBlob data) {
            this.data = data;
      }
      public String getName() {
            return name;
      }
      public void setName(String name) {
            this.name = name;
      }
}

JsonSerializer:
//(You can find out some other object-serializer (or write your own) to avoid dependency over Cassandra-code)
import me.prettyprint.cassandra.serializers.ObjectSerializer;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;

public class ByteArraySerializer extends JsonSerializer<Object> {
                @Override
                public void serialize(Object value, JsonGenerator jgen,
                                                SerializerProvider provider) throws IOException,
                                                JsonProcessingException {
                                byte[] bytes = ObjectSerializer.get().toBytes(value);
                                jgen.writeBinary(bytes);
                }
}

JsonDeserializer:
import java.io.IOException;
//(You can find out some other object-deserializer (or write your own) to avoid dependency over Cassandra-code)
import me.prettyprint.cassandra.serializers.ObjectSerializer;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;

public class ByteArrayDeserializer extends JsonDeserializer<Object> {
                @Override
                public Object deserialize(JsonParser jp, DeserializationContext ctxt)
                                                throws IOException, JsonProcessingException {
                                byte[] bytes = jp.getBinaryValue();
                                Object obj = ObjectSerializer.get().fromBytes(bytes);
                                return obj;
                }
}

-          Sarang Anajwala

Wednesday, June 26, 2013

maven dependency source download

Commands to download source/javadocs jars for maven dependencies:

  • mvn dependency:sources OR mvn dependency:resolve -Dclassifier=sources
  • mvn dependency:resolve -Dclassifier=javadoc

Regards,
Sarang

Wednesday, February 13, 2013

Install GIT from source

Important when you want to install latest version of git on your machine. (Yum repo may not contain latest version)

Following are the steps to install GIT from source:

  1. Install dependencies required by GIT:

$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel

2.      Download tar from http://git-scm.com/download (or http://code.google.com/p/git-core/downloads/list)

3.      Then, Compile and Install:

$ tar -zxf git-<version>.tar.gz

$ cd git-<version>

$ make prefix=/usr/local all

$ sudo make prefix=/usr/local install

-Sarang

Tuesday, February 12, 2013

Use CountDownLatch as a CyclicBarrier

Following is a program to use CountDownLatch as a CyclicBarrier: (However, unlike CyclicBarrier, CountDownLatch cannot be restarted!) Just to understand how/if CountDownLatch can be used instead of CyclicBarrier.

public class CountDownLatchTry {
      private static CountDownLatch latch = new CountDownLatch(2);

      /**
      * @param args
      */
      public static void main(String[] args) {
            // TODO Auto-generated method stub
            Runnable r1 = new Runnable() {
                  public void run() {
                        System.out.println("T1: Before countDown()");
                        latch.countDown();
                        System.out.println("T1: After countDown()... sleeping");
                        try {
                              Thread.sleep(2000);
                        } catch (InterruptedException e1) {
                              // TODO Auto-generated catch block
                              e1.printStackTrace();
                        }
                        try {
                              latch.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T1: After await()");
                  }
            };
           
            Runnable r2 = new Runnable() {
                  public void run() {
                        System.out.println("T2: Before countDown()");
                        latch.countDown();
                        System.out.println("T2: After countDown()... sleeping");
                        try {
                              Thread.sleep(2000);
                        } catch (InterruptedException e1) {
                              // TODO Auto-generated catch block
                              e1.printStackTrace();
                        }
                        try {
                              latch.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T2: After await()");
                  }
            };

            Thread t1 = new Thread(r1, "T1");
            Thread t2 = new Thread(r2, "T2");
           
            t1.start();
            t2.start();
            System.out.println("Done!");
      }
}

Corresponding CyclicBarrier example:

public class CyclicBarrierTry {

      private static CyclicBarrier cb = new CyclicBarrier(2);
      /**
      * @param args
      */
      public static void main(String[] args) {
            // TODO Auto-generated method stub
           
            Runnable r1 = new Runnable() {
                  public void run() {
                        System.out.println("T1: Before await()");
                        try {
                              cb.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        } catch (BrokenBarrierException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T1: After await()");
                  }
            };
           
            Runnable r2 = new Runnable() {
                  public void run() {
                        System.out.println("T2: Before await()");
                        try {
                              cb.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        } catch (BrokenBarrierException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T2: After await()");
                  }
            };

            Thread t1 = new Thread(r1, "T1");
            Thread t2 = new Thread(r2, "T2");
           
            t1.start();
            t2.start();
            System.out.println("Done!");
      }

}

Saturday, February 9, 2013

Potential perf issues with String.substring()

This post is relevant for Oracle’s java implementation of 1.6!

Following is the implementation of substring method in String class:

    public String substring(int beginIndex, int endIndex) {
      if (beginIndex < 0) {
          throw new StringIndexOutOfBoundsException(beginIndex);
      }
      if (endIndex > count) {
          throw new StringIndexOutOfBoundsException(endIndex);
      }
      if (beginIndex > endIndex) {
          throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
      }
      return ((beginIndex == 0) && (endIndex == count)) ? this :
          new String(offset + beginIndex, endIndex - beginIndex, value);
    }

Now, if you take a look at the highlighted part of the code, it says a new String is created with same char sequence (‘value’), but with different offset!
Let’s take a scenario where we have a huge string, say of 100MB and we take a substring containing last 100 chars of that string.

String s100MB = <100MB String>; //memory occupied is 100MB
String substring = s100MB.subString(s100MB.length() – 100); //does not occupy any additional memory for the chars of substring as it uses the same char array as the parent string
s100MB = null; //‘substring’ still occupies 100MB of memory where as what it requires is only 200k (for 100 chars)

Now, in real world this may not be a very serious issue as GC is not as instantaneous but cases where ‘substring’ hangs around in memory for very long time – this can be unnecessary wastage of memory! (Worse…. think of the original string being 1GB instead of 100MB!)

<![if !supportLists]>-          <![endif]>Sarang



Thursday, January 31, 2013

final Collection in java

An interesting aspect about final Collection that many java developers may not be familiar with is that making a collection final means only the reference cannot be changed but you can add, remove or change an object inside collection.

 

Example:

            private final List<String> names = new ArrayList<String>();

            names.add("Name1"); //Allowed

            names.add("Name2"); //Allowed

                       

            names = new ArrayList<String>(); //Error