Tuesday 27 August 2013

Singleton, Serialization, RMI, Proxy Design Pattern

Singleton

Q1. What is a singleton pattern? How do you code it in Java?
Ans. A singleton is a class that can be instantiated only one time in a JVM per class loader. Repeated calls always return the same instance. Ensures that a class has only one instance, and provide a global point of access. It can be an issue if singleton class gets loaded by multiple class loaders or JVMs.

public class OnlyOne {
      private static OnlyOne one = new OnlyOne();
            // private constructor. This class cannot be instantiated from outside and prevents subclassing.
      private OnlyOne(){}
      public static OnlyOne getInstance() {
            return one;
      }
}

Q2. What is the difference b/w Singleton and Static class?
Ans. Static class is one approach to make a class singleton by declaring all the methods as static so that you can’t create any instance of that class and can call the static methods directly.

A static class is one that has only static methods. The design style embodied in a static class is purely procedural.

Singleton, on the other hand, is a pattern specific to OO design. It is an instance of an object (with all the possibilities inherent in that, such as polymorphism), with a creation procedure that ensures that there is only ever one instance of that particular role over its entire lifetime.

Singleton pattern has several advantages over static classes. First, a singleton can extend classes and implement interfaces, while a static class cannot (it can extend classes, but it does not inherit their instance members). A singleton can be initialized lazily or asynchronously while a static class is generally initialized when it is first loaded, leading to potential class loader issues. However the most important advantage, though, is that singletons can be handled polymorphically without forcing their users to assume that there is only one instance.

Q3. Difference between Singleton and Flyweight Design pattern?
Ans.
Singleton pattern is a CREATIONAL pattern in which only one instance is created and the same instance is reused multiple times by different users.

Flyweight pattern is a STRUCTURAL pattern which is useful in scenarios where there are lot of objects which share some common intrinsic information. Instead of storing the common intrinsic information n times for n objects, it is stored only once in one object and is referenced by all the objects which want to use it.

(This object which contains all the common intrinsic information is called the flyweight object)

Q4. How to share a Singleton across multiple JVM's.
Ans. For Serializable and Externalizable classes, readResolve method allows a class to replace/resolve the object read from the stream before it is returned to the caller. By implementing the readResolve method, a class can directly control the types and instances of its own instances being deserialized. The method is defined as follows:
        ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;

Ex:
public class Singleton {       public static final Singleton INSTANCE = new Singleton(); 
      private Singleton () { }
      private Object readResolve() { 
            return INSTANCE; 
      } 
}

The readResolve method is called when ObjectInputStream has read an object from the stream and is preparing to return it to the caller. readResolve is called after readObject has returned (conversely writeResolve is called before writeObject and probably on a different object). ObjectInputStream checks whether the class of the object defines the readResolve method. If the method is defined, the readResolve method is called to substitute another instance in the place of the one created by readObject (i.e to allow the object in the stream to designate the object, INSTANCE here, to be returned). The object reference returned by this method is then replaced in place of newly created object.

And before the object is written, it is written to object output stream. writeReplace() method on the other side takes care of the same. The writeReplace() method allows a class of an object to nominate its own replacement in the stream before the object is written. By implementing the writeReplace method, a class can directly control the types and instances of its own instances being serialized.

The writeReplace method is called when ObjectOutputStream is preparing to write the object to the stream. The ObjectOutputStream checks whether the class defines the writeReplace method. If the method is defined, the writeReplace method is called to allow the object to designate its replacement in the stream. The object returned should be either of the same type as the object passed in or an object that when read and resolved will result in an object of a type that is compatible with all references to the object. If it is not, a ClassCastException will occur when the type mismatch is discovered.

For example, a Singleton class could be created for which only a single instance of each symbol binding existed within a virtual machine. The readResolve method would be implemented to determine if that singleton was already defined and substitute the preexisting equivalent Singleton object to maintain the identity constraint. In this way the uniqueness of Singleton objects can be maintained across serialization.

Methods are defined as follows:
            ANY-ACCESS-MODIFIER Object writeReplace()/readResolve() throws ObjectStreamException;


Serialization

Q5. What is Java Serial Version ID?
Ans. Say you create a “Car” class, instantiate it, and write it out to an object stream. The flattened car object sits in the file system for some time. Meanwhile, if the “Car” class is modified by adding a new field. Later on, when you try to read (i.e. deserialize) the flattened “Car” object, you get the java.io.InvalidClassException – because all serializable classes are automatically given a unique identifier. This exception is thrown when the identifier of the class is not equal to the identifier of the flattened object. If you really think about it, the exception is thrown because of the addition of the new field. You can avoid this exception being thrown by controlling the versioning yourself by declaring an explicit serialVersionUID. There is also a small performance benefit in explicitly declaring your serialVersionUID (because does not have to be calculated). So, it is best practice to add your own serialVersionUID to your Serializable classes as soon as you create them as shown below:

public class Car {
      static final long serialVersionUID = 1L; //assign a long value
}

Q6. Is it possible that class fields/members are not written to stream in the serialization process?
Ans. There are three exceptions in which serialization doesn't necessarily read and write to the stream. These are
1. Serialization ignores static fields, because they are not part of any particular state.
2. Base class fields are only handled if the base class itself is serializable.
3. Transient fields.

Q7. What happens to the object references included in the object during serialization process?
Ans. The serialization mechanism generates an object graph for serialization. Thus it determines whether the included object references are serializable or not. This is a recursive process. Thus when an object is serialized, all the included objects are also serialized along with the original object.

NOTE: One should make sure that all the included objects are also serializable. If any of the objects is not serializable then it throws a NotSerializableException.

Q8. What is Externalizable interface?
Ans. Basically SERIALIZABLE uses default implementation for reading and writing the object you want to persist.  You just have to implement SERIALIZABLE interface for your class and rest will be taken care. Java runtime will use reflection to figure out how to marshal and unmarshal your objects.

Thus, if you want to have control over how to read and write objects, you can use Externalizable interface. This contains two methods readExternal and writeExternal
which you will need to implement with your own way of storing the information and retrieving the information of the object. These methods give you a control over the serialization mechanism. Thus if your class implements this interface, you can customize the serialization process by implementing these methods.

Q9. Why do we need Externalizable interface? Can't we override writeObject method?
Ans. writeObject() method is defined in ObjectOutputStream class and is declared as final. Hence, you can't override writeObject() method. Similar is the case with readObject() method, which is defined in ObjectInputStream class and also declared as final. Thus, to have control over the serialization process, you need to implement Externalizable interface and define the writeExternal() and readExternal() methods.

Q10. When should we use Externalizable interface?
Ans.  We should use it when it is required to have control over serialization process. Unless you have very specific requirements one wouldn't use EXTERNALIZABLE. 

In earlier version of Java, reflection was very slow, and so serializing large object graphs (e.g. in client-server RMI applications) was a bit of a performance problem. To handle this situation, thejava.io.Externalizable interface was provided, which is like java.io.Serilizable but with custom-written mechanisms to perform the marshalling and unmarshalling functions. This gives you the means to get around the reflection performance bottleneck.

In recent versions of java (1.3 onwards, certainly) the performance of reflection is vastly better than it used to be, and so this is much less of a problem. 

Biggest drawback of Externalizable is that you have to maintain this logic yourself - if you add, remove or change a field in your class, you have to change your writeExternal/readExternal methods to account for it.


RMI & Proxy Design Pattern

Q11. Explain the RMI architecture.
Ans: Java Remote Method Invocation (RMI) provides a way for a Java program on one machine to communicate with objects residing in different JVMs (i.e. different processes or address spaces). The important parts of the RMI architecture are the stub class, object serialization and the skeleton class. RMI uses a layered architecture where each of the layers can be enhanced without affecting the other layers. The layers can be summarized as follows:
1. Application Layer: The client and server program.
2. Stub & Skeleton Layer: Intercepts method calls made by the client. It redirects these calls to a remote RMI service.
3. Remote Reference Layer: Sets up connections to remote address spaces, manages connections, and understands how to interpret and manage references made from clients to the remote service objects.
4. Transport layer: Based on TCP/IP connections between machines in a network. It provides basic connectivity, as well as some firewall penetration strategies.

Design pattern: RMI stub classes provide a reference to a skeleton object located in a different address space on the same or different machine. This is a typical example of a proxy design pattern (i.e. remote proxy), which makes an object executing in another JVM appear like a local object. In JDK 5.0 and later, the RMI facility uses dynamic proxies instead of generated stubs, which makes RMI easier to use.

RMI runtime steps (as shown in the diagram above) involved are:
Step 1: Start RMI registry and then RMI server. Bind the remote objects to the RMI registry.
Step 2: The client process will look up the remote object from the RMI registry.
Step 3: The lookup will return the stub to the client process from the server process.
Step 4: The client process will invoke method calls on the stub. The stub calls the skeleton on the server process through the RMI reference manager.
Step 5: The skeleton will execute the actual method call on the remote object and return the result or an exception to the client process via the RMI reference manager and the stub.

Q12. What are stubs and skeletons?
Ans.  STUB: Stub is a client side proxy; the purpose of which is marshalling the data. It acts as a proxy for remote object. The caller invokes a method on the local stub which is responsible for carrying out the method call on the remote object. In RMI, a stub for a remote object implements the same set of remote interfaces that a remote object implements.
Marshalling: It is the process of converting the java code (source code) into network oriented stream (bit-blobs stream)

SKELETON: Skeleton is a server side proxy; the purpose of which is converting the network oriented stream into java program (human readable format) i.e unmarshalling.

RMI Process
All network-related code is put in the stub and skeleton so that the client and server won't have to deal with the network and sockets in their code. The stub implements the same Remote interface (as in an interface that extends java.rmi.Remote) that the server implements. So, the client can call the same methods in the stub that it wants to call in this server. But, the functions in the stub are filled with network-related code, not the actual implementation of the required function. For example, if a server implements an add(int,int) function, the stub also will have an add(int,int) function, but it won't contain the actual implementation of the addition function; instead, it will contain the code to connect to the remote skeleton, to send details about the function to be invoked, to send the parameters, and to get the results back.
So, this will be the situation:
Client <--->stub <---> [NETWORK] <---> skeleton <---> Server

The client speaks to the stub, the stub speaks to the skeleton through the network, the skeleton speaks to the server, the server executes the required function, and the results are also passed in the same way. So, you will have four separate programs corresponding to each of these entities (this means four class files).

Later, in JDK 1.2, the skeletons were incorporated into the server itself so that there are no separate entities as skeletons. In other words, the skeletons's functionality was incorporated into the server itself. So, the scenario became like this:
Client <---> stub  <--->  [NETWORK]  <---> Server_with_skeleton_functionality

Q13. What design pattern does RMI use?
Ans. RMI. Stubs and skeletons work as proxy objects and thus RMI is based on proxy design pattern.

Q14. What is a remote object and what is RMI server?
Ans: A remote object is one whose methods can be invoked from another JVM (i.e. another process). A remote object class MUST implement the Remote interface i.e java.rmi.Remote.

A RMI Server is an application that creates a number of remote objects. An RMI Server is responsible for
1. Creating an instance of the remote object (e.g. CarImpl instance = new CarImpl()).
2. Exporting the remote object.
3. Binding the instance of the remote object to the RMI registry.

Q15. How will you pass parameters in RMI?
Ans:
1. Primitive types are passed by value (e.g. int, char, boolean etc).
2. References to remote objects (i.e. objects which implement the Remote interface) are passed as remote references that allow the client process to invoke methods on the remote objects.
3. Non-remote objects are passed by value using object serialization. These objects should allow them to be serialized by implementing the java.io.Serializable interface

The client process initiates the invocation of the remote method by calling the method on the stub. The stub (client side proxy of the remote object) has a reference to the remote object and forwards the call to the skeleton (server side proxy of the remote object) through the reference manager by marshalling the method arguments. During marshalling, each object is checked to determine whether it implements java.rmi.Remote interface. If it does then the remote reference is used as the marshalled data otherwise the object is serialized into byte streams and sent to the remote process where it is de-serialized into a copy of the local object. The skeleton converts this request from the stub into the appropriate method call on the actual remote object by un-marshalling the method arguments into local stubs on the server (if they are remote reference) or into local copy (if they are sent as serialized objects).

Q16. What are the services provided by the RMI Object?
Ans: In addition to its remote object architecture, RMI provides some basic object services, which can be used in a distributed application. These services are
1. Object naming/registry service: RMI servers can provide services to clients by registering one or more remote objects with its local RMI registry.
2. Object activation service: It provides a way for server (i.e. remote) objects to be started on an as-needed basis. Without the remote activation service, a server object has to be registered with the RMI registry service.
3. Distributed garbage collection: It is an automatic process where an object, which has no further remote references, becomes a candidate for garbage collection.


1 comment:

  1. I am hoping the same best work from you in the future as well. In fact your creative writing abilities may inspired others.
    ExtraTorrent UK proxy

    ReplyDelete