Friday, August 17, 2012

Performance comparison of Executor framework vs Fork/Join framework’s RecursiveTask feature in java or JDK7

I was testing new RecursiveTask feature of ForkJoin framework introduced in JDK7 or Java 1.7.

There are two types of ForkJoinTask specializations:
  1. Instances of RecursiveAction represent executions that do not yield a return value.
  2. In contrast, instances of RecursiveTask yield return values.
I have already posted an example of RecursiveAction in previous post. To know more about theoretic details and RecursiveAction sample code, you can visit the link: How to use Fork-Join Framework features in JDK7?


In this post I will do comparison of Executor Framework Vs ForkJoin framework's RecursiveTask feature. Following example fills primitive long array of size 100000000 with values from 0 to 10000000.

I use executor framework to calculate the sum of whole array  then I perform same logic using ForkJoin framework's RecursiveTask feature. To setup the example, I will first show the code which uses executor framework and its result then I will show ForkJoin framework's RecursiveTask feature implementing same logic and its result. Array sum logic in both samples was executed 10 times to get the average output and performance difference.

Update 1: Anonymous commenter advised to split the executor pool in even size (4 = number of available processors in my case) to maximize the through put. Advise well taken and updated blog as well. There is defiantly improvement in performance.

Executor framework code sample:

import static java.util.Arrays.asList;

import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ExecutorSum {
    Random random = new Random();

    // Fill array with its own index value
    public void fillArray(long[] array) {
        for (int i = 0; i < array.length; i++) {
            array[i] = i;
        }
    }

    public static void main(String[] args) throws InterruptedException,
            ExecutionException {
        ExecutorSum sum = new ExecutorSum();
        long[] array = new long[10_00_00_000];
        sum.fillArray(array);

        for (int i = 0; i < 10; i++) {
            int processors = Runtime.getRuntime().availableProcessors();
            ExecutorService executor = Executors.newFixedThreadPool(processors);
            List<Future<Long>> results;
            long start = System.currentTimeMillis();
          
            // array size/No. of processors
            int splitCount = array.length / processors;
          
            //Split pool size into even size for maximum through put
            results = executor.invokeAll(asList(new ArraySum(array, 0,
                    splitCount), new ArraySum(array, splitCount + 1,
                    splitCount * 2), new ArraySum(array, (splitCount * 2) + 1,
                    splitCount * 3), new ArraySum(array, (splitCount * 3) + 1,
                    array.length)

            ));

            executor.shutdown();

            // Calculating final result sum
            long count = 0;
            for (Future<Long> result : results) {
                count = count + result.get();
            }

            System.out.println("result: " + count);
            System.out.println("Sequential processing time: "
                    + (System.currentTimeMillis() - start) + " ms");
        }
    }
}

class ArraySum implements Callable<Long> {
    private final long from;
    private final long to;
    private long[] array;

    ArraySum(long[] array, long from, long to) {
        this.from = from;
        this.to = to;
        this.array = array;
    }

    @Override
    public Long call() throws Exception {
        long count = 0L;
        // Calculating sum of the given array range
        for (int i = (int) from; i < to; i++) {
            count = count + array[i];
        }

        return count;
    }
}

Output:

result: 4999999800000000
Sequential processing time: 113 ms
result: 4999999800000000
Sequential processing time: 108 ms
result: 4999999800000000
Sequential processing time: 113 ms
result: 4999999800000000
Sequential processing time: 124 ms
result: 4999999800000000
Sequential processing time: 122 ms
result: 4999999800000000
Sequential processing time: 107 ms
result: 4999999800000000
Sequential processing time: 123 ms
result: 4999999800000000
Sequential processing time: 134 ms
result: 4999999800000000
Sequential processing time: 122 ms
result: 4999999800000000
Sequential processing time: 109 ms

Fork/Join framework code sample:

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class ForkJoinSumTask {
   
    public void fillArray(long[] array) {
        for (int i=0; i<array.length; i++) {
            array[i] = i;
        }
    }

    public static void main(String[] args) {
        ForkJoinSumTask sum = new ForkJoinSumTask();
        long[] array = new long[10_00_00_000];
        sum.fillArray(array);
       
        System.out.println("Number of processors available: " + Runtime.getRuntime().availableProcessors());
       
        ForkJoinPool fjpool = new ForkJoinPool(32); //Default parallelism level = Runtime.getRuntime().availableProcessors()
       
        for (int i=0; i<10; i ++) {
            RecursiveSumTask task = new RecursiveSumTask(array, 0, array.length);
            long start = System.currentTimeMillis();
            System.out.println("Result: " + fjpool.invoke(task));
            System.out.println("Parallel processing time: "    + (System.currentTimeMillis() - start)+ " ms");
        }
       
        System.out.println("Number of steals: " + fjpool.getStealCount() + "\n");
    }
}

class RecursiveSumTask extends RecursiveTask<Long> {
    private static final long serialVersionUID = 1L;
    private final long from;
    private final long to;
    private long[] array;
    final int splitSize = 10_00_0000; //Some threshold size to spit the task

    RecursiveSumTask(long[] array, long from, long to) {
        this.from = from;
        this.to = to;
        this.array = array;
    }

    @Override
    protected Long compute() {
        long count = 0L;
        List<RecursiveTask<Long>> forks = new LinkedList<>();
       
        if ( to - from > splitSize) {
            // task is huge so divide in half
            long mid = (from + to) >>> 1;
           
            //Divided the given task into task1 and task2
            RecursiveSumTask task1 = new RecursiveSumTask(array, from, mid);
            forks.add(task1);
            task1.fork();
           
            RecursiveSumTask task2 = new RecursiveSumTask(array, mid, to);
            forks.add(task2);
            task2.fork();
        } else {
            //Calculating sum of the given array range
            for (int i = (int) from; i < to; i++) {
                count = count + array[i];
            }
        }
       
        //Waiting for the result
        for (RecursiveTask<Long> task : forks) {
            count = count + task.join();
        }
       
        return count;
    }
}

Output:

Number of processors available: 4
Result: 4999999950000000
Parallel processing time: 135 ms
Result: 4999999950000000
Parallel processing time: 123 ms
Result: 4999999950000000
Parallel processing time: 105 ms
Result: 4999999950000000
Parallel processing time: 115 ms
Result: 4999999950000000
Parallel processing time: 111 ms
Result: 4999999950000000
Parallel processing time: 114 ms
Result: 4999999950000000
Parallel processing time: 114 ms
Result: 4999999950000000
Parallel processing time: 109 ms
Result: 4999999950000000
Parallel processing time: 126 ms
Result: 4999999950000000
Parallel processing time: 128 ms
Number of steals: 301

Conclusion:

Both code samples calculate array sum 10 times to warmup HotSpot JVM and get average result. As you can see from both outputs, there is no visible improvement in the performance using RecursiveTask. May be my sum logic is small and not so complex. If the logic is more complex then performance difference will be lot more.

References:
  1. How to use Fork-Join Framework features in JDK7?  
  2. Fork and Join: Java Can Excel at Painless Parallel Programming 
  3. JDK 7 Adoption Guide

Thursday, August 16, 2012

How to use Fork/Join Framework's RecursiveAction feature in JDK7?

JDK 7 has new additions for supporting parallelism using ForkJoinPool executor that is dedicated to running instances implementing ForkJoinTask.

ForkJoinTask objects feature two specific methods:
  1. The fork() method allows a ForkJoinTask to be planned for asynchronous execution. This allows a new ForkJoinTask to be launched from an existing one. fork() only schedules a new task within a ForkJoinPool, but no child Java Virtual Machine is ever created.
  2. In turn, the join() method allows a ForkJoinTask to wait for the completion of another one.
There are two types of ForkJoinTask specializations:
  1. Instances of RecursiveAction represent executions that do not yield a return value.
  2. In contrast, instances of RecursiveTask yield return values. You can checkout RecursiveTask code sample at link: Performance comparison of Executor framework vs ForkJoin framework’s RecursiveTask feature in java or JDK7
Following example illustrates how to use RecursiveAction type of ForkJoinTask implementation:

Code Sample:

import static java.util.Arrays.asList;

import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class ForkJoinRandomFillAction {
    Random random = new Random();
   
    public void loadArray(int[] array) {
        for (int i=0; i<array.length; i++) {
            array[i] = random.nextInt(10000); //Generates numbers from 0 to 10000
        }
    }
   
    public static void main(String[] args) {
        ForkJoinRandomFillAction sort = new ForkJoinRandomFillAction();
      
        int arrayLength = 1_00_00_0000;
        int array[] = new int[arrayLength];

        //No. of times sequential & Parallel operation should be performed to warm up HotSpot JVM
        final int iterations = 10;
      
        for (int i = 0; i < iterations; i++) {
            long start = System.currentTimeMillis();
            sort.loadArray(array);

            System.out.println("Sequential processing time: " + (System.currentTimeMillis() - start) + " ms");
          
        }
      
        System.out.println("Number of processor available: " + Runtime.getRuntime().availableProcessors());
      
        ForkJoinPool fjpool = new ForkJoinPool(64); //Default parallelism level = Runtime.getRuntime().availableProcessors()
      
        for (int i = 0; i < iterations; i++) {
            // Create a task with the complete array
            RecursiveAction task = new RandomFillAction(array, 0, array.length);
            long start = System.currentTimeMillis();
            fjpool.invoke(task);

            System.out.println("Parallel processing time: "    + (System.currentTimeMillis() - start)+ " ms");
        }
      
        System.out.println("Number of steals: " + fjpool.getStealCount() + "\n");
    }
}

class RandomFillAction extends RecursiveAction {
    private static final long serialVersionUID = 1L;
    final int low;
    final int high;
    private int[] array;
    final int splitSize = 40000; //Some threshold size to spit the task
   
    public RandomFillAction(int[] array, int low, int high) {
        this.low = low;
        this.high = high;
        this.array = array;
    }

    @Override
    protected void compute() {
        if (high - low > splitSize) {
            // task is huge so divide in half
            int mid = (low + high) >>> 1;
            invokeAll(asList(new RandomFillAction(array, low, mid), new RandomFillAction(array, mid, high)));
        } else {
            //Some calculation logic
            Random random = new Random();
            for (int i = low; i < high; i++) {
                array[i] = random.nextInt(10000);
            }
        }
    }
}

Output:

Sequential processing time: 1180 ms
Sequential processing time: 1178 ms
Sequential processing time: 1167 ms
Sequential processing time: 1165 ms
Sequential processing time: 1162 ms
Sequential processing time: 1158 ms
Sequential processing time: 1154 ms
Sequential processing time: 1169 ms
Sequential processing time: 1168 ms
Sequential processing time: 1161 ms
Number of processor available: 4
Parallel processing time: 469 ms
Parallel processing time: 393 ms
Parallel processing time: 389 ms
Parallel processing time: 373 ms
Parallel processing time: 375 ms
Parallel processing time: 371 ms
Parallel processing time: 587 ms
Parallel processing time: 384 ms
Parallel processing time: 385 ms
Parallel processing time: 376 ms
Number of steals: 1498

Conclusion:
  1. ForkJoin framework gives almost 300% improvement in performance compare to sequential execution.
  2. I was just trying to demonstrate ForkJoin framework in simplest way possible. You can definitely use executor framework in java to split the task in different threads to gain better performance.
  3. This post focused on the new fork/join tasks provided by Java SE 7 for making it easier to write parallel programs. Though it is not that as easy as marking some methods or long running loops with annotations to make them run in parallel still it is a good addition to JDK 7.
References:
  1. Performance comparison of Executor framework vs ForkJoin framework’s RecursiveTask feature in java or JDK7
  2. Fork and Join: Java Can Excel at Painless Parallel Programming
  3. JDK 7 Adoption Guide

Tuesday, August 7, 2012

How to use node.js?

Introduction:

Node.js is a platform built on Chrome's JavaScript run-time for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices. Node.js is a server-side version of JavaScript. That means all the things all them cool things about JavaScript apply here.

What makes Node any different from the rest?
Node is evented I/O for V8 JavaScript. V8 is Google’s super fast JavaScript implementation that’s used in their Chrome browser. JavaScript’s ability to pass around closures makes event-based programming dead simple.

Node is not strictly for web development. You can think of Node as a framework for server development of any kind. With Node you can build an IRC server, a chat server, or HTTP server as done in following hello world example. 

You can use node.js to create light weight web server. See the following example from node.js tutorial site:

var http = require('http');
  http.createServer(function (req, res) {
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.write("Dynamic contents...");
      res.end('Hello World\n');
  }).listen(1337, "127.0.0.1");

console.log('Server running at http://127.0.0.1:1337/');
 
Above code is java script so you can write your dynamic code generation logic in java script and start using it in no time.

You will have to download and setup node.js from link:http://nodejs.org/ for Windows or whatever platform you prefer to use.

Start the web server using command:
node hello.js

To test if above sample works open your browser and hit url:  http://127.0.0.1:1337/

You should see familiar Hello World message.

References:
node.js Download: http://nodejs.org/
node.js Hello World Example: http://www.theprojectspot.com/tutorial-post/Node-js-for-beginners-part-1-hello-world/2
More detailed discussion: http://net.tutsplus.com/tutorials/javascript-ajax/this-time-youll-learn-node-js/

Thursday, July 26, 2012

How to create android 4 ICS emulator UI in tablet mode instead of phone mode?

Till now I was developing android application for Android 2.3.3. Now, I have started development for Android 4.0.* ICS (Ice scream Sandwich) version. I created new Android 4.0.3 image using AVD manager targeting API Level 15. Emulator runs but UI is in phone mode instead of tablet mode.

After some investigation I found following solution:
Step1: Goto AVD Manager.
Step2: Select Android 4.* AVD image.
Step3: Click Edit button on right side in AVD Manager UI.
Step4: Change skin type from "Default (WVGA800)" to "WXGA800" or WXGA720. (which ever resolution works for you)
Step5: Click Edit AVD button.
Step6: Start your Android 4.* emulator. This time you should see Android tablet like emulator UI.

References:
http://stackoverflow.com/questions/9917793/how-to-run-android-emulator-as-a-tablet-mode

Thursday, July 19, 2012

How to use keytool in java to generate key store to use MapView in Android?

Android MapView needs a MD5 key to access Google Maps on Android device or emulator. To do that we need to generate key store using java toolkit's keytool.exe.

Following command shows how to generate key store using keytool:
Command: C:\Program Files\Java\jdk1.6.0_30\bin>keytool -genkey -alias android -keyalg RSA -keystore <keystre.jks-path> -keysize 2048 -keypass <password>

For above command you can you JDK 1.6 or JDK 1.7. I tried the command with both versions.

How to find the MD5 key store if you have already generated it in past?
Command: keytool -list -v -keystore <keystore path>

Above command will ask you for that password. Provide the password you used to generate the key store. If you are using JDK 1.7 then don't forget to mention "-v" in above command otherwise you will get "SHA1" key only as output.

Issues faced:
1. I noticed in few post people mentioned that use keytool.exe from JDK 1.6, using JDK 1.7 key tool generates key store in SHA1 format instead of MD5 format which is required for MapView. That is not the case. Above command (keytool -list -v -keystore <keystore path>) will give you output of all the key in all available formats.

2. While generating key store you might get error -> keytool error: java.io.FileNotFoundException: keystore.jks (Access is denied)
This can happen because you don't have write permission in the directory where you are planning to generate key store.

3. You might also get Google map signed api key errors in Android which will look like follows:
java.io.IOException: Server returned: 3
This can happen if you have forgotten to generate debug keystore in MD5 format. Following command might just do the trick for you:

C:\Program Files\Java\jdk1.6.0_30\bin>keytool -list -alias <androiddebugkey> -keystore <debug.keystore path> -storepass android -keypass <password>

Output:
androiddebugkey, Jul 17, 2012, PrivateKeyEntry,
Certificate fingerprint (MD5): 12:16:C2:...
Copy above output printed after key "(MD5):" text and use it to obtain your apiKey from link: https://developers.google.com/android/maps-api-signup

For more information look at link:
https://developers.google.com/maps/documentation/android/mapkey#getdebugfingerprint

Note: Debug key only works in debug mode. Debug key will not work in production mode. When you upload your app on Android Market Place, you will have to generate key again. Look at LINK for more information.

References:
  1. Android MapView tutorial: https://developers.google.com/maps/documentation/android/hello-mapview
  2. The Most Common Java Keytool Keystore Commands: http://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html
  3. http://stackoverflow.com/questions/7633867/android-mapview-loading
  4. http://stackoverflow.com/questions/7296467/google-map-signed-api-key-errors-in-android

Tuesday, July 17, 2012

Why do I get debug certificate expired error when I debug Android app from Eclipse?

When I ran my Android app from eclipse IDE I got "Error generating final archive: Debug certificate expired" error at the console. I investigated on net and found following solution for the issue:

Step1: Goto "C:\Users\<user-name>\.android" (In fixed in Windows 7)
Step2: Delete "debug.keystore" file there or delete your debug certificate under ~/.android/debug.keystore on Linux and Mac OS X.
Step3: The Eclipse plugin should then generate a new certificate when next time you try to build a debug package. You may need to clean and then build the project to generate the certificate.

The self-signed certificate used to sign your application in debug mode (the default on Eclipse/ADT and Ant builds) will have an expiration date of 365 days from its creation date.

Note: You cannot release your application to the public when signed with the debug certificate.

References:
  1. http://developer.android.com/tools/publishing/app-signing.html
  2. https://groups.google.com/forum/?fromgroups#!topic/android-beginners/cBsrlCSZYhI
  3. http://stackoverflow.com/questions/2194808/debug-certificate-expired-error-in-eclipse-android-plugins

Friday, June 8, 2012

Playing around to Compiling Java Files At Runtime using Compiler API, as a result of JSR 199.

I was playing around to compiling java files at runtime using Compiler API as a result of JSR 199.  I used source at Compile Java Files At Runtime. From the source "ToolProvider.getSystemJavaCompiler()" at line 28 was returning null. Posting here so it might help someone else facing same issue in future.

I was getting java.lang.NullPointerException so I did "System.out.println(System.getProperty("java.home"));" and noticed my eclipse was pointing "C:\Program Files\Java\jre7" even after I changed my preferences to use JDK1.7 in place of JRE1.7. This error accors if java development envrionment points to JRE instead of JDK as it is menioned in a bug report at link: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6477844

I found a work around by forcing to use JDK1.7 by setting system property like this: "System.setProperty("java.home", "C:\\Program Files\\Java\\jdk1.7.0_02");"

Then I compiled my program and did not get any NullPointerException.

Thursday, March 15, 2012

Getting Started with Scala

I started my learning by doing fresh eclipse 3.6 + Scala 2.9 build setup. Setup failed first time but second time I was able to create sample project and run few sample programs. Scala IDE download link is mentioned in references link at the bottom of this post. Now it is time to take deep dive into Scala world!

 Why Scala? Scala is a SCAlable LAnguage.

Introductions:
Scala is a functional-object hybrid language with several powerful factors working in its favor:
1.    Scala compiles to Java byte code, meaning it runs on the JVM. In addition to enabling you to continue leveraging the rich Java open-source ecosystem, Scala can be integrated into an existing IT environment with zero migration effort.
2.    Scala is based on the functional principles of Haskell and ML, yet still borrows heavily from the familiar object-oriented concepts Java programmers love. As a result, it can blend the best of both worlds into a whole that offers significant benefit without sacrificing the familiarity we've come to depend on.
Learning a new programming language is always a daunting task, particularly for one with an entirely new mindset on approaching problems, such as the functional approach that Scala embraces, and even more so when it is hybridized with another approach, such as how Scala melds object-orientation with functional concepts. Learning Scala requires time, and with that commitment looming over your already busy schedule, you may not be able to identify the return on your investment at first blush. Let me assure you, Scala provides a number of intriguing features, many of which will be covered in future pieces in this series. Following is a partial list to help you see the benefits of tackling this language. With Scala, you'll be able to:
•    Create internal DSLs (think Ruby), thanks to Scala's flexibility regarding identifiers.
•    Create highly scalable, concurrent data processors, thanks to Scala's immutable-state-by-default stance.
•    Reduce equivalent Java code by one-half or two-thirds, thanks to a variety of Scala's syntactic features such as closures and implicit definitions.
•    Take advantage of parallel hardware architectures (such as multi-core CPUs), thanks to Scala's encouragement of functional designs.
•    Understand larger code bases, thanks to Scala's simplification of certain type rules, in essence demanding that "everything is an object."

Certainly Scala represents a powerful, new way to look at programming; the fact that it compiles to and runs on the JVM just makes using it for "real work" all that much easier.

Functional concepts
Functional languages get their name from the concept that programs should behave like mathematical functions; in other words, given a set of inputs, a function should always return the same output. Not only does this mean that every function must return a value, but that functions must inherently carry no intrinsic state from one call to the next. This intrinsic notion of statelessness, carried over into the functional/object world to mean immutable objects by default, is a large part of why functional languages are being hailed as the great saviors of a madly concurrent world.
Unlike many of the dynamic languages that have recently begun to carve out a space of their own on the Java platform, Scala is statically typed, just as Java code is. Unlike the Java platform, however, Scala makes heavy use of type inferencing, meaning the compiler analyzes the code deeply to determine what type a particular value is, without programmer intervention. Type inferencing requires less redundant type code. For example, consider the Java code required to declare local variables and assign to them, shown in Listing 1:
Listing 1. The genius of javac (sigh)
class BrainDead {
  public static void main(String[] args) {
    String message = "Why does javac need to be told message is a String?" +
      "What else could it be if I'm assigning a String to it?";
  }
}

let's take a look at what Scala can do.

Listing 2. Hello.Scala
              
object HelloWorld {
  def main(args: Array[String]): Unit = {
    System.out.println("Hello, Scala!")
  }
}

How to Compile:
Compile this with scalac Hello.scala and then run the resulting code either by using the Scala launcher (scala HelloWorld) or by using the traditional Java launcher, taking care to include the Scala core library on the JVM's classpath (java -classpath %SCALA_HOME%\lib\scala-library.jar;. HelloWorld). Either way, the traditional greeting should appear.


Listing 2 explained:
Some elements in Listing 2 are surely familiar to you, but some very new elements are at work here too. For instance, starting with the familiar call to System.out.println demonstrates Scala's fidelity to the underlying Java platform. Scala goes to great lengths to make the full power of the Java platform available to Scala programs. (In fact, it will even allow a Scala type to inherit from a Java class, and vice versa, but more about that later.)

On the other hand, if you're observant, you'll have noticed the lack of a semicolon at the end of the System.out.println call; this is no typo. Unlike the Java platform, Scala does not require the semicolon to terminate a statement if the termination is obvious by the line ending. Semicolons are still supported, however, and are sometimes necessary if, for example, more than one statement appears on the same physical line. For the most part, the budding Scala programmer can simply leave off the semicolons, and the Scala compiler will gently remind him or her (usually with a glaring error message) when one is necessary.

Also, although this is a minor nit, Scala does not require the file containing a class definition to mirror the name of the class. Some will find this a refreshing change from Java programming; those who do not can continue to use the Java class-to-file naming convention without problem.

Key Points to remember about Scala:
1.    Scala makes it very easy to interact with Java code. All classes from the java.lang package are imported by default, while others need to be imported explicitly.
2.    static members (methods or fields) do not exist in Scala. Rather than defining static members, the Scala programmer declares these members in singleton objects.
3.    Scala Integration with Java, it should be noted that it is also possible to inherit from Java classes and implement Java interfaces directly in Scala.
4.    Functions as objects: It is possible to pass functions as arguments in Scala, to store them in variables, and to return them from other functions. This ability to manipulate functions as values is one of the cornerstone of a very interesting programming paradigm called functional programming.
5.    Classes in Scala are declared using a syntax which is close to Java’s syntax. One important difference is that classes in Scala can have parameters.
6.    All classes in Scala inherit from a super-class. When no super-class is specified, as in the Complex example of previous section, scala.AnyRef is implicitly used.

I am collecting Scala notes from whatever details I am able to find on internet. This is my first draft of the notes I am creating on Scala. I will fine tune this blog post once I collect all important features and components of Scala. This blog is still good resource for quick 2 minutes Scala reference.

References:
Link: http://www.ibm.com/developerworks/java/library/j-scala01228.html
Video: http://www.parleys.com/#st=5&sl=1&id=10
Download & setup Scala IDE: http://scala-ide.org/download/current.html

Thursday, March 1, 2012

Why Android 2.3 apps can not access telephone API's or modify call state using MODIFY_PHONE_STATE permission?

I tried to record call as well many others are trying all over the world. Android 2.3 does not allow you to do that as far as i know. I refereed following links:
1. http://prasanta-paul.blogspot.in/2010/09/call-control-in-android.html

2. http://code.google.com/p/auto-answer/source/browse/trunk/src/com/everysoft/autoanswer/AutoAnswerIntentService.java

Above linked seemed to help. Many people told it worked from them in Android 2.1 and Android 2.2 but it does not work with Android 2.3. I got error message: "java.lang.SecurityException: Neither user 10035 nor current process has android.permission.MODIFY_PHONE_STATE." 


To capture call or pickup call programatically you need to use "android.permission.MODIFY_PHONE_STATE" permission in AndroidManifest.xml. From Android 2.3 onwards developers are not allowed to access this permission. Only venders with OEM license can use it for any apps which come preloaded on Android device when you buy it.

Enhancement request for Android 2.3 is already submitted by many developers as many are already using MODIFY_PHONE_STATE permission and without that permission their applications will be useless. Android guys have replied saying this permission was never supposed to be used by developers.

Visit above links for more information. If you are targeting Android 2.1 and Android 2.2 then those links might still help. If you found any new information regarding it then please comment below.

Tuesday, February 21, 2012

What is LazyPanel convenience class in GWT and how to use it?

The gwt lazy panel has a createWidget method that is created when lazyPanel.setVisible("true") is called, making it possible to reduce initial loading of a panel. It is a convenience class to help lazy loading of a panel. The bulk of a LazyPanel is not instantiated until setVisible(true) or ensureWidget() is called.

This class primarily can be used in conjunction with StackPanel, DisclosurePanel, and TabPanel when the child panels contain relatively heavy weight contents. It can a speed your GWT UI load time if LazyPanel is used wisely.

Check out following links for more information:

API documentation link: http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/user/client/ui/LazyPanel.html

Example link: http://ukitech.blogspot.in/2009/07/example-for-gwt-lazy-panel.html