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

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