Monday, 10 June 2019

Java: Custom Class Loader


In this post, I am going to explain how to load a class from .class file using custom class loader.

Developing custom class loader
Step 1: Extend ‘ClassLoader’ class.
public class FileClassLoader extends ClassLoader {
 private ClassLoader parentClassLoader;

 public FileClassLoader() {
  this(ClassLoader.getSystemClassLoader());
 }

 public FileClassLoader(ClassLoader parentClassLoader) {
  super(parentClassLoader);
  this.parentClassLoader = parentClassLoader;
 }

 .....
 .....
 .....
}

Step 2: Override ‘findClass’method.
protected Class<?> findClass(String classFilePath) throws ClassNotFoundException {
 try {
  return parentClassLoader.loadClass(classFilePath);
 } catch (ClassNotFoundException e) {
  System.out.println("Class is not found by parent class loader");
  File file = new File(classFilePath);
  byte bytes[] = getByteArray(new File(classFilePath));
  
  return this.defineClass(null, bytes, 0, bytes.length);
 }

}


FileClassLoader.java
package com.sample.app.classloader;

/**
 * Loads the class file
 *
 */
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileClassLoader extends ClassLoader {
 private ClassLoader parentClassLoader;

 public FileClassLoader() {
  this(ClassLoader.getSystemClassLoader());
 }

 public FileClassLoader(ClassLoader parentClassLoader) {
  super(parentClassLoader);
  this.parentClassLoader = parentClassLoader;
 }

 private static byte[] getByteArray(File file) {

  byte[] bytes = new byte[(int) file.length()];

  try (DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file));) {
   dataInputStream.readFully(bytes);
   return bytes;
  } catch (FileNotFoundException e) {
   return null;
  } catch (IOException e) {
   return null;
  }

 }

 protected Class<?> findClass(String classFilePath) throws ClassNotFoundException {
  try {
   return parentClassLoader.loadClass(classFilePath);
  } catch (ClassNotFoundException e) {
   System.out.println("Class is not found by parent class loader");
   File file = new File(classFilePath);
   byte bytes[] = getByteArray(new File(classFilePath));
   
   return this.defineClass(null, bytes, 0, bytes.length);
  }

 }

}

Step 2: Define Employee.java.

Employee.java
package com.sample.demoapp.model;

public class Employee {

 public String toString() {
  return "Represent Employee Information";
 }
}


App.java
package com.sample.app;

import com.sample.app.classloader.FileClassLoader;

public class App {

 public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
  ClassLoader classLoader = new FileClassLoader();
  
  Class clazz = classLoader.loadClass("/Users/krishna/Documents/com/sample/demoapp/model/Employee.class");
  
  Object obj = clazz.newInstance();
  
  System.out.println(obj);
 }
}

Output
Class is not found by parent class loader
Represent Employee Information




Previous                                                 Next                                                 Home

No comments:

Post a Comment