https://github.com/hellyguo/inmemclassloaddemo
demo for loading classes in memory
https://github.com/hellyguo/inmemclassloaddemo
classloading demo jdk11 jdk17 jdk8
Last synced: 4 months ago
JSON representation
demo for loading classes in memory
- Host: GitHub
- URL: https://github.com/hellyguo/inmemclassloaddemo
- Owner: hellyguo
- License: mit
- Created: 2024-11-11T02:35:26.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-12-07T06:13:35.000Z (about 1 year ago)
- Last Synced: 2024-12-07T07:18:58.105Z (about 1 year ago)
- Topics: classloading, demo, jdk11, jdk17, jdk8
- Language: Java
- Homepage:
- Size: 59.6 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Demo: Loading classes in memory
[δΈζη](README_cn.md)
## jdk8
### use `ClassLoader#defineClass`
1. define a class loader, extends `URLClassLoader`
2. define a new public method, call `defineClass` indirectly
```java
public Class> loadClassFromBytes(String className, byte[] bytes) {
return this.defineClass(className, bytes, 0, bytes.length);
}
```
### use `Unsafe#defineAnonymousClass`
> need to use `sun.misc.Unsafe`, which is not recommended
```java
public Class> loadClass(String className, byte[] classBytes) {
return UNSAFE.defineAnonymousClass(SimTarget.class, classBytes, EMPTY_OBJECTS);
}
```
## jdk11
### use `ClassLoader#defineClass`
same as `jdk8`
### use `Unsafe#defineAnonymousClass`
> need to use jvm argument: `--add-exports java.base/jdk.internal.misc=`
```java
public Class> loadClass(String className, byte[] classBytes) {
return UNSAFE.defineAnonymousClass(AnonClassHolder.class, classBytes, EMPTY_OBJECTS);
}
```
## jdk17
### use `ClassLoader#defineClass`
same as `jdk8`
### use `MethodLookup#defineHiddenClass`
> need to let the hidden class and the holder class in the same package!
```java
public static Class> loadClass(String className, byte[] classBytes) {
if (!className.startsWith(PACKAGE_NAME)) {
throw new RuntimeException("not same package, should failed");
}
try {
MethodHandles.Lookup lookup = MethodHandles.lookup();
return lookup.defineHiddenClass(classBytes, true,
MethodHandles.Lookup.ClassOption.NESTMATE,
MethodHandles.Lookup.ClassOption.STRONG)
.lookupClass();
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
```
## HowTo
1. (`optional`) cd `demo-inmem-base`
2. (`optional`) compile
```shell
mvn package -Dmaven.test.skip=true
# or
mvnd package -Dmaven.test.skip=true
```
3. (`optional`) call `class2bytes.sh`, generate the Java file, which is hold bytes.
4. test in `demo-inmem-jdk8`/`demo-inmem-jdk11`/`demo-inmem-jdk17`