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

 

Friday, December 28, 2012

Setup yum repository from a linux iso shared on remote windows machine

1. Mount remote windows share on linux system

In general, a useful stuff – specially when important software-installers are stored on a windows share. It can be useful to mount the windows share on your linux system to use it efficiently.

Following are the steps:
  • Login to Linux as root user
  • > mkdir /mtn/winshare 
  • > mount -t cifs //<windows-machine-IP-addr>/<folder-path/ -o username=<user>,password=<pw> /mnt/winshare (For RHEL > 4)
  • > mount -t smbfs //<windows-machine-IP-addr>/<folder-path/ -o username=<user>,password=<pw> /mnt/winshare (For RHEL < 4)

2. Extract Files from iso image and create yum repository

  • > mkdir -p /mnt/iso/{1,2,3}
  • > mount -o loop /mnt/winshare/disk.iso /mnt/iso/1
  • > rpm -ivh  /mnt/iso/1/Packages/<createrepo-package-name>.rpm
  • > cd /mnt/iso
  • > createrepo .
  • > yum clean all

3. Create yum repository configuration file

  • > vi /etc/yum.repos.d/iso.repo
  • Place following text in iso.repo
           [iso] 
           name=My ISO Repo
           baseurl=file:///mnt/iso
           enabled=1
           gpgcheck=0 

Now you should be able to install any package from iso using yum.

- Sarang Anajwala

Monday, December 24, 2012

Debug class-not-found exception

Print ClassNotFoundException

A simple problem that I have found many people struggling with – how to print class-path. Following is the line that can be used to print classpath.

Arrays.toString((((URLClassLoader) Test.class.getClassLoader().getURLs()));

This code returns an array list of all jars and directories on the classpath of the classloader.

-          Sarang Anajwala

 

Friday, December 14, 2012

End of Public Updates for Java SE 6

A quick update on future of Java 6.

From oracle blog -
“The last publicly available release of Oracle JDK 6 is to be released in February, 2013. This means that after 19 February 2013, all new security updates, patches and fixes for Java SE 6 and Java SE 5 will only be available through My Oracle Support and will thus require a commercial license with Oracle.“


Presents a case for upgrade to Java 7!

- Sarang Anajwala