Wednesday, December 8, 2010

Reflection and String mutability

Can strings become mutable  with reflection?

public class ChangingMutabilityWithReflection {

public String name = "Strings are immutable";

public static void main(String[] args) throws Exception {

ChangingMutabilityWithReflection abc = new ChangingMutabilityWithReflection();

Class c1 = Class.forName("com.Rupali.common.ChangingMutabilityWithReflection");

Field field2 = c1.getDeclaredField("name");

field2.setAccessible(true);

System.out.println("Value of immutable String = " + abc.name);

field2.set(abc, "change immutability");

System.out.println("changed value of string " + abc.name);

}

}

Why String has been made immutable in Java?

Though, performance is also a reason (assuming you are already aware of the internal String pool maintained for making sure that the same String object is used more than once without having to create/re-claim it those many times), but the main reason why String has been made immutable in Java is 'Security'.


Suppose you need to open a secure file which requires the users to authenticate themselves. Let's say there are two users named 'user1' and 'user2' and they have their own password files 'password1' and 'password2', respectively. Obviously 'user2' should not have access to 'password1' file.

As we know the filenames in Java are specified by using Strings. Even if you create a 'File' object, you pass the name of the file as a String only and that String is maintained inside the File object as one of its members.

Had String been mutable, 'user1' could have logged into using his credentials and then somehow could have managed to change the name of his password filename (a String object) from 'password1' to 'password2' before JVM actually places the native OS system call to open the file. This would have allowed 'user1' to open user2's password file. Understandably it would have resulted into a big security flaw in Java. I understand there are so many 'could have's here, but you would certainly agree that it would have opened a door to allow developers messing up the security of many resources either intentionally or un-intentionally.

With Strings being immutable, JVM can be sure that the filename instance member of the corresponding File object would keep pointing to same unchanged "filename" String object. The 'filename' instance member being a 'final' in the File class can anyway not be modified to point to any other String object specifying any other file than the intended one (i.e., the one which was used to create the File object).

Test Driven Development

What is TDD?

Test-Driven Development (TDD) is a software development technique consisting of short iterations where new test cases covering the desired improvement or new functionality are written first, then the production code necessary to pass the tests is implemented, and finally the software is refactored to accommodate changes.


Practitioners emphasize that test-driven development is a method of designing software, not merely a method of testing.

Test-Driven Development Cycle

1. Add a test

In test-driven development, each new feature begins with writing a test. This test must inevitably fail because it is written before the feature has been implemented. In order to write a test, the developer must understand the specification and the requirements of the feature clearly. This may be accomplished through use cases and user stories to cover the requirements and exception conditions. This could also imply an invariant, or modification of an existing test. This is a differentiating feature of test-driven development versus writing unit tests after the code is written: it makes the developer focus on the requirements before writing the code, a subtle but important difference.

2. Run all tests and see if the new one fails

This validates that the test harness is working correctly and that the new test does not mistakenly pass without requiring any new code.

3. Write some code

The next step is to write some code that will cause the test to pass. The new code written at this stage will not be perfect and may, for example, pass the test in an inelegant way. That is acceptable because later steps will improve and hone it.

It is important that the code written is only designed to pass the test; no further (and therefore untested) functionality should be predicted and ‘allowed for’ at any stage.

4. Run the automated tests and see them succeed

If all test cases now pass, the programmer can be confident that the code meets all the tested requirements. This is a good point from which to begin the final step of the cycle.

5. Refactor code

Now the code can be cleaned up as necessary. By re-running the test cases, the developer can be confident that refactoring is not damaging any existing functionality.

6. Repeat

Starting with another new test, the cycle is then repeated to push forward the functionality. The size of the steps can be as small as the developer likes, or get larger if s/he feels more confident.

Friday, October 8, 2010

Can you override Static Methods in Java

 Well... the answer is NO if you think from the perspective of how an overriden method should behave in Java. But, you don't get any compiler error if you try to override a static method. That means, if you try to override, Java doesn't stop you doing that; but you certainly don't get the same effect as you get for non-static methods. Overriding in Java simply means that the particular method would be called based on the run time type of the object and not on the compile time type of it (which is the case with overriden static methods). Okay... any guesses for the reason why do they behave strangely? Because they are class methods and hence access to them is always resolved during compile time only using the compile time type information. Accessing them using object references is just an extra liberty given by the designers of Java and we should certainly not think of stopping that practice only when they restrict it :-)


Example: let's try to see what happens if we try overriding a static method:-

class SuperClass{
......
public static void staticMethod(){
System.out.println("SuperClass: inside staticMethod");
}
......
}

public class SubClass extends SuperClass{
......
//overriding the static method
public static void staticMethod(){
System.out.println("SubClass: inside staticMethod");
}

......
public static void main(String []args){
......
SuperClass superClassWithSuperCons = new SuperClass();
SuperClass superClassWithSubCons = new SubClass();
SubClass subClassWithSubCons = new SubClass();

superClassWithSuperCons.staticMethod();
superClassWithSubCons.staticMethod();
subClassWithSubCons.staticMethod();
...
}

}

Output:-

SuperClass: inside staticMethod
SuperClass: inside staticMethod
SubClass: inside staticMethod

Notice the second line of the output. Had the staticMethod been overriden this line should have been identical to the third line as we're invoking the 'staticMethod()' on an object of Runtime Type as 'SubClass' and not as 'SuperClass'. This confirms that the static methods are always resolved using their compile time type information only.

Memory leaks with static

'static' can't straightway be blamed for causing memory leaks. But, if the programmer has not well thought the usage and has not taken care of the setting the references to 'null' explicitly after using the static objects then they can definitely cause memory leaks. Let's see how.

As 'static' members will by default live for the entire life of an app unless they are explicitly set to 'null'. So, always make it a point to nullify the references as soon as you reach at a point in your code where the use of the static member is over. For example: suppose you have created a 'Statement' object from a DB Connection and the connection is a pooled one. Now as you know calling close()method on a pooled connection will not actually close the connection instead it will return the Connection object to the pool to be re-used. So, in such a case unless you explicitly close the 'Statement' object, it would keep consuming precious memory space for no real use. Just think the scenario where you have declared the 'Statement' object as a static member, it'll be maintained in the memory for the entire life time of the app even when the control is out of the scope. It's just a sample scenario and many of you might never have used 'Statement' object in such an irresponsible manner. It's just an attempt to show how the 'static' can be misused to cause memory leaks in Java.


Not that if your Statement object is non-static you should reply on the out-of-scope nullification (i.e., as soon as control is out of scope the local objects would be marked for re-claimation) as in case you still have a significant amount of code (in terms of time/space) after using the Statement last and before reaching the end of the local scope, it would be a sheer wastage of memory if you don't explicitly nullify the 'Statement' after its use is over. Such a scenario should also be thought of as memory leaks only and one should always make sure the nullification of resources is as close to their last usage as possible.


Therefore, in summary we can say that one should/must :-

  • always think if you really need to make this variable/member a 'static' one?
  • always try to confine the scope of an object to restrict its usage only to the section it's actually needed
  • always make a conscious effort to explicitly nullify objects once you finish using them (especially the large objects)

Choosing the Most Specific Method - Tricky Method Overloading

Let's start with looking at a code-segment and try to think of the output/error, it would produce when compiled/executed and subsequently we'll discuss the behavior of code.

public class NullTest {

   public static void method(Object obj){
     System.out.println("method with param type - Object");
   }
 
   public static void method(String obj){
     System.out.println("method with param type - String");
   }
 
   public static void main(String [] args){
     method(null);
   }
}

So, what do you expect as the output here? Before thinking about the output, do you really expect the code to compile successfully? Well... yeah, the code will compile and run fine as opposed to anyone who might have sensed an ambiguity here - we'll see the reason soon. 

Since the methods are overloaded, the resolution will be done at compile-time only. Which method do you see being bind here - the one with parameter type 'Object' or the one with parameter type 'String' and why? Of course, the compiler can't bind two methods with one call, so on what basis would it pick the most suitable? Which method would be picked, is evident from the output given below:-


method with param type - String

Any guesses for why a special treatment is being given to 'String' here? Well... it's not actually for 'String' class specifically, but any sub-class would get a preference over the super class in such a situation. But, why? Because JLS (Section: 15.12.2.5)allows this. It clearly says:

"If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specificmethod is chosen."

As you easily deduce that the compiler should be able to pick 'the most specific', failing which it will throw a compile-time error. Let's understand it with the below code-segment which doesn't compile because the compiler can't pick 'the most specific' here.


public class NullTest {

   public static void method(Object obj){
     System.out.println("method with param type - Object");
   }
 
   public static void method(String str){
     System.out.println("method with param type - String");
   }
 
   public static void method(StringBuffer strBuf){
     System.out.println("method with param type - StringBuffer");
   }
 
   public static void main(String [] args){
     method(null); //... compile-time error!
   }
}

Why is the compiler not able to pick 'the most specific' here - because both Stringand StringBuffer are are sub-classes of the Object class, but without being in the same inheritance hierarchy. For finding 'the most specific' method, the compiler needs to find a method having the parameter type, which is a sub-class of the parameter types of all other overloaded methods.

This holds true for overloaded methods having more than one parameters as well. The compiler would pick 'the most specific' by looking which method is having at least one of its parameter types as a clear sub-class of the corresponding parameter type and other parameter types being either the same or clear sub-classes, in all otheroverloaded methods. If it can find one, good, otherwise it will throw a compile-time error. For example:


public class NullTest {

 public static void method(Object obj, Object obj1){
   System.out.println("method with param types - Object, Object");
 }

 public static void method(String str, Object obj){
   System.out.println("method with param types - String, Object");
 }

 public static void main(String [] args){
   method(null, null);
 }
}

Output

method with param types - String, Object

In this case the compiler can easily pick 'the most specific' as the method having parameter types (String, Object) as the other overloaded method is having its parameter types as (Object, Object) - clearly 'String' is a subclass of 'Object' and the other parameter is of same type, so the method with parameter types(String, Object) can be picked with ease. But, the below code would throw a compile-time error as none of the methods satisfy the condition for being picked as 'the most specific' method.


public class NullTest {

 public static void method(Object obj, String obj1){
   System.out.println("method with param types - Object, String");
 }

 public static void method(String str, Object str1){
   System.out.println("method with param types - String, Object");
 }

 public static void main(String [] args){
   method(null, null); //... compile-time error!
 }
}

Work with Memcache

Step1. Download memecache windows exe file from http://jehiah.cz/projects/memcached-win32/
1. Unzip the binaries in your desired directory (eg. c:\memcached)
2. Install the service using the command: 'c:\memcached\memcached.exe -d install' from either the command line
3. Start the server from the Microsoft Management Console or by running the following command: 'c:\memcached\memcached.exe -d start'
4. Use the server, by default listening to port 11211
or 5 memcached.exe -v -d start -m 128 -l 127.0.0.1 -p 11211
This starts memcached.exe up as a daemon, using 128mb of memory, and listening on IP 127.0.01, port 11211.
package memcache;
import com.danga.MemCached.*;

public class MemCacheClient {
// create a static client as most installs only need
// a single instance
protected static MemCachedClient mcc = new MemCachedClient();

// set up connection pool once at class load
static {

// server list and weights
String[] servers =
{
//"10.139.201.51:11211",
"127.0.0.1:11211",
//"server2.mydomain.com:1624",
//"server3.mydomain.com:1624"
};

Integer[] weights = { new Integer(3), new Integer(3), new Integer(2) };

// grab an instance of our connection pool
SockIOPool pool = SockIOPool.getInstance();

// set the servers and the weights
pool.setServers( servers );
pool.setWeights( weights );

// set some basic pool settings
// 5 initial, 5 min, and 250 max conns
// and set the max idle time for a conn
// to 6 hours
pool.setInitConn( 5 );
pool.setMinConn( 5 );
pool.setMaxConn( 250 );
pool.setMaxIdle( 1000 * 60 * 60 * 6 );

// set the sleep for the maint thread
// it will wake up every x seconds and
// maintain the pool size
pool.setMaintSleep( 30 );

// set some TCP settings
// disable nagle
// set the read timeout to 3 secs
// and don't set a connect timeout
pool.setNagle( false );
pool.setSocketTO( 3000 );
pool.setSocketConnectTO( 0 );

// initialize the connection pool
pool.initialize();


// lets set some compression on for the client
// compress anything larger than 64k
mcc.setCompressEnable( true );
mcc.setCompressThreshold( 64 * 1024 );
}
/**
* http://jehiah.cz/projects/memcached-win32/
* 1. Unzip the binaries in your desired directory (eg. c:\memcached)
2. Install the service using the command: 'c:\memcached\memcached.exe -d install' from either the command line
3. Start the server from the Microsoft Management Console or by running the following command: 'c:\memcached\memcached.exe -d start'
4. Use the server, by default listening to port 11211

memcached.exe -v -d start -m 128 -l 10.139.201.51 -p 11211
* @param arg
*/
public static void main(String arg[]) {
mcc.set( "foo", "This is a test String" );
String bar = String.valueOf(mcc.get( "foo" ));
System.out.println(bar);
}
}

Tuesday, September 7, 2010

Lazy initialization of Java Singletons

Code snippet below shows a typical way of initializing singleton class in Java.

class Singleton {
  private static Singleton singleton;

  private Singleton() {
  }

  public static synchronized Singleton getSingleton() {
      if (singleton == null)
          singleton = new Singleton();
      return singleton;
  }
}


Nothing wrong with this approach but the only issue is performance penalty we pay for the synchronized block. Another not so clean way to get around this is by using Double-checked locking idiom as shown below in the code snippet. But again volatile variables are not terribly fast as compared to synchronized blocks so the performance mileage we get out this, won't be much.

class Singleton {
  private volatile static Singleton singleton;

  private Singleton() {
  }

  public static Singleton getSingleton() {
      if (singleton == null) {
          synchronized (Singleton.class) {
              if (singleton == null)
                  singleton = new Singleton();
          }
      }
      return singleton;
  }
}

Fortunately, there is a better and cleaner way of doing this by using Initialization on Demand Holder Idiom.
...
static class SingletonHolder {
  private static Singleton singleton = new Singleton();

  public static Singleton getSingleton() {
      return singleton;
  }
}
...

The trick here is that whenever the first call to SingletonHolder.getSingleton() is made, the SingletonHolder static class will be loaded into the JVM and so, JVM will take care of synchronizing if multiple threads are invoking the method and hence it is obviously going to be more efficient than users doing synchronization.

Wednesday, August 11, 2010

Don't Ignore serialVersionUID

Okay,I admit that this one should have totally been obvious to me long ago. But just 4.5 years with Java...so perhaps I can be forgiven ;)
The serializable class BlaBlaBla does not declare a static final serialVersionUID field of type long BlaBlaBla.java 
If you're like me, you roll your eyes and politely add a @SuppressWarnings("serial") to the top of the class definition (or, worse, you just shut the warning message off in your IDE altogether. Even I don't do that!). You reason with yourself that current versions of Java conveniently and automatically compute the serialVersionUID at run-time, so there's no need to bother with the formality of a version number on your class - it's just a nuisance holdover from days of Java yore.!


IT'S A TRAP!


Now that I've found myself well into a new project with this lazy philosophy, I'm starting to run into problems.\I'm finding that when I make the most trivial changes to my shared classes, I need to compile both the server and the client components. The two components that were supposed to be loosely coupled are now hopelessly intertwined. So I did some further research on how the JVM computes the ad-hoc serialVersionUID at runtime when it isn't provided.

In a nutshell, backward-compatability with respect to serialization and de-serialization is a lot less fragile than the cases that the serialVersionUID generation is protecting you against. That version generation algorithm computes an SHA hash based on the class name, sorted member variables, modifiers, and interfaces.

In reality, serialization and de-serialization generally only breaks when one of the following things happens to your class (from the aforementioned article at JavaWorld):

  • Delete fields
  • Change class hierarchy
  • Change non-static to static
  • Change non-transient to transient
  • Change type of a primitive field
Ensure Minimal Coupling Between Components
To ensure that your components which use Serialization have minimal runtime dependencies on each other, you have two options:
  • Declare a specific serialVersionUID, and update it whenever you make a change that breaks backward compatability.
  • Don't rely on any classes for use as transfer objects which will potentially change. This one is pretty obvious, but sometimes you will be surprised down the road at which classes are modified more often than others.
  • Don't use your own objects at all when transferring data. Instead, rely on classes like Integers, Strings, or HashMaps to shuttle data around among components. (Obviously, protocols like SOAP and REST rely on XML documents for this to ensure maximum de-coupling, but you're presumably using something like EJB remoting to avoid the complexity or overhead of these protocols).

What is difference between iterator access and index access?

Index based access allow access of the element directly on the basis of index. The cursor of the datastructure can directly goto the ‘n’ location and get the element. It doesnot traverse through n-1 elements.
In Iterator based access, the cursor has to traverse through each element to get the desired element.So to reach the ‘n’th element it need to traverse through n-1 elements.
Insertion,updation or deletion will be faster for iterator based access if the operations are performed on elements present in between the datastructure.
Insertion,updation or deletion will be faster for index based access if the operations are performed on elements present at last of the datastructure.
Traversal or search in index based datastructure is faster.
ArrayList is index access and LinkedList is iterator access.

Can a static block throw exception?

Yes, static block can throw only Runtime exception or can use a try-catch block to catch checked exception.
Typically scenario will be if JDBC connection is created in static block and it fails then exception can be caught, logged and application can exit. If System.exit() is not done, then application may continue and next time if the class is referred JVM will throw NoClassDefFounderror since the class was not loaded by the Classloader

What the heck in Serialization?

Why to Serialize at all?

A typical enterprise application will have multiple components and will be distributed across various systems and networks. In Java, everything is represented as objects; if two Java components want to communicate with each other, there needs be a mechanism to exchange data. One way to achieve this is to define your own protocol and transfer an object. This means that the receiving end must know the protocol used by the sender to re-create the object, which would make it very difficult to talk to third-party components. Hence, there needs to be a generic and efficient protocol to transfer the object between components. Serialization is defined for this purpose, and Java components use this protocol to transfer objects.

This is how Serialization algo work in Java:








Static vs init block in java

The static block is only loaded when the class object is created by the JVM for the 1st time whereas init {} block is loaded every time class object is created. Also first the static block is loaded then the init block.

public class LoadingBlocks {

static{
System.out.println("Inside static");
}
{
System.out.println("Inside init");
}
public static void main(String args[]){
new LoadingBlocks();
new LoadingBlocks();
new LoadingBlocks();
}
}
Output:
Inside static
Inside init
Inside init
Inside init

Tuesday, August 10, 2010

SRP:The Single Responsibility Principle

THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A
CLASS TO CHANGE.

It is important to separate two responsibilities into two separate classes.Because each responsibility is an axis of change. When the requirements change, that change will be manifest through a change in responsibility amongst the classes. If a class assumes more than one responsibility, then there will be more than one reason for it to change.
If a class has more then one responsibility, then the responsibilities become coupled.Changes to one responsibility may impair or inhibit the class’ ability to meet the others.This kind of coupling leads to fragile designs that break in unexpected ways when changed.
E.g. If we define a  Rectangle class with two methods. One draws the rectangle on the screen, the other computes the area of the rectangle. Two different applications use the Rectangle class. One application does computational geometry. It uses Rectangle to help it with the mathematics of geometric shapes.It never draws the rectangle on the screen. The other application is graphical in nature. It may also do some computational geometry, but it definitely draws the rectangle on the screen.

This design violates the SRP. The Rectangle class has two responsibilities. The first responsibility is to provide a mathematical model of the geometry of a rectangle. The second responsibility is to render the rectangle on a graphical user interface.

The violation of SRP causes several nasty problems. Firstly, we must include the GUI
in the computational geometry application. In a Java application, the .class files for the GUI have to be deployed to the target platform. Secondly, if a change to the GraphicalApplication causes the Rectangle to
change for some reason, that change may force us to rebuild, retest, and redeploy the ComputationalGeometryApplication. If we forget to do this, that application may break in unpredictable ways.

Wednesday, August 4, 2010

Pass by reference or value?

Check out this program to understand:

public class TestPassByReference {
         public static void main(String[] args) {
                // declare and initialize variables and objects
                int i = 25;
                String s = "Java is fun!";
                StringBuffer sb = new StringBuffer("Hello, world");

                // print variable i and objects s and sb
                System.out.println(i);     // print it (1)
                System.out.println(s);    // print it (2)
                System.out.println(sb);  // print it (3)

                // attempt to change i, s, and sb using methods
                iMethod(i);
                sMethod(s);
                sbMethod(sb);

                 // print variable i and objects s and sb (again)
                 System.out.println(i);    // print it (7)
                 System.out.println(s);   // print it (8)
                 System.out.println(sb); // print it (9)

         }

         public static void iMethod(int iTest) {
                iTest = 9;                          // change it
                System.out.println(iTest); // print it (4)
                return;
         }

         public static void sMethod(String sTest) {
                sTest = sTest.substring(8, 11); // change it
                System.out.println(sTest);        // print it (5)
                return;
         }

         public static void sbMethod(StringBuffer sbTest) {
                sbTest = sbTest.insert(7, "Java "); // change it
                System.out.println(sbTest);            // print it (6)
                return;
          }
}

Output of the program :

25
Java is fun!
Hello, world
9
fun
Hello, Java world
25
Java is fun!
Hello, Java world