package kr.debop4j.core.reflect; import com.carrotsearch.junitbenchmarks.BenchmarkOptions; import kr.debop4j.core.AbstractTest; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; /** * kr.debop4j.core.reflect.ClassLoaderTest * * @author 배성혁 ( sunghyouk.bae@gmail.com ) * @since 13. 1. 21 */ @Slf4j public class ClassLoaderTest extends AbstractTest { static public class TestClass { public String name; public String toString() { return name; } } private static final String testClassName = "kr.debop4j.core.reflect.ClassLoaderTest$TestClass"; @BenchmarkOptions(benchmarkRounds = 100, warmupRounds = 1) @Test public void differentClassLoader() throws Exception { ClassLoader testClassLoader = new ClassLoader() { @Override protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { Class c = findLoadedClass(name); if (c != null) return c; if (name.startsWith("java.")) return super.loadClass(name, resolve); if (!name.equals(testClassName)) throw new ClassNotFoundException("Class not found on purpose: " + name); ByteArrayOutputStream output = new ByteArrayOutputStream(32 * 1024); InputStream input = ClassLoaderTest.class.getResourceAsStream("/" + name.replace('.', '/') + ".class"); if (input == null) return null; try { byte[] buffer = new byte[4096]; int total = 0; while (true) { int length = input.read(buffer, 0, buffer.length); if (length == -1) break; output.write(buffer, 0, length); } } catch (IOException ex) { throw new ClassNotFoundException("Error reading class file.", ex); } finally { try { input.close(); } catch (IOException ignored) { } } byte[] buffer = output.toByteArray(); return defineClass(name, buffer, 0, buffer.length); } }; Class testClass = testClassLoader.loadClass(testClassName); Object testObject = testClass.newInstance(); Assert.assertNotNull(testObject); FieldAccess access = FieldAccess.get(testObject.getClass()); access.set(testObject, "name", "first"); Assert.assertEquals("first", testObject.toString()); Assert.assertEquals("first", access.get(testObject, "name")); } }