Wednesday, May 11, 2016

Serialization in Java

Object Serialization in Java is a process used to convert Object into a binary format which can be persisted into disk or sent over network to any other running Java virtual machine; the reverse process of creating object from binary stream is called deserialization in Java. Java provides Serialization API for serializing and deserializing object which includes java.io.Serializable, java.io.Externalizable, ObjectInputStream and ObjectOutputStream etc.

Question 1) What is the difference between Serializable and Externalizable interface in Java?
Externalizable provides us writeExternal() and readExternal() method which gives us flexibility to control java serialization mechanism instead of relying on Java's default serialization. Correct implementation of Externalizable interface can improve performance of application drastically.

Question 2) How many methods Serializable has? If no method then what is the purpose of Serializable interface?
Serializable interface exists in java.io package and forms core of java serialization mechanism. It doesn't have any method and also called Marker Interface in Java. When your class implements java.io.Serializable interface it becomes Serializable in Java and gives compiler an indication that use Java Serialization mechanism to serialize this object.

Question 3) What is serialVersionUID? What would happen if you don't define this?
SerialVersionUID is an ID which is stamped on object when it get serialized usually hashcode of object, you can use tool serialver to see serialVersionUID of a serialized object . SerialVersionUID is used for version control of object. you can specify serialVersionUID in your class file also. Consequence of not specifying serialVersionUID is that when you add or modify any field in class then already serialized class will not be able to recover because serialVersionUID generated for new class and for old serialized object will be different. Java serialization process relies on correct serialVersionUID for recovering state of serialized object and throws java.io.InvalidClassException in case of serialVersionUID mismatch

Question 4) While serializing you want some of the members not to serialize? How do you achieve it?
Declare it either static or transient based on your need and it will not be included during Java serialization process.

Question 5) What will happen if one of the members in the class doesn't implement Serializable interface?
If you try to serialize an object of a class which implements Serializable, but the object includes a reference to an non- Serializable class then a ‘NotSerializableException’ will be thrown at runtime and

Question 6) If a class is Serializable but its super class in not, what will be the state of the instance variables inherited from super class after deserialization?
Java serialization process only continues in object hierarchy till the class is Serializable i.e. implements Serializable interface in Java and values of the instance variables inherited from super class will be initialized by calling constructor of Non-Serializable Super class during deserialization process. Once the constructor chaining will started it wouldn't be possible to stop that , hence even if classes higher in hierarchy implements Serializable interface , there constructor will be executed.

Question 7) Can you Customize Serialization process or can you override default Serialization process in Java?
The answer is yes you can. We all know that for serializing an object ObjectOutputStream.writeObject (saveThisobject) is invoked and for reading object ObjectInputStream.readObject() is invoked but there is one more thing which Java Virtual Machine provides you is to define these two method in your class. If you define these two methods in your class then JVM will invoke these two methods instead of applying default serialization mechanism. You can customize behavior of object serialization and deserialization here by doing any kind of pre or post processing task. Important point to note is making these methods private to avoid being inherited, overridden or overloaded. Since only Java Virtual Machine can call private method integrity of your class will remain and Java Serialization will work as normal. I

Question 8) Suppose super class of a new class implement Serializable interface, how can you avoid new class to being serialized?
If Super Class of a Class already implements Serializable interface in Java then its already Serializable in Java, since you can not unimplemented an interface its not really possible to make it Non Serializable class but yes there is a way to avoid serialization of new class. To avoid Java serialization you need to implement writeObject() and readObject() method in your Class and need to throw NotSerializableException from those method. This is another benefit of customizing java serialization process as described in above Serialization interview question and normally it asked as follow-up question as interview progresses.

Question 9) Which methods are used during Serialization and DeSerialization process in Java?
 Java Serialization is done by java.io.ObjectOutputStream class. That class is a filter stream which is wrapped around a lower-level byte stream to handle the serialization mechanism. To store any object via serialization mechanism we call ObjectOutputStream.writeObject(saveThisobject) and to deserialize that object we call ObjectInputStream.readObject() method. Call to writeObject() method trigger serialization process in java. one important thing to note about readObject() method is that it is used to read bytes from the persistence and to create object from those bytes and its return an Object which needs to be type cast to correct type.

Question 10) Suppose you have a class which you serialized it and stored in persistence and later modified that class to add a new field. What will happen if you deserialize the object already serialized?
It depends on whether class has its own serialVersionUID or not. As we know from above question that if we don't provide serialVersionUID in our code java compiler will generate it and normally it’s equal to hashCode of object. by adding any new field there is chance that new serialVersionUID generated for that class version is not the same of already serialized object and in this case Java Serialization API will throw java.io.InvalidClassException and this is the reason its recommended to have your own serialVersionUID in code and make sure to keep it same always for a single class.

11) What are the compatible changes and incompatible changes in Java Serialization Mechanism?
The real challenge lies with change in class structure by adding any field, method or removing any field or method is that with already serialized object. As per Java Serialization specification adding any field or method comes under compatible change and changing class hierarchy or UN-implementing Serializable interfaces some under non compatible changes. For complete list of compatible and non compatible changes I would advise reading Java serialization specification.

12) Can we transfer a Serialized object vie network?
Yes you can transfer a Serialized object via network because Java serialized object remains in form of bytes which can be transmitter via network. You can also store serialized object in Disk or database as Blob.

Friday, April 1, 2016

Solid Principles in Java

                                   Solid Principles in Java


Classes are the building blocks of your java application. If these blocks are not strong, your building (i.e. application) is going to face the tough time in future. This essentially means that not so well-written can lead to very difficult situations when the application scope goes up or application faces certain design issues either in production or maintenance.

A set of well designed and written classes can speed up the coding process by leaps and bounds, while reducing the number of bugs in comparison.

Solid Definition

S ---->Single Responsibility Principle
0 ---> Open Closed Principle
L ---> Liskov's Substitution Principle
I --->  Interface Segregation Principle
D ---> Dependency Inversion Principle

Single Responsibility Principle :-  "One class should have one and only one responsibility".

In other words, you should write, change and maintain a class for only one purpose. If it is model class then it should strictly represent only one actor/ entity. This will give you the flexibility to make changes in future without worrying the impacts of changes for another entity.

Similarly, If you are writing service/manager class then it should contain only that part of method calls and nothing else. Not even utility global functions related to module. Better separate them in another globally accessible class file. This will help in maintaining the class for that particular purpose, and you can decide the visibility of class to specific module only.

Open Closed Principle :- "Software components should be open for extension, but closed for modification".

your classes should be designed such a way that whenever fellow developers wants to change the flow of control in specific conditions in application, all they need to extend your class and override some functions and that’s it.If other developers are not able to design desired behavior due to constraints put by your class, then you should reconsider changing your class. Other Developers should be able to override the options provided by software in unharmful way permitted by software.

For example, if you take a look into any good framework like struts or spring, you will see that you can not change their core logic and request processing, BUT you modify the desired application flow just by extending some classes and plugin them in configuration files.

Liskov’s Substitution Principle :- "Derived types must be completely substitutable for their base types".

It means that the classes fellow developer created by extending your class should be able to fit in application without failure. I.e. if a fellow developer poorly extended some part of your class and injected into framework/ application then it should not break the application or should not throw fatal exceptions.

This can be insured by using strictly following first rule. If your base class is doing one thing strictly, the fellow developer will override only one feature incorrectly in worst case. This can cause some errors in one area, but whole application will not do down.

Interface Segregation Principle :- "Clients should not be forced to implement unnecessary methods which they will not use"

Take an example. Developer Tiger created an interface Reportable and added two methods generateExcel() and generatedPdf(). Now client ‘A’ wants to use this interface but he intend to use reports only in PDF format and not in excel. Will he achieve the functionality easily.

NO. He will have to implement two methods, out of which one is extra burden put on him by designer of software. Either he will implement another method or leave it blank. So are not desired cases, right??

So what is the solution? Solution is to create two interfaces by breaking the existing one. They should be like PdfReportable and ExcelReportable. This will give the flexibility to user to use only required functionality only.

Dependency Inversion Principle :- "Depend on abstractions, not on concretions"

you should design your software in such a way that various modules can be separated from each other using an abstract layer to bind them together. The classical use of this principle of BeanFactory in spring framework. In spring framework, all modules are provided as separate components which can work together by simply injected dependencies in other module. They are so well closed in their boundaries that you can use them in other software modules apart from spring with same ease.

This has been achieved by dependency inversion and open closed principles. All modules expose only abstraction which is useful in extending the functionality or plugin in another module.

Thursday, March 17, 2016

How to read File into String in Java 7

Before Java 7, you have to write lot of code e.g. open an input stream, convert that input stream into a Reader, and then wrap that into a BufferedReader and so on. Of course, JDK 1.5's Scanner class did provide some API but it was not so simple like we have in python.

Whenever you convert binary data into text data, you must remember to use correct character encoding. An incorrect choice of character encoding may result in totally different or slightly different content than the original file.

Before JDK 1.7 we used to read file


InputStream inputStream = new FileInputStream("abc.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
      
String line = br.readLine();
StringBuilder sb = new StringBuilder();
      
while(line != null){
   sb.append(line).append("\n");
   line = br.readLine();
}
      
String fileAsString = sb.toString();
System.out.println("File data is : " + fileAsString);

From JDK 1.7

String fileData = new String(Files.readAllBytes(Paths.get("abc.txt")));
System.out.println("FileData  : " + fileData);

The above code uses platform's default character encoding. If you want you can use your own/custom character encoding.

 How to provide a custom character encoding 


 String fileData = new String(Files.readAllBytes(Paths.get("abc.txt")), StandardCharsets.UTF_8);
 System.out.println("FileData  : " + fileData);

Wednesday, February 17, 2016

How to Upload files through your application (Getting rid of fakepath)

Some browsers have a security feature that prevents JavaScript from knowing your file's local full path. It makes sense  as a client, you don't want the server to know your local machine's filesystem.Now when you browse a file from your local system you get the file name instead of File whole path. This results in many applications giving error as File Not Found.

Just create a Dynamic Web project from your IDE
You can use apache commons-fileupload-1.3.jar and commons-io-2.2.jar, Now create a Index.html

Index.html

Now create a Servlet named FileServlet

FileServlet

public class FileServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    private ServletFileUpload uploader = null;
  
    /**
     * @see HttpServlet#HttpServlet()
     */
    public FileServlet () {
    super();
    // TODO Auto-generated constructor stub
    }
   
    @Override
    public void init() throws ServletException{
    DiskFileItemFactory fileFactory = new DiskFileItemFactory();
    File filesDir = (File) getServletContext().getAttribute("FILES_DIR_FILE");
    fileFactory.setRepository(filesDir);
    this.uploader = new ServletFileUpload(fileFactory);
    uploadFileAction = new UploadFileAction();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String fileName = request.getParameter("fileName");
    String name = request.getParameter("username");
    if(fileName == null || fileName.equals("")){
    throw new ServletException("File Name can't be null or empty");
     }
    File file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileName);
    if(!file.exists()){
    throw new ServletException("File doesn't exists on server.");
    }
    System.out.println("File location on server::"+file.getAbsolutePath());
    }
   
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("request.getContentType()\t"+request.getContentType());
    if(!ServletFileUpload.isMultipartContent(request)){
    throw new ServletException("Content type is not multipart/form-data");
    }

    //String name = request.getParameter("name");
    String name = request.getParameter("username");
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    try {
    List fileItemsList = uploader.parseRequest(request);
    Iterator fileItemsIterator = fileItemsList.iterator();
    File file = null;
    FileItem fileItem = null;
    while(fileItemsIterator.hasNext()){
    fileItem = fileItemsIterator.next();
    if(fileItem.getName() != null){
    System.out.println("FieldName="+fileItem.getFieldName());
    System.out.println("FileName="+fileItem.getName());
    System.out.println("ContentType="+fileItem.getContentType());
    System.out.println("Size in bytes="+fileItem.getSize());

    if(fileItem.getName().contains("/") || fileItem.getName().contains("\\")){
    String fileName = FilenameUtils.getName(fileItem.getName());
    System.out.println(fileName);
    file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileName);
    }
    else{
    file = new File(request.getServletContext().getAttribute("FILES_DIR")+File.separator+fileItem.getName());
    }

    System.out.println("Absolute Path at server="+file.getAbsolutePath());
    fileItem.write(file);
    out.write("File "+fileItem.getName()+ " uploaded successfully.");
    }
    if(fileItem.getName() != null){
    System.out.println("resp\t"+resp);
    System.out.println("File "+fileItem.getName();
    out.println("success");
    }
    }
    } catch (FileUploadException e) {
    e.printStackTrace();
    } catch (Exception e) {
    e.printStackTrace();
    }

}
    }


Now create Listener named FileLocationContextListener

FileLocationContextListener

@WebListener
public class FileLocationContextListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent servletContextEvent) {
        String rootPath = System.getProperty("catalina.home");
        ServletContext ctx = servletContextEvent.getServletContext();
        String relativePath = ctx.getInitParameter("tempfile.dir");
        File file = new File(rootPath + File.separator + relativePath);
        if(!file.exists()) file.mkdirs();
        System.out.println("File Directory created to be used for storing files");
        ctx.setAttribute("FILES_DIR_FILE", file);
        ctx.setAttribute("FILES_DIR", rootPath + File.separator + relativePath);
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        //do cleanup if needed
    }
   
}

web.xml




When you run this program a tmpfiles directory is created in your tomcat server and then file that you browsed through your application gets copied to this location.
from your servlet when you do file.getAbsolutePath() you get the full path of your file.
Now you can easily upload it to your Database or read it as per your requirements

Tuesday, January 12, 2016

Codes for Data Type as per BSON Specifications

As we know MongoDb is document oriented Database so what actually means is Mongodb fundamentally record type is kind of nested dictionary of key value associations. We Map the documents that come out of Mongo Db to Objects in the Programming language that can represent these type of key value associations.

In Javascript, the type of Object that represents these kinds of key value associations is called a Javascript Object. MongoDB uses a binary representation for the data inside the document.
The specification for Binary representation can be find out at  http://bsonspec.org/

The Binary format BSON stands for Binary JSON and it is a serialized format that designed to represent a super set of what can be described in JSON syntax

Now for example you have a collection as people which has a column as name and the user has stored some integer values also in that name field. you want to query the people document to find the name but don't want to display the result having name field with value as integer

db.people.find({name:{$type:2}})
This will fetch you the name from people collection  which are of String type. here the value 2 is mapped for String datatype.

Similar for other datatype has been mapped to some integer value. Here is an list of all Datatype which are mapped to a particular Integer type as per BSON specifications