Skip to content

Instantly share code, notes, and snippets.

@serkan-ozal
Created November 24, 2016 17:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save serkan-ozal/8737583841b4b12e3a42d39d4af051ae to your computer and use it in GitHub Desktop.
Save serkan-ozal/8737583841b4b12e3a42d39d4af051ae to your computer and use it in GitHub Desktop.
ClassCopyDemo
import java.lang.reflect.Field;
import sun.misc.Unsafe;
import javassist.ClassPool;
import javassist.CtClass;
public class ClassCopyDemo {
/*
<!-- Javassist dependency -->
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.17.1-GA</version>
</dependency>
*/
private static final Unsafe UNSAFE;
static {
try {
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
UNSAFE = (Unsafe) unsafeField.get(null);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Unable to get unsafe", e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unable to get unsafe", e);
}
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
Class<?> copyFooClass = copyClass(Foo.class);
Incrementer fooInstance = Foo.class.newInstance();
Incrementer copyFooInstance = (Incrementer) copyFooClass.newInstance();
System.out.println(fooInstance.getClass() + ".increment(int x): " + fooInstance.increment(1));
System.out.println(copyFooInstance.getClass() + ".increment(int x): " + copyFooInstance.increment(1));
System.out.println(fooInstance.getClass() + " == " + copyFooInstance.getClass() + ": " +
fooInstance.getClass().equals(copyFooInstance.getClass()));
}
private static Class<?> copyClass(Class<?> classToBeCopied) {
try {
String copyClassName = classToBeCopied.getName() + "$Copy";
ClassPool cp = ClassPool.getDefault();
CtClass ctClass = cp.getAndRename(classToBeCopied.getName(), copyClassName);
byte[] bytecode = ctClass.toBytecode();
return UNSAFE.defineClass(
copyClassName,
bytecode,
0,
bytecode.length,
classToBeCopied.getClassLoader(),
classToBeCopied.getProtectionDomain());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public interface Incrementer {
int increment(int x);
}
public static class Foo implements Incrementer {
@Override
public int increment(int x) {
return x + 1;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment