Thursday, September 06, 2012

Java class loading mechanism

The default class loaders hierarchy of the JVM

- bootstrap class loader: loads Java's core classes, the java.* packages, the path is found on sun.boot.class.path sytem property, and usually it loads rt.jar and i18n.jar files, this classloader also loads the main class and all other classes that are referenced;

- extensions class loader: loads classes from the ext folder located in JAVA_HOME/jre/lib/ext, the path is found on java.ext.dirs system property;

- system class loader: loads classes that are available on paths specified by the system property java.class.path, the default value is the current directory, but you can change it by using the -classpath or -cp command-line options, or setting the CLASSPATH environment variable.
Delegation model
The class loaders are linked in a hierarchical structure. When asked to load a class, a class loader first asks its parent (class loader that loaded it) to load the class. If the parent can't load that class, the class loader would try to load it itself. If the parent succeeded, that class is returned to the class loader. On creation of a class loader instance, we can use it's constructor to set the parent.

When a class loader tries to load a class, it delegates to its parent and the parent does the same until the bootstrap class loader.

Role of the Thread context ClassLoader and how it can be used
The context ClassLoader is provided when creating the thread for use by code running in this thread when loading classes and resources.It was introduced in Java 1.2 to enable frameworks running in application servers to access the right class loader for loading application classes.

The need of context class loader came because of the visibility problem in classpath. For example, say that you have a server (Tomcat), the framework jar would need to be placed in WEB-INF/lib and not on the system class path or in a server class path such as TOMCAT_HOME/common/lib.
The process of loading classes with Class.forName() Create an instance of the class by invoking the class.newInstance() method on the class object after dynamic loading.

Example:
String className = "ro.blogspot.UserDao";
Class cls = Class.forName(className);
UserDao userDao = (UserDao)cls.newInstance();
List users = userDao.getAllUsers();


Java serialization mechanisms

In Java we can create reusable objects in memory, but they have a limited life, as long the Java virtual machine remains running.

Java serialization is a mechanism where an object's state can be saved as a sequence of bytes that have the object's data and information about the objects's type and the types of data stored in the object and can later be fully restored to regenerate the original object. You can use object serialization on any object that implements the java.io.Serializable or the java.io.Externalizable interface.

The Serializable interface is just a marker interface (it has no methods or fields). Transient keyword is a modifier applied to fields (like time elapsed or logger) that are not part of the persistent state of the object and thus never saved during serialization.


Example:
import java.io.Serializable;

public class PersistentObject implements Serializable {
  String name = "DefaultName";
}


import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;


public class MainClass {

  public static void main(String[] args) {
    String filename = "persistentObject.ser";
    PersistentObject persistentObject = new PersistentObject();
    FileOutputStream fos = null;
    ObjectOutputStream out = null;
    try {
      fos = new FileOutputStream(filename);
      out = new ObjectOutputStream(fos);
      out.writeObject(persistentObject);
    }
    catch (IOException ex) {
      System.out.println("couldn't serialize");
    }
    finally {
      if (out != null) {
        try {
          out.close();
        }
        catch (IOException e) {
          System.out.println("couldn't close the object output stream");
        }
      }
    }
  }
}

and the content of persistenObject.ser file viewed with a HEX editor is

where you can see the type of my field as java.lang.String and the value and now if I make the field name transient it won't be saved in my file.
 transient String name = "DefaultName";

This is how we read a serializable object from a file:


import java.io.*;


public class MainClass {

  public static void main(String[] args) {
    String filename = "persistentObject.ser";
    PersistentObject persistentObject = null;
    FileInputStream fis = null;
    ObjectInputStream in = null;
    try {
      fis = new FileInputStream(filename);
      in = new ObjectInputStream(fis);
      persistentObject = (PersistentObject) in.readObject();
    }
    catch (IOException ex) {
      System.out.println("couldn't read the object");
    }
    catch (ClassNotFoundException ex) {
      System.out.println("couldn't the class to cast the object from the file: " + filename);
    }
    finally {
      if (in != null) {
        try {
          in.close();
        }
        catch (IOException e) {
          System.out.println("couldn't close the input stream);
        }
      }
    }
    System.out.println("value from object is: " + persistentObject.name);
  }
}

and after running this application we'll see in console: "value from object is: DefaultName".

In case there is a graph and has an object that does not support the Serializable interface a NotSerializableException will be thrown and will identify the class of the non-serializable object.

Example:
Having an animal class which doesn't implement the java.io.Serializable interface

public class Animal {
    private String name;
    public String getName() {
        return name;
    }
    public Animal(String name) {
        this.name = name;
    }
}

and the same persistence object that includes an instance of animal

import java.io.Serializable;
public class PersistentObject implements Serializable {
    String name = "DefaultName";
    Animal testAnimal = new Animal("Test");
}

If we try to write an object of type PersistentObject again
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;


public class MainClass {

  public static void main(String[] args) {
    String filename = "persistentObject.ser";
    PersistentObject persistentObject = new PersistentObject();
    FileOutputStream fos = null;
    ObjectOutputStream out = null;
    try {
      fos = new FileOutputStream(filename);
      out = new ObjectOutputStream(fos);
      out.writeObject(persistentObject);
    }
    catch (IOException ex) {
      System.out.println("couldn't serialize");
    }
    finally {
      if (out != null) {
        try {
          out.close();
        }
        catch (IOException e) {
          System.out.println("couldn't close the object output stream");
        }
      }
    }
  }
}

we'll get the following stacktrace

java.io.NotSerializableException: ro.blogspot.valentinjava.Animal
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at ro.blogspot.valentinjava.MainClass.main(MainClass.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)...

and the written object can't be read.

The serialization mechanism can be customized with the help of  the java.io.Externalizable  interface white has two methods writeExternal(ObjectOutput out) method to save the state of the object and readExternal(ObjectInput in) method to read the data written by the writeExternal method from the stream and restore the state of the object.

Each class is good to have a serial version number, that is used to identify the original class version which it can be used of writing streams and from which it can be read. For example, a class must have:

 private static final long serialVersionUID = -8997273866406805568L;
and this number is a 64-bit hash of the class name, interface class names, methods, and fields. As a remark for dynamic proxy classes and enum types the serial version number is always 0L.

If you want to deserialize a class which was serialized with a different serialVersionUID you'll get an Exception in thread "main" java.io.InvalidClassException.

Monday, September 03, 2012

Java core concepts: interfaces and inheritance, classes and objects, polymorphism

As Java is an object oriented programming language and there are multiple object interacting, there is need for a contract between objects. Object's interface is an abstract type that is used to specify what the object can do to the outside world, it can contain method signature and constant declaration (variables that are declared to be static and final), may never contain method definitions.

Example:
interface Printable {
  void print();
  String DEFAULT_COLOR = "BLACK";
  String ERROR_COLOR = "RED";
}
A class is a construct that is used to create instances of itself referred as objects. A class has members which enable it's instances to have state and behavior. We can say that an animal is an instance of the class of objects known as animals.

Example:
public class Animal {
  int age = 0;
  int weight = 0;
  void speak(){
    System.out.println("I am an animal and can speak");
  }
}

The fields age, weight represent the object's state, and the method speak define its interaction with the outside world. Abstract classes can have or not abstract methods and cannot be instantiated, but they can be sub-classed. An abstract methods is a methods that has just the declaration (as we did for interfaces, without braces, and followed by a semicolon).

Example:
public abstract class Animal {
  int age = 0;
  int weight = 0;
  abstract void speak();
}

When an abstract class is subclassed, the subclass many times provides implementations for all of the abstract methods in its parent class, if there is at least one abstract method without implementation then the subclass must also be declared abstract.

Differences between interfaces and abstract classes:
- interfaces can contain only fields that are static and final;
- abstract classes can contain fields that are not static and final; - interfaces can contain just methods signatures;
- abstract classes can contain implemented methods;
- interfaces can help on multiple inheritance (example: implements Comparable, Printable);
- abstract classes are usually sub-classed to share pieces of implementation.


Polymorphism is the ability of an object to take on many forms. There are three types of polymorphism: ad-hoc (overloading and overriding), parametric (generics) and dynamic method binding(late binding).
The signature of a method is the combination of the method's name along with the number and types of the parameters (and their order).

Overloaded methods are methods with the same name signature but with a different number of parameters or different types in the parameter list.
Overridden methods are methods that are redefined within a subclass.

Java parametric polymorphism is called generics and implemented through type erasure. This design decision was made to ensure backwards compatibility and ensure that Java generics are interoperable with non-generic code.

Dynamic (or late biding) method is the ability of a program to resolve references to subclass methods at runtime.

Suppose you have two subclasses Horse and Lion:
public abstract class Animal {
   public abstract void eat;
}

public class Horse extends Animal {
   public void eat() {
      System.out.println("Eats grass");
   }
}

public class Lion extends Animal {
   public void eat() {
      System.out.println("Eats meat");
   }
}

And now you have a list of animals you can just do this and it will print to correct eat:
List animals = new List();
animals.add(new Lion());
animals.add(new Horse());

for(Animal a: animals) {
    a.eat();
}

Inheritance is used when there is a is-a relationship between a class and another (the lion is an animal). Composition is used when there is a has-a relationship between a class and another (a house have doors).

As a general rule prefer composition over inheritance because:
 - a subclass depends on the inherited implementation details for its function and when the super-class's implementation it's changed the subclass functionality might brake;
- inheritance breaks encapsulation by exposing subclasses to implementation details in the super-class;
- for code reuse.

Wednesday, August 08, 2012

Hello world!

 I'm Valentin, a java developer. In this blog, I'll write about programming.
 If you have any wishes about things I should write about, feel free to leave a comment.

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello, World");
    }

}