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