Created
November 24, 2016 17:08
-
-
Save serkan-ozal/8737583841b4b12e3a42d39d4af051ae to your computer and use it in GitHub Desktop.
ClassCopyDemo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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