Saturday, September 6, 2014

Type Erasure and Bridge Methods in Generics

"Generics programming is about abstracting and classifying algorithms and data structures. It's goal is the incremental construction of systematic catalogs of useful, efficient and abstract algorithms and data structures"

-Alexander Stepanov

Generics programming concepts are nothing new. And it is not something Java introduced to the world (Ada, Eiffel and C++ supported generics even before Java did). In 1988 David Musser and Alexander Stepanov introduced and defined this concept.

Java introduced Generics in 2004 (Java 5) and implement it as type erasure. Type erasure consist of following steps:

  • Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
  • Insert type casts if necessary to preserve type safety.
  • Generate bridge methods to preserve polymorphism in extended generic types.
You can conclude from this, that generics in java are purely compile time feature. Because of this, generics in Java incur no run-time overhead and it is important to point this out. I suspect they implement Generics as compile time correctness because they were focused on backward compatibility.

Here is simple demonstration of replacing generics type with their bounds. In this case bound is Object. I know there are better ways of copy array to collection (like Collections.addAll method), but this is only for demonstration purpose, so I will stick with it. ;)
public static <T> void array2Coll(T[] a, Collection<T> c) {
  for (T o : a) {
    c.add(o);
  }
}
After type erasure code will look like this:
public static void array2Coll(Object[] a, Collection c) {
  for (Object o : a) {
    c.add(o);
  }
}
As you can see, generics type has been replaced with Object type (it's upper bound). If their bound would be something else (for example <T> extends Comparable), then generics would be replaced by Comparable.

Sometimes compiler create a synthetic method, called a bridge method, as part of the type erasure process. Next examples will explain why and when compiler create this methods.
public class Node<T> {
  private T data;

  public Node(T data) { this.data = data; }
    public void setData(T data) {
      System.out.println("Node.setData");
      this.data = data;
    }
  }

public class MyNode extends Node<Integer> {
  public MyNode(Integer data) { 
    super(data); 
  }

  public void setData(Integer data) {
    System.out.println("MyNode.setData");
    super.setData(data);
  }
}
After type erasure compiler will create one synthetic bridge method for second class:
public class Node {

  private Object data;

  public void setData(Object data) {
    System.out.println("Node.setData");
    this.data = data;
  }
}

public class MyNode extends Node {

  public MyNode(Integer data) { 
    super(data); 
  }

  // synthetic bridge method
  public void setData(Object data) {
    setData((Integer) data);
  }

  public void setData(Integer data) {
    System.out.println(Integer data);
    super.setData(data);
  }
}
In this example bridge method was created because MyNode class was missing setData method for Object parameter. Without this method we wouldn't have proper polymorphic behavior and next example would throw ClassCastException.
  MyNode mn = new MyNode(5);
  Node n = mn;  
  n.setData("Hello"); //throws ClassCastException

Friday, June 13, 2014

groovy Closures memoization

Memoization (if you don't know already) is technique that groovy closure can use and remember the result of its invocation for a specific set of inputs. It to this by internally caching the result.
This is quite common technique to speed up recursive algorithms (Usually you will use maps for this).

Groovy support memoization through it's .memoize() method.
The first invocation is doing actual work and and subsequent invocation is pulling result from cache.
If you run this program, you will see something like this as output:


Test without memoization:
Adding 1 and 3 took 1540 msec with result 4.
Adding 1 and 3 took 1500 msec with result 4.
Adding 1 and 3 took 1501 msec with result 4.
Adding 1 and 3 took 1500 msec with result 4.
Adding 1 and 3 took 1500 msec with result 4.
Test with memoization:
Adding 1 and 3 took 1500 msec with result 4.
Adding 1 and 3 took 0 msec with result 4.
Adding 1 and 3 took 0 msec with result 4.
Adding 1 and 3 took 1 msec with result 4.
Adding 1 and 3 took 0 msec with result 4.


As you can see there is quite a difference between two test. It goes without saying that your closures should return same result for same parameters.
addTwoNumbers = {int a, b ->
    //simulate some lengthy calculation
    Thread.sleep(1500)
    a + b
}
println("Test without memoization:")
def testItWithoutMemoization(a, b) {
    long start = System.currentTimeMillis()
    long result = addTwoNumbers(a, b)

    println("Adding $a and $b took " +
            "${System.currentTimeMillis() - start} " +
            "msec with result $result.")
}

testItWithoutMemoization(1, 3)
testItWithoutMemoization(1, 3)
testItWithoutMemoization(1, 3)
testItWithoutMemoization(1, 3)
testItWithoutMemoization(1, 3)

addTwoNumbersWithMem = addTwoNumbers.memoize()

println("Test with memoization:")
def testItWithMemoization(a, b) {
    long start = System.currentTimeMillis()
    long result = addTwoNumbersWithMem(a, b)

    println("Adding $a and $b took " +
            "${System.currentTimeMillis() - start} " +
            "msec with result $result.")
}

testItWithMemoization(1, 3)
testItWithMemoization(1, 3)
testItWithMemoization(1, 3)
testItWithMemoization(1, 3)
testItWithMemoization(1, 3)

Tuesday, June 10, 2014

Grails - dataBind in Service Layer

Here is quick tip how you can use dataBind grails command outside of grails controller.
import org.codehaus.groovy.grails.web.metaclass.BindDynamicMethod

class DataBinder {

    private static BindDynamicMethod bindDynamicMethod = new BindDynamicMethod()

    /**
     * make the controller bindData method statically available, e.g. for service layer use
     * implemented as closure to allow static import emulating controller layer bindData usage 1:1
     */
    static Closure bindData = { Object[] args ->
        bindDynamicMethod.invoke(args ? args[0] : null, BindDynamicMethod.METHOD_SIGNATURE, args)
    }
}

//usage
class TestBind {
    public void intermediateNotification(Map params) {
        Test test = new Test()
        DataBinder.bindData(test, params)
        test.save()    
    }
}

Friday, June 6, 2014

Android remote logger - send logs to server

I want to show you simple implementation of remote logger for Android. This can be used for sendings logs from your app to server (backend).

public final class Logger {

    public static final String DISPATCHER_REPORT_URI = App.getDispatcherUri() + "/vidLog/report";

    private static final int CAPACITY = 10;
    private static final String APPLICATION_LOG_TAG = "YourApp";
    private static List<String> logs = new Vector<String>(CAPACITY);
   
    public synchronized static void r(String msg) {

        if (logs.size() + 1 > CAPACITY) {
            flushRemote();
        }

        logs.add(buildLog(msg));
    }

    public synchronized static void flushRemote() {
        final String formattedLogs = collectAndFormatLogs();

        Runnable sendLogs = new Runnable() {
            @Override
            public void run() {
                HttpHelper.doPostRequest(YOUR_SERVER_URI, "APP_LOG", formattedLogs);
            }
        };
        new Thread(sendLogs).start();

        logs.clear();
    }

    private static String collectAndFormatLogs() {
        String logsFormatted = "";
        for (String log : logs) {
            logsFormatted += log + "\n";
        }
        return logsFormatted;
    }

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");

    private static String buildLog(String msg) {
        return sdf.format(new Date()) +
                " REMOTE " +
                APPLICATION_LOG_TAG + " " +
                msg;
    }

}
//Usage
Logger.r("first message");
Logger.r("second message");

//When CAPACITY is exceeded logs will be flushed automatically.
Logger.flushRemote();

Save context in Android Application class

If you are tired of always passing application context through your classes in Android, you can try something like this. In this way you will store your application context in Application class as static field and you can access this field from anywhere.
public class App extends Application {

  private static Context context;

  @Override
  public void onCreate() {
   super.onCreate();
   context = this;

   /* other stuf */
  }

  public static Context getContext() {
   return context;
  }

}

Wednesday, May 28, 2014

Busy developer Android Google Analytics guide

I was working on integrating Google Analytics (GA) into existing Android application. If you want to track your activities in GA, you need to put stop and start reports in your activities onStart and onStop lifecycle events. You need to do this in _every_ activity.

I don't like this approach, it doesn't feel right (I hate copy paste code in any form).

Luckily there is another approach.

You can implement ActivityLifecycleCallbacks and then you can override onActivityStopped and onActivityStarted methods and by doing so, you will put start and stop method in every activity. Here is how to do it:

public class CustomActivityLifeCycleListener implements Application.ActivityLifecycleCallbacks {

    @Override
    public void onActivityStopped(Activity activity) {
        GoogleAnalytics.getInstance(activity).reportActivityStop(activity);
    }

    @Override
    public void onActivityStarted(Activity activity) {
        GoogleAnalytics.getInstance(activity).reportActivityStart(activity);
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

    }

    @Override
    public void onActivityResumed(Activity activity) {

    }

    @Override
    public void onActivityPaused(Activity activity) {

    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {

    }

}
You need to register this LifeCycle listener in you application class (by extending Application) and initialize your GA tracker.
public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new CustomActivityLifeCycleListener());
        //R.xml.global_tracker is my tracker configuration, you can also initialize tracker
        //by passing your GA property in String constructor.
        GoogleAnalytics.getInstance(getContext()).newTracker(R.xml.global_tracker);
    }

}
You can also save this tracker (instance) in your app class because you will need tracker if you want to send events or whatever.

One more thing. You need to register your tracker resource in your AndroidManifest or else your GA configuration will not work. It took me something like 3h until I figure this out!

Also you need to update yours Google Play Service lib and install Google Analytics libs in your Android SDK tool.

Monday, May 5, 2014

Java Consumer Producer example (without using Java BlockingQueue)

I found very interesting and nice blocking queue implementation.
Off course you can use Java BlockingQueue (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html) implementation,
but if you want to learn something new along the way why not implement it by yourself?

I left some original comments and add some of my own.
Enjoy!

public class BlockingQueueTest {
    private final BlockingQ bq = new BlockingQ();
    /**
     The Worker thread is not very robust.  If a RuntimeException
     occurse in the run method, the thread will stop.
     */
    private class Worker extends Thread {
        public Worker(String name) { super(name); start(); }
        public void run() {
            try {
                //This loop will continue to take next runnable task from queue or
                //will block on pop() method.
                while(!isInterrupted()) {
                    ((Runnable)bq.pop()).run();
                }
                //This will spit out the "poison pill". :)
            } catch(InterruptedException ex) {}
            System.out.println(getName() + " finished");
        }
    }
    public BlockingQueueTest() {
        // We create 10 threads as workers
        Thread[] workers = new Thread[10];
        for (int i=0; i < workers.length; i++)
            workers[i] = new Worker("Worker Thread " + i);

        // We then push 100 commands onto the queue
        for (int i=0; i<100; i++) {
            final String msg = "Task " + i + " completed";
            bq.push(new Runnable() {
                public void run() {
                    System.out.println(msg);
                    // Sleep a random amount of time, up to 1 second
                    try { Thread.sleep((long)(Math.random()*1000)); }
                    catch(InterruptedException ex) { }
                }
            });
        }

        // We then push one "poison pill" onto the queue for each
        // worker thread, which will only be processed once the other
        // tasks are completed.
        for (int i=0; i < workers.length; i++) {
            bq.push(new Runnable() {
                public void run() {
                    Thread.currentThread().interrupt();
                }
            });
        }

        // Lastly we join ourself to each of the Worker threads, so
        // that we only continue once all the worker threads are
        // finished.
        for (int i=0; i < workers.length; i++) {
            try {
                workers[i].join();
            } catch(InterruptedException ex) {}
        }
        System.out.println("BlockingQueueTest finished");
    }
    public static void main(String[] args) throws Exception{
        new BlockingQueueTest();
    }
}

class BlockingQ {
    /**
     It makes logical sense to use a linked list for a FIFO queue,
     although an ArrayList is usually more efficient for a short
     queue (on most VMs).
     */
    private final LinkedList queue = new LinkedList();
    /**
     This method pushes an object onto the end of the queue, and
     then notifies one of the waiting threads.
     */
    public void push(Object o) {
        synchronized(queue) {
            queue.add(o);
            //This will notify blocked thread (on queue.wait() bellow) to continue.
            queue.notify();
        }
    }
    /**
     The pop operation blocks until either an object is returned
     or the thread is interrupted, in which case it throws an
     InterruptedException.
     */
    public Object pop() throws InterruptedException {
        //Racing condition starts here.
        synchronized(queue) {
            //Thread will wait if queue is empty.
            while (queue.isEmpty()) {
                queue.wait();
            }
            return queue.removeFirst();
        }
    }
}
This implementation was taken from: http://www.javaspecialists.eu/archive/Issue016.html

Wednesday, March 12, 2014

Collection add elements in single line


Passing arrays instance arguments in single line of code is very useful. For example you can do something like this:
addNumbers(new int[] {1,2,3});
And it will work perfectly, but for collections you can't to that. However using anonymous inner classes with instance initialization we can get similar effect:
addNumbers(new ArrayList<Integer>(3) {{ add(1); add(2); add(3); }});
If we expand this code, it will be more clear how it works.
addNumbers(new ArrayList<Integer>(3) {//anonymous class
  //instance initialization block
  { 
    add(1); 
    add(2); 
    add(3); 
  }
});
Just for completeness here are addNumber methods:
private static int addNumbers(int[] numbers) {
    int result = 0;
    for (int number : numbers) {
        result += number;
    }
    return result;
}

private static Integer addNumbers(Collection<Integer> numbers) {
    Integer result = 0;
    for (Integer number : numbers) {
        result += number;
    }
    return result;
}

Create thread in Java (two ways)

There are two ways you can create new Thread in Java. First one is to implement Runnable. This is more common way of doing this, but if you look at the Thread's code, you will see that Thread only calls run() on Runnable object, so you basically don't need it here. Second way is not to use Runnable, but instead just implement Thread's run() ant that's it!

Using Runnable:
  Thread secondMethod = new Thread(new Runnable() {
      int index = 0;
      @Override
      public void run() {
          try {
              while (index < 100) {
                  int interval = (int) ((Math.random() * 500) + 500);
                  Thread.sleep(interval);
                  System.out.print("*");
                  index++;
              }
          } catch (InterruptedException exc) {
              //Empty
          }
      }
  });
Without Runnable:
Thread firstMethod = new Thread() {
    int index = 0;
    @Override
    public void run() {
        try {
            while (index < 100) {
                int interval = (int) ((Math.random() * 500) + 500);
                sleep(interval);
                System.out.print(".");
                index++;
            }
        } catch (InterruptedException exc) {
            //Empty
        }
    }
};

Saturday, January 18, 2014

Good book - Refactoring: Improving the Design of Existing Code


This book "Refactoring: Improving the Design of Existing Code" is really good reading for everyone that want to upgrade his coding mojo with some new tricks. This are basically "old" tricks, but it good to know them by name. :) Happy reading!