The Java ClassLoader defineClass() method converts an array of bytes into an instance of the Class class. A default ProtectionDomain is assigned to the current defined class by the defineClass() method.

When a class is defined, the JVM assigns it a ProtectionDomain to determine what the class is allowed to do, such as read or write files.

Syntax

Declaration for java.lang.ClassLoader.defineClass() method is as given below:

defineClass(String name, byte[] b, int off, int len)

Parameters

The java.lang.ClassLoader.defineClass() method accepts the following parameters:

  • name: It is a String which is the expected binary name of the class. It can also be null.

  • b: It is a byte array that contains the class data (means bytecode).

  • off: An integer value that specifies the start offset in the byte array.

  • len: It is also an integer that shows the length of the class data in bytes.

Return Value

This method returns an object that represents the newly defined class.

Exception

The list of exceptions thrown by java.lang.ClassLoader.defineClass() method:

  • ClassFormatError: This exception occurs if the data does not contain a valid class.

  • IndexOutOfBoundsException: If off or len is negative, or if sum of off and len exceeds the length of the byte array.

  • SecurityException: Thrown if a security manager is present and it denies access to define the class.

Example: Defining a Class from Bytecode

Following Java program shows the use of defineClass() method. You need to create a Java class and compile that class to generate bytecode. Then, pass the path of that bytecode in the program as shown below:

import java.io.*;

public class MyClassLoader extends ClassLoader {
   public Class<?> loadMyClass(String classFilePath) throws IOException {
      byte[] classData = readClassFile(classFilePath);
      return defineClass(null, classData, 0, classData.length);
   }

   private byte[] readClassFile(String classFilePath) throws IOException {
	  // pass the path of java class
      File file = new File("D:/Java Programs/Add.class");
      FileInputStream fis = new FileInputStream(file);
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      byte[] buffer = new byte[1024];
      int bytesRead;
      while ((bytesRead = fis.read(buffer)) != -1) {
          bos.write(buffer, 0, bytesRead);
      }
      fis.close();
      return bos.toByteArray();
   }

   public static void main(String[] args) {
      System.out.println("Custom ClassLoader Example");

      MyClassLoader myClassLoader = new MyClassLoader();
	  // pass the path of java class
      String classFilePath = "D:/Java Programs/Add.class"; 

      try {
         Class<?> loadedClass = myClassLoader.loadMyClass(classFilePath);
         System.out.println("Class Loaded: " + loadedClass.getName());
      } catch (Exception e) {
         System.out.println("Error loading class: " + e.getMessage());
      }
   }
}

Output

Compile and run the above program in your local machine, this will produce the following result −

Custom ClassLoader Example
Class Loaded: Add
java_lang_classloader.htm
Advertisements