-
Notifications
You must be signed in to change notification settings - Fork 0
/
LoadClass.java
57 lines (48 loc) · 2.24 KB
/
LoadClass.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package org.mtokarski.unsafe;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.ProtectionDomain;
/**
* To load class safely add -Dsafe=true to VM arguments
*/
public class LoadClass {
public static void main(String[] args) throws IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
String className = "com.example.MessageClass";
try {
LoadClass.class.getClassLoader().loadClass(className);
} catch (ClassNotFoundException e) {
System.out.println("Class " + className + " not found");
System.out.println();
}
byte[] classBytes = Files.readAllBytes(Paths.get("./resources/MessageClass.class"));
Class<?> messageClass = defineClass(className, classBytes, LoadClass.class.getClassLoader());
System.out.println(messageClass + " loaded!");
System.out.println();
Object message = messageClass.getConstructor().newInstance();
System.out.println(message);
Method setMessage = messageClass.getDeclaredMethod("setMessage", String.class);
setMessage.invoke(message, "It works! Method was invoked.");
System.out.println(message);
}
private static Class<?> defineClass(String name, byte[] bytes, ClassLoader classLoader) {
if ("true".equals(System.getProperty("safe"))) {
final InternalClassLoader internalClassLoader = new InternalClassLoader(classLoader);
return internalClassLoader.defineClass(name, bytes, null);
} else {
System.out.println("Using unsafe to load class");
System.out.println();
return UnsafeUtil.unsafe.defineClass(name, bytes, 0, bytes.length, classLoader, null);
}
}
private static class InternalClassLoader extends ClassLoader {
InternalClassLoader(ClassLoader classLoader) {
super(classLoader);
}
public Class<?> defineClass(String name, byte[] bytes, ProtectionDomain protectionDomain) {
return defineClass(name, bytes, 0, bytes.length, protectionDomain);
}
}
}