The class loader dynamically loads Java class files into JVM memory, allowing the JVM to call and execute the bytecodes in the class files

Custom class loaders

The class loader that loads the class file

1.1, classes,

There is a test.class file in the /Users/indi directory

1.2. Class loaders

import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class MyClassLoader extends ClassLoader { private String root; public String getRoot() { return root; } public void setRoot(String root) { this.root = root; } protected Class<? > findClass(String name) throws ClassNotFoundException { byte[] classData = loadClassData(name); if (classData == null) { throw new ClassNotFoundException(); } else { return defineClass(name, classData, 0, classData.length); } } private byte[] loadClassData(String className) { String fileName = root + File.separatorChar + className.replace('.', File.separatorChar) + ".class"; try { InputStream ins = new FileInputStream(fileName); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length = 0; while ((length = ins.read(buffer)) ! = -1) { baos.write(buffer, 0, length); } return baos.toByteArray(); } catch (IOException e) { e.printStackTrace(); } return null; }}Copy the code

test

public static void main(String[] args)  {
    MyClassLoader classLoader = new MyClassLoader();
    // root是类所在目录
    classLoader.setRoot("/Users/indi");

    Class<?> testClass = null;
    try {
        // test是类名称
        testClass = classLoader.loadClass("test");
        Object object = testClass.newInstance();
        System.out.println(object.getClass().getClassLoader());

        Method test = testClass.getMethod("test");
        test.invoke(object);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException | InvocationTargetException e) {
        e.printStackTrace();
    }
}
Copy the code

2. Load the class loader of the encrypted class file

2.1. Encrypt class files

import java.io.*; /** * Encrypt */ public class Encrypt {public static void main(String[] args) {Encrypt (new File("/Users/indi/test.class"),new File("/Users/indi/encrypt/test.class")); } /** * encryption algorithm * @param rsource * @param target */ public static void encrypt(File rsource,File target){FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(rsource); fos = new FileOutputStream(target); int temp = -1; while ((temp = fis.read()) ! = -1){ fos.write(temp ^ 0x98); } } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException ioException){ }finally { if(fos ! = null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if(fis ! = null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }Copy the code

2.2. Decrypt the class loader

import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class DecryptClassLoader extends ClassLoader { private String root; public DecryptClassLoader(String root){ this.root = root; } private static final String CLASS_SUFFIX = ".class"; @Override protected Class<? > findClass(String name) throws ClassNotFoundException { byte[] data = this.loadClassData(name); if (data == null) { return super.findClass(name); } return super.defineClass(name, data, 0, data.length); } public byte[] loadClassData(String className) { String filePath = getFilePath(className); ByteArrayOutputStream bos = null; try { InputStream is = new FileInputStream(filePath); bos = new ByteArrayOutputStream(); int temp = -1; while ((temp = is.read()) ! = -1) { bos.write(temp ^ 0x98); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { return bos.toByteArray(); } } private String getFilePath(String className) { return this.root + File.separatorChar + className + CLASS_SUFFIX; }}Copy the code

test

public static void main(String[] args) { DecryptClassLoader classLoader = new DecryptClassLoader("/Users/indi/encrypt");  try { Class<? > clazz = classLoader.findClass("test"); Object obj = clazz.newInstance(); Method method = clazz.getMethod("test"); method.invoke(obj); } catch (ClassNotFoundException e) { e.printStackTrace(); }catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) { e.printStackTrace(); }}Copy the code