Skip to content

Instantly share code, notes, and snippets.

@andrewromanenco
Created November 17, 2016 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andrewromanenco/290b6b4ad8111496eebf36f8e1e991f3 to your computer and use it in GitHub Desktop.
Save andrewromanenco/290b6b4ad8111496eebf36f8e1e991f3 to your computer and use it in GitHub Desktop.
Demo for defining class loaders in Java
import static java.lang.System.out;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Demo code for http://www.romanenco.com/defining-class-loader-java
* Compile and run from command line:
* javac CLoaderExample.java
* java -cp . CLoaderExample
*/
public class CLoaderExample {
public static void main(String[] args) throws Exception {
out.println("With delegation");
/*
* Note
* dlc will receive only one call for loadClass
* and class loader of Custom is system one
*/
final DelegatingCL dcl = new DelegatingCL();
Class<?> c = dcl.loadClass("Custom");
out.println("Class loader of C: " + c.getClassLoader());
Class<?> cParent = c.getSuperclass();
out.println("Class loader of super: " + cParent.getClassLoader());
out.println("With interception");
/*
* Note
* icl receives loadclass call twice, for Custom and it's parent (java.lang.Object)
* Class loader of Custom is icl
* Class loader of Object - null - this means bootstrap.
*/
final InterceptingCL icl = new InterceptingCL();
Class<?> d = icl.loadClass("Custom");
out.println("Class loader of C: " + d.getClassLoader());
Class<?> dParent = d.getSuperclass();
out.println("Class loader of super: " + dParent.getClassLoader());
}
}
/**
* Delegating class loader does not make any resolutions, just print calls.
*/
class DelegatingCL extends ClassLoader {
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
out.println("CLoader.loadClass(s, b): " + name + ", " + resolve);
return super.loadClass(name, resolve);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
out.println("CLoader.findClass(s): " + name);
return super.findClass(name);
}
}
/**
* This class loader delegates to parent all calls, other than for class Custom.
*/
class InterceptingCL extends ClassLoader {
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
out.println("CLoader.loadClass(s, b): " + name + ", " + resolve);
if (name.equals("Custom")) {
return readAndDefine(name);
}
return super.loadClass(name, resolve);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
out.println("CLoader.findClass(s): " + name);
return super.findClass(name);
}
private Class<?> readAndDefine(String name) {
Path path = Paths.get(name + ".class");
byte[] data;
try {
data = Files.readAllBytes(path);
} catch (IOException e) {
throw new RuntimeException("Can't read file", e);
}
return defineClass(name, data, 0, data.length);
}
}
class Custom {
public static final int I = 99;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment