diff options
author | chibash <chiba@javassist.org> | 2018-09-08 15:47:38 +0900 |
---|---|---|
committer | chibash <chiba@javassist.org> | 2018-09-08 15:47:38 +0900 |
commit | 6320bc4e14350af392b285b1b1ea312673625b21 (patch) | |
tree | 8fd478f2baa4bd75048432ed3474d383131f5f04 /src/test | |
parent | 0958148acbb1b737ca90f78670a4d13c6f321416 (diff) | |
download | javassist-6320bc4e14350af392b285b1b1ea312673625b21.tar.gz javassist-6320bc4e14350af392b285b1b1ea312673625b21.zip |
changes CtClass#toClass() and ClassPool#toClass() etc. to support Java 11,
in other words, java.lang.invoke.MethodHandles.Lookup.
Diffstat (limited to 'src/test')
19 files changed, 197 insertions, 414 deletions
diff --git a/src/test/DefineClassCapability.java b/src/test/DefineClassCapability.java new file mode 100644 index 00000000..c6dec200 --- /dev/null +++ b/src/test/DefineClassCapability.java @@ -0,0 +1,5 @@ +/* + * This is used as a capability for running CtClass#toClass(). + */ +public class DefineClassCapability { +} diff --git a/src/test/javassist/JvstTest.java b/src/test/javassist/JvstTest.java index e2f9211f..aab0b907 100644 --- a/src/test/javassist/JvstTest.java +++ b/src/test/javassist/JvstTest.java @@ -1,6 +1,8 @@ package javassist; import junit.framework.*; +import test1.DefineClassCapability; + import java.io.File; import java.io.FileInputStream; import java.io.InputStream; @@ -743,8 +745,8 @@ public class JvstTest extends JvstTestRoot { ctInterface.stopPruning(true); ctInterface.writeFile(); - ctInterface.toClass(); - targetCtClass.toClass(); + ctInterface.toClass(DefineClassCapability.class); + targetCtClass.toClass(DefineClassCapability.class); } public void testDispatch() throws Exception { @@ -1161,6 +1163,7 @@ public class JvstTest extends JvstTestRoot { suite.addTestSuite(javassist.SetterTest.class); suite.addTestSuite(javassist.bytecode.InsertGap0.class); suite.addTestSuite(javassist.tools.reflect.LoaderTest.class); + suite.addTestSuite(javassist.tools.CallbackTest.class); suite.addTestSuite(testproxy.ProxyTester.class); suite.addTestSuite(testproxy.ProxyFactoryPerformanceTest.class); // remove? suite.addTestSuite(javassist.proxyfactory.ProxyFactoryTest.class); diff --git a/src/test/javassist/JvstTest2.java b/src/test/javassist/JvstTest2.java index 117560c0..0ea4571b 100644 --- a/src/test/javassist/JvstTest2.java +++ b/src/test/javassist/JvstTest2.java @@ -9,6 +9,7 @@ import org.junit.runners.MethodSorters; import java.lang.reflect.Method; import javassist.expr.*; +import test2.DefineClassCapability; @SuppressWarnings({"rawtypes","unused"}) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @@ -709,7 +710,7 @@ public class JvstTest2 extends JvstTestRoot { public void testToClass() throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass cc = cp.makeClass("test2.ToClassTest"); - Class c = cc.toClass(); + Class c = cc.toClass(DefineClassCapability.class); assertEquals(getClass().getClassLoader(), c.getClassLoader()); } diff --git a/src/test/javassist/JvstTest3.java b/src/test/javassist/JvstTest3.java index 47131a93..46f06b16 100644 --- a/src/test/javassist/JvstTest3.java +++ b/src/test/javassist/JvstTest3.java @@ -340,7 +340,7 @@ public class JvstTest3 extends JvstTestRoot { System.out.println("Num Annotation : " +ans.length); // c.debugWriteFile(); - Class newclass = c.toClass(); + Class newclass = c.toClass(DefineClassCapability.class); java.lang.annotation.Annotation[] anns = newclass.getAnnotations(); System.out.println("Num NewClass Annotation : " +anns.length); assertEquals(ans.length, anns.length); @@ -737,7 +737,7 @@ public class JvstTest3 extends JvstTestRoot { CtMethod m2 = cc2.getDeclaredMethod("getX"); copyAnnotations(m1, m2); cc2.getClassFile(); - Class clazz = cc2.toClass(); + Class clazz = cc2.toClass(DefineClassCapability.class); java.lang.reflect.Method m = clazz.getDeclaredMethod("getX", new Class[0]); assertEquals(1, m.getAnnotations().length); test3.VisibleAnno a = m.getAnnotation(test3.VisibleAnno.class); @@ -790,7 +790,7 @@ public class JvstTest3 extends JvstTestRoot { cc.addField(fobj, CtField.Initializer.constant("bar")); cc.writeFile(); - Class clazz = cc.toClass(); + Class clazz = cc.toClass(DefineClassCapability.class); assertEquals(2L, clazz.getField("j").getLong(null)); assertEquals(3, clazz.getField("i").getInt(null)); assertEquals(4, clazz.getField("s").getShort(null)); @@ -1108,7 +1108,7 @@ public class JvstTest3 extends JvstTestRoot { sb.append("}"); ctc.addMethod(CtNewMethod.make(sb.toString(), ctc)); ctc.debugWriteFile(); - ctc.toClass().getConstructor().newInstance(); + ctc.toClass(DefineClassCapability.class).getConstructor().newInstance(); } // JIRA-83 diff --git a/src/test/javassist/JvstTest4.java b/src/test/javassist/JvstTest4.java index 187abb3d..7c8c7457 100644 --- a/src/test/javassist/JvstTest4.java +++ b/src/test/javassist/JvstTest4.java @@ -1054,7 +1054,7 @@ public class JvstTest4 extends JvstTestRoot { addDeadCode(newClass, "public boolean evaluate7(){ return !true; }"); newClass.debugWriteFile(); - Class<?> cClass = newClass.toClass(); + Class<?> cClass = newClass.toClass(test4.DefineClassCapability.class); Object o = cClass.getConstructor().newInstance(); java.lang.reflect.Method m = cClass.getMethod("evaluate"); m.invoke(o); @@ -1112,6 +1112,7 @@ public class JvstTest4 extends JvstTestRoot { attr.setAnnotation(a); m.getMethodInfo().addAttribute(attr); cc.writeFile(); + anno.toClass(test4.DefineClassCapability.class); Class<?> rc = ((java.lang.annotation.Annotation)m.getAnnotations()[0]).annotationType(); assertEquals(anno.getName(), rc.getName()); } diff --git a/src/test/javassist/JvstTest5.java b/src/test/javassist/JvstTest5.java index ec8ff66a..c5eff4d1 100644 --- a/src/test/javassist/JvstTest5.java +++ b/src/test/javassist/JvstTest5.java @@ -223,7 +223,7 @@ public class JvstTest5 extends JvstTestRoot { "}"); System.out.println(src); badClass.addMethod(CtMethod.make(src, badClass)); - Class clazzz = badClass.toClass(); + Class clazzz = badClass.toClass(Class.forName("DefineClassCapability")); Object obj = clazzz.getConstructor().newInstance(); // <-- falls here } @@ -451,6 +451,6 @@ public class JvstTest5 extends JvstTestRoot { public void testNestHostAttributeCopy() throws Exception { CtClass cc = sloader.get("test5.NestHost2$Foo"); cc.getClassFile().compact(); - cc.toClass(); + cc.toClass(test5.DefineClassCapability.class); } } diff --git a/src/test/javassist/SetterTest.java b/src/test/javassist/SetterTest.java index 44eec140..a76b2a30 100644 --- a/src/test/javassist/SetterTest.java +++ b/src/test/javassist/SetterTest.java @@ -1,112 +1,114 @@ -package javassist;
-import java.lang.reflect.Method;
-
-import junit.framework.TestCase;
-
-@SuppressWarnings({"rawtypes","unchecked"})
-public class SetterTest extends TestCase {
-
- ClassPool pool;
-
- public SetterTest(String name) {
- super(name);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- pool = ClassPool.getDefault();
- }
-
- /**
- * Tests a getter only on a field without a Modifier.
- *
- * @throws Exception
- */
- public void testFieldGetter() throws Exception {
- CtClass clazz = pool.makeClass("HasFieldGetter");
- clazz.setSuperclass(pool.get("java.lang.Object"));
- CtField field = new CtField(CtClass.booleanType, "broken", clazz);
- clazz.addField(field, "true");
- clazz.addMethod(CtNewMethod.getter("isBroken", field));
- Class _class = clazz.toClass();
-
- Object object = _class.getConstructor().newInstance();
- check(_class, object, true);
- }
-
- /**
- * Tests a getter and a setter on a field without a Modifier.
- *
- * @throws Exception
- */
- public void testFieldGetterSetter() throws Exception {
- CtClass clazz = pool.makeClass("HasFieldGetterSetter");
- clazz.setSuperclass(pool.get("java.lang.Object"));
- CtField field = new CtField(CtClass.booleanType, "broken", clazz);
- clazz.addField(field, "true");
- clazz.addMethod(CtNewMethod.getter("isBroken", field));
- clazz.addMethod(CtNewMethod.setter("setBroken", field));
- Class _class = clazz.toClass();
-
- Object object = _class.getConstructor().newInstance();
-
- set(_class, object, false);
- check(_class, object, false);
- }
-
- /**
- * Tests a getter only on a field with Modifier.STATIC.
- *
- * @throws Exception
- */
- public void testStaticFieldGetter() throws Exception {
- CtClass clazz = pool.makeClass("HasStaticFieldGetter");
- clazz.setSuperclass(pool.get("java.lang.Object"));
- CtField field = new CtField(CtClass.booleanType, "broken", clazz);
- field.setModifiers(Modifier.STATIC);
- clazz.addField(field, "true");
- clazz.addMethod(CtNewMethod.getter("isBroken", field));
- Class _class = clazz.toClass();
-
- Object object = _class.getConstructor().newInstance();
- check(_class, object, true);
- }
-
- /**
- * Tests a getter and setter on a field with Modifier.STATIC.
- *
- * @throws Exception
- */
- public void testStaticFieldGetterSetter() throws Exception {
- CtClass clazz = pool.makeClass("HasStaticFieldGetterSetter");
- clazz.setSuperclass(pool.get("java.lang.Object"));
- CtField field = new CtField(CtClass.booleanType, "broken", clazz);
- field.setModifiers(Modifier.STATIC);
- clazz.addField(field, "true");
- clazz.addMethod(CtNewMethod.getter("isBroken", field));
- clazz.addMethod(CtNewMethod.setter("setBroken", field));
- Class _class = clazz.toClass();
-
- Object object = _class.getConstructor().newInstance();
-
- set(_class, object, false);
- check(_class, object, false);
- }
-
- private void check(Class _class, Object object, boolean shouldBe)
- throws Exception
- {
- Method method = _class.getMethod("isBroken", new Class[] {});
- Boolean result = (Boolean) method.invoke(object, new Object[] {});
- assertEquals("boolean is wrong value",
- shouldBe, result.booleanValue());
- }
-
- private void set(Class _class, Object object, boolean willBe)
- throws Exception
- {
- Method method = _class.getMethod("setBroken",
- new Class[] {Boolean.TYPE});
- method.invoke(object, new Object[] { Boolean.valueOf(willBe)});
- }
-}
+package javassist; +import java.lang.reflect.Method; + +import junit.framework.TestCase; + +@SuppressWarnings({"rawtypes","unchecked"}) +public class SetterTest extends TestCase { + + ClassPool pool; + Class<?> capability; + + public SetterTest(String name) { + super(name); + } + + protected void setUp() throws Exception { + super.setUp(); + pool = ClassPool.getDefault(); + capability = Class.forName("DefineClassCapability"); + } + + /** + * Tests a getter only on a field without a Modifier. + * + * @throws Exception + */ + public void testFieldGetter() throws Exception { + CtClass clazz = pool.makeClass("HasFieldGetter"); + clazz.setSuperclass(pool.get("java.lang.Object")); + CtField field = new CtField(CtClass.booleanType, "broken", clazz); + clazz.addField(field, "true"); + clazz.addMethod(CtNewMethod.getter("isBroken", field)); + Class _class = clazz.toClass(capability); + + Object object = _class.getConstructor().newInstance(); + check(_class, object, true); + } + + /** + * Tests a getter and a setter on a field without a Modifier. + * + * @throws Exception + */ + public void testFieldGetterSetter() throws Exception { + CtClass clazz = pool.makeClass("HasFieldGetterSetter"); + clazz.setSuperclass(pool.get("java.lang.Object")); + CtField field = new CtField(CtClass.booleanType, "broken", clazz); + clazz.addField(field, "true"); + clazz.addMethod(CtNewMethod.getter("isBroken", field)); + clazz.addMethod(CtNewMethod.setter("setBroken", field)); + Class _class = clazz.toClass(capability); + + Object object = _class.getConstructor().newInstance(); + + set(_class, object, false); + check(_class, object, false); + } + + /** + * Tests a getter only on a field with Modifier.STATIC. + * + * @throws Exception + */ + public void testStaticFieldGetter() throws Exception { + CtClass clazz = pool.makeClass("HasStaticFieldGetter"); + clazz.setSuperclass(pool.get("java.lang.Object")); + CtField field = new CtField(CtClass.booleanType, "broken", clazz); + field.setModifiers(Modifier.STATIC); + clazz.addField(field, "true"); + clazz.addMethod(CtNewMethod.getter("isBroken", field)); + Class _class = clazz.toClass(capability); + + Object object = _class.getConstructor().newInstance(); + check(_class, object, true); + } + + /** + * Tests a getter and setter on a field with Modifier.STATIC. + * + * @throws Exception + */ + public void testStaticFieldGetterSetter() throws Exception { + CtClass clazz = pool.makeClass("HasStaticFieldGetterSetter"); + clazz.setSuperclass(pool.get("java.lang.Object")); + CtField field = new CtField(CtClass.booleanType, "broken", clazz); + field.setModifiers(Modifier.STATIC); + clazz.addField(field, "true"); + clazz.addMethod(CtNewMethod.getter("isBroken", field)); + clazz.addMethod(CtNewMethod.setter("setBroken", field)); + Class _class = clazz.toClass(capability); + + Object object = _class.getConstructor().newInstance(); + + set(_class, object, false); + check(_class, object, false); + } + + private void check(Class _class, Object object, boolean shouldBe) + throws Exception + { + Method method = _class.getMethod("isBroken", new Class[] {}); + Boolean result = (Boolean) method.invoke(object, new Object[] {}); + assertEquals("boolean is wrong value", + shouldBe, result.booleanValue()); + } + + private void set(Class _class, Object object, boolean willBe) + throws Exception + { + Method method = _class.getMethod("setBroken", + new Class[] {Boolean.TYPE}); + method.invoke(object, new Object[] { Boolean.valueOf(willBe)}); + } +} diff --git a/src/test/javassist/bytecode/InsertGap0.java b/src/test/javassist/bytecode/InsertGap0.java index 824b9305..425f12d7 100644 --- a/src/test/javassist/bytecode/InsertGap0.java +++ b/src/test/javassist/bytecode/InsertGap0.java @@ -175,7 +175,7 @@ public final class InsertGap0 extends JvstTestRoot { cc.addField(new CtField(CtClass.intType, "i", cc), "++counter"); boolean p = cc.stopPruning(true); cc.writeFile(); - Class c = cc.toClass(); + Class c = cc.toClass(ClassFile.class); cc.stopPruning(p); Object obj = c.getConstructor().newInstance(); @@ -194,7 +194,7 @@ public final class InsertGap0 extends JvstTestRoot { cc.addField(new CtField(CtClass.intType, "i", cc), "++counter"); boolean p = cc.stopPruning(true); cc.writeFile(); - Class c = cc.toClass(); + Class c = cc.toClass(ClassFile.class); cc.stopPruning(p); Object obj = c.getConstructor().newInstance(); diff --git a/src/test/javassist/tools/CallbackTest.java b/src/test/javassist/tools/CallbackTest.java index 96632bda..f5861ceb 100644 --- a/src/test/javassist/tools/CallbackTest.java +++ b/src/test/javassist/tools/CallbackTest.java @@ -3,6 +3,7 @@ package javassist.tools; import javassist.*; import junit.framework.TestCase; import test.javassist.tools.DummyClass; +import test.javassist.tools.DefineClassCapability; import static javassist.tools.Callback.*; @@ -34,7 +35,7 @@ public class CallbackTest extends TestCase { }); // Change class and invoke method; - classToChange.toClass(); + classToChange.toClass(DefineClassCapability.class); new DummyClass().dummyMethod(); } } diff --git a/src/test/test/javassist/DefineClassCapability.java b/src/test/test/javassist/DefineClassCapability.java new file mode 100644 index 00000000..e6a0fd51 --- /dev/null +++ b/src/test/test/javassist/DefineClassCapability.java @@ -0,0 +1,7 @@ +package test.javassist; + +/* + * This is used as a capability for running CtClass#toClass(). + */ +public class DefineClassCapability { +} diff --git a/src/test/test/javassist/convert/ArrayAccessReplaceTest.java b/src/test/test/javassist/convert/ArrayAccessReplaceTest.java index d81f220d..cebd1853 100644 --- a/src/test/test/javassist/convert/ArrayAccessReplaceTest.java +++ b/src/test/test/javassist/convert/ArrayAccessReplaceTest.java @@ -1,7 +1,5 @@ package test.javassist.convert; -import java.net.URL; -import java.net.URLClassLoader; import java.util.HashMap; import java.util.Map; @@ -11,7 +9,7 @@ import javassist.CtClass; import junit.framework.TestCase; public class ArrayAccessReplaceTest extends TestCase { - private static SimpleInterface simple; + private static SimpleInterface simple = null; public void setUp() throws Exception { ClassPool pool = new ClassPool(true); @@ -21,7 +19,9 @@ public class ArrayAccessReplaceTest extends TestCase { converter.replaceArrayAccess(echoClass, new CodeConverter.DefaultArrayAccessReplacementMethodNames()); simpleClass.instrument(converter); //simpleClass.writeFile("/tmp"); - simple = (SimpleInterface) simpleClass.toClass(new URLClassLoader(new URL[0], getClass().getClassLoader()), Class.class.getProtectionDomain()).getConstructor().newInstance(); + + simple = (SimpleInterface)new javassist.Loader.Simple().invokeDefineClass(simpleClass) + .getConstructor().newInstance(); } public void testComplex() throws Exception { @@ -31,7 +31,9 @@ public class ArrayAccessReplaceTest extends TestCase { CodeConverter converter = new CodeConverter(); converter.replaceArrayAccess(clazz, new CodeConverter.DefaultArrayAccessReplacementMethodNames()); clazz.instrument(converter); - ComplexInterface instance = (ComplexInterface) clazz.toClass(new URLClassLoader(new URL[0], getClass().getClassLoader()), Class.class.getProtectionDomain()).getConstructor().newInstance(); + ComplexInterface instance + = (ComplexInterface)new javassist.Loader.Simple().invokeDefineClass(clazz) + .getConstructor().newInstance(); assertEquals(Integer.valueOf(5), instance.complexRead(4)); } diff --git a/src/test/test/javassist/proxy/ProxyCacheGCTest.java b/src/test/test/javassist/proxy/ProxyCacheGCTest.java index 97b7281d..e47c4383 100644 --- a/src/test/test/javassist/proxy/ProxyCacheGCTest.java +++ b/src/test/test/javassist/proxy/ProxyCacheGCTest.java @@ -90,9 +90,9 @@ public class ProxyCacheGCTest extends TestCase // now create a proxyfactory and use it to create a proxy ProxyFactory factory = new ProxyFactory(); - Class javaTargetClass = classPool.toClass(ctTargetClass); - Class javaHandlerClass = classPool.toClass(ctHandlerClass); - Class javaFilterClass = classPool.toClass(ctFilterClass); + Class javaTargetClass = classPool.toClass(ctTargetClass, test.javassist.DefineClassCapability.class); + Class javaHandlerClass = classPool.toClass(ctHandlerClass, test.javassist.DefineClassCapability.class); + Class javaFilterClass = classPool.toClass(ctFilterClass, test.javassist.DefineClassCapability.class); MethodHandler handler= (MethodHandler)javaHandlerClass.getConstructor().newInstance(); MethodFilter filter = (MethodFilter)javaFilterClass.getConstructor().newInstance(); diff --git a/src/test/test/javassist/proxy/TestSecuredPrivileged.java b/src/test/test/javassist/proxy/TestSecuredPrivileged.java deleted file mode 100644 index c51555f5..00000000 --- a/src/test/test/javassist/proxy/TestSecuredPrivileged.java +++ /dev/null @@ -1,281 +0,0 @@ -package test.javassist.proxy; -import static org.hamcrest.Matchers.arrayWithSize; -import static org.hamcrest.Matchers.both; -import static org.hamcrest.Matchers.endsWith; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.startsWith; -import static org.hamcrest.Matchers.stringContainsInOrder; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.security.ProtectionDomain; -import java.util.Arrays; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import javassist.ClassPool; -import javassist.CtClass; -import javassist.util.proxy.DefineClassHelper; - -public class TestSecuredPrivileged { - - public TestSecuredPrivileged() { - } - - @Rule - public ExpectedException thrown = ExpectedException.none(); - /** - * Test proves that you cannot even access members with - * private static and final modifiers. */ - @Test - public void testDefinedHelperPrivilegedFieldVisibility() { - try { - Field privi = DefineClassHelper.class.getDeclaredField("privileged"); - assertTrue(Modifier.isStatic(privi.getModifiers())); - thrown.expectCause(instanceOf(IllegalAccessException.class)); - thrown.expectMessage(both(stringContainsInOrder(Arrays.asList("cannot access a member"))) - .and(stringContainsInOrder(Arrays.asList("with modifiers \"private static final".split("", 1))))); - - privi.get(null); - } catch(Throwable t) { - throw new RuntimeException(t); - } - } - /** - * Test proves that the default enum constant is a class and specifically - * auto selected for Java 9. */ - @Test - public void testDefinedHelperPrivilegedField() { - try { - Field privi = DefineClassHelper.class.getDeclaredField("privileged"); - assertTrue(Modifier.isStatic(privi.getModifiers())); - Constructor<DefineClassHelper> con = DefineClassHelper.class.getDeclaredConstructor(); - con.setAccessible(true); - DefineClassHelper inst = con.newInstance(); - assertThat(inst, instanceOf(DefineClassHelper.class)); - privi.setAccessible(true); - Object p = privi.get(inst); - assertThat(""+p, equalTo("JAVA_9")); - assertThat(p.getClass().getName(), endsWith("SecuredPrivileged$1")); - } catch(Throwable t) { - throw new RuntimeException(t); - } - } - /** - * Test proves that caller class security is enforced and works - * as expected. */ - @Test - public void testDefinedHelperPrivilegedFieldMethodAccessDenied() { - try { - Constructor<DefineClassHelper> con = DefineClassHelper.class.getDeclaredConstructor(); - con.setAccessible(true); - DefineClassHelper inst = con.newInstance(); - Field privi = DefineClassHelper.class.getDeclaredField("privileged"); - privi.setAccessible(true); - Object priviInst = privi.get(inst); - Method defineClass = priviInst.getClass().getDeclaredMethod( - "defineClass", new Class[] { - String.class, byte[].class, int.class, int.class, - ClassLoader.class, ProtectionDomain.class - }); - - assertThat(defineClass, notNullValue()); - defineClass.setAccessible(true); - assertThat(defineClass.getName(), equalTo("defineClass")); - assertTrue(defineClass.canAccess(priviInst)); - ClassPool cp = ClassPool.getDefault(); - CtClass c = cp.makeClass("a.b.C"); - byte[] bc = c.toBytecode(); - - thrown.expectCause(instanceOf(IllegalAccessError.class)); - thrown.expectMessage(equalTo("java.lang.IllegalAccessError: Access denied for caller.")); - - @SuppressWarnings("unused") - Object res = defineClass.invoke(priviInst, new Object[] { - c.getName(), bc, 0, bc.length, new ClassLoader() {}, - ClassLoader.class.getProtectionDomain() - }); - } catch(InvocationTargetException t) { - throw new RuntimeException(t.getTargetException()); - } catch(Throwable t) { throw new RuntimeException(t); } - } - /** - * Test proves that we do have 3 enum constants in the private static - * inner class. */ - @Test - public void testDefinedHelperEnumClass() { - try { - Constructor<DefineClassHelper> con = DefineClassHelper.class.getDeclaredConstructor(); - con.setAccessible(true); - assertThat(DefineClassHelper.class.getDeclaredClasses(), arrayWithSize(1)); - Class<?> secPriv = DefineClassHelper.class.getDeclaredClasses()[0]; - assertTrue(secPriv.isEnum()); - assertThat(secPriv.getEnumConstants(), arrayWithSize(3)); - assertThat(""+secPriv.getEnumConstants()[0], equalTo("JAVA_9")); - assertThat(""+secPriv.getEnumConstants()[1], equalTo("JAVA_7")); - assertThat(""+secPriv.getEnumConstants()[2], equalTo("JAVA_OTHER")); - - } catch (Throwable t) {t.printStackTrace();} - - } - /** - * Test proves that you cannot modify private static final reference even - * with setAccessible(true). */ - @Test - public void testDefinedHelperCannotSetPrivileged() { - try { - Constructor<DefineClassHelper> con = DefineClassHelper.class.getDeclaredConstructor(); - con.setAccessible(true); - DefineClassHelper inst = con.newInstance(); - Class<?> secPriv = DefineClassHelper.class.getDeclaredClasses()[0]; - Object J7 = secPriv.getEnumConstants()[1]; - Field privi = DefineClassHelper.class.getDeclaredField("privileged"); - privi.setAccessible(true); - thrown.expectCause(instanceOf(IllegalAccessException.class)); - thrown.expectMessage(startsWith("java.lang.IllegalAccessException: Can not set static final")); - privi.set(inst, J7); - - } catch (Throwable t) {throw new RuntimeException(t);} - - } - /** - * Test proves that you can achieve the impossible and modify private - * static final class reference without an instance. Now we can Mock - * test JDK 6 to 8 functionality */ - @Test - public void testDefinedHelperSetPrivilegedToJava7() { - try { - Constructor<DefineClassHelper> con = DefineClassHelper.class.getDeclaredConstructor(); - con.setAccessible(true); - DefineClassHelper inst = con.newInstance(); - Class<?> secPriv = DefineClassHelper.class.getDeclaredClasses()[0]; - Object J9 = secPriv.getEnumConstants()[0]; - Object J7 = secPriv.getEnumConstants()[1]; - Field privi = DefineClassHelper.class.getDeclaredField("privileged"); - privi.setAccessible(true); - Object privInst = privi.get(inst); - Field unsf = privInst.getClass().getDeclaredField("sunMiscUnsafe"); - unsf.setAccessible(true); - Object refu = unsf.get(privInst); - Field tuf = refu.getClass().getDeclaredField("sunMiscUnsafeTheUnsafe"); - tuf.setAccessible(true); - Object tu = tuf.get(refu); - Method tu_call = tu.getClass().getMethod("call", new Class<?>[] {String.class, Object[].class}); - tu_call.setAccessible(true); - long offset = (Long) tu_call.invoke(tu, new Object[] {"staticFieldOffset", new Object[] {privi}}); - tu_call.invoke(tu, new Object[] {"putObjectVolatile", new Object[] {DefineClassHelper.class, offset, J7}}); - - Object p = privi.get(inst); - assertThat(""+p, equalTo("JAVA_7")); - assertThat(p.getClass().getName(), endsWith("SecuredPrivileged$2")); - - tu_call.invoke(tu, new Object[] {"putObjectVolatile", new Object[] {DefineClassHelper.class, offset, J9}}); - - } catch (Throwable t) {t.printStackTrace();} - - } - /** - * Test proves that Java 7+ MethodHandle defineClass (or DefineClassHelper.toClass) - * works as expected. */ - @Test - public void testDefinedHelperJava7ToClass() { - try { - Constructor<DefineClassHelper> con = DefineClassHelper.class.getDeclaredConstructor(); - con.setAccessible(true); - DefineClassHelper inst = con.newInstance(); - Class<?> secPriv = DefineClassHelper.class.getDeclaredClasses()[0]; - Object J9 = secPriv.getEnumConstants()[0]; - Object J7 = secPriv.getEnumConstants()[1]; - Field privi = DefineClassHelper.class.getDeclaredField("privileged"); - privi.setAccessible(true); - Object privInst = privi.get(inst); - Field unsf = privInst.getClass().getDeclaredField("sunMiscUnsafe"); - unsf.setAccessible(true); - Object refu = unsf.get(privInst); - Field tuf = refu.getClass().getDeclaredField("sunMiscUnsafeTheUnsafe"); - tuf.setAccessible(true); - Object tu = tuf.get(refu); - Method tu_call = tu.getClass().getMethod("call", new Class<?>[] {String.class, Object[].class}); - tu_call.setAccessible(true); - long offset = (Long) tu_call.invoke(tu, new Object[] {"staticFieldOffset", new Object[] {privi}}); - tu_call.invoke(tu, new Object[] {"putObjectVolatile", new Object[] {DefineClassHelper.class, offset, J7}}); - - ClassPool cp = ClassPool.getDefault(); - CtClass c = cp.makeClass("a.b.J7"); - byte[] bc = c.toBytecode(); - Class<?> bcCls = DefineClassHelper.toClass("a.b.J7", new ClassLoader() {}, null, bc); - assertThat(bcCls.getName(), equalTo("a.b.J7")); - assertThat(bcCls.getDeclaredConstructor().newInstance(), - not(equalTo(bcCls.getDeclaredConstructor().newInstance()))); - - tu_call.invoke(tu, new Object[] {"putObjectVolatile", new Object[] {DefineClassHelper.class, offset, J9}}); - - } catch (Throwable t) {t.printStackTrace();} - - } - /** - * Test proves that Java 6 reflection method defineClass (or DefineClassHelper.toClass) - * works as expected. */ - @Test - public void testDefinedHelperJavaOtherToClass() { - try { - Constructor<DefineClassHelper> con = DefineClassHelper.class.getDeclaredConstructor(); - con.setAccessible(true); - DefineClassHelper inst = con.newInstance(); - Class<?> secPriv = DefineClassHelper.class.getDeclaredClasses()[0]; - Object J9 = secPriv.getEnumConstants()[0]; - Object JO = secPriv.getEnumConstants()[2]; - Field privi = DefineClassHelper.class.getDeclaredField("privileged"); - privi.setAccessible(true); - Object privInst = privi.get(inst); - Field unsf = privInst.getClass().getDeclaredField("sunMiscUnsafe"); - unsf.setAccessible(true); - Object refu = unsf.get(privInst); - Field tuf = refu.getClass().getDeclaredField("sunMiscUnsafeTheUnsafe"); - tuf.setAccessible(true); - Object tu = tuf.get(refu); - Method tu_call = tu.getClass().getMethod("call", new Class<?>[] {String.class, Object[].class}); - tu_call.setAccessible(true); - long offset = (Long) tu_call.invoke(tu, new Object[] {"staticFieldOffset", new Object[] {privi}}); - tu_call.invoke(tu, new Object[] {"putObjectVolatile", new Object[] {DefineClassHelper.class, offset, JO}}); - - ClassPool cp = ClassPool.getDefault(); - CtClass c = cp.makeClass("a.b.JO"); - byte[] bc = c.toBytecode(); - Class<?> bcCls = DefineClassHelper.toClass("a.b.JO", new ClassLoader() {}, null, bc); - assertThat(bcCls.getName(), equalTo("a.b.JO")); - assertThat(bcCls.getDeclaredConstructor().newInstance(), - not(equalTo(bcCls.getDeclaredConstructor().newInstance()))); - - tu_call.invoke(tu, new Object[] {"putObjectVolatile", new Object[] {DefineClassHelper.class, offset, J9}}); - - } catch (Throwable t) {t.printStackTrace();} - - } - /** - * Test proves that default Java 9 defineClass (or DefineClassHelper.toClass) - * works as expected. */ - @Test - public void testDefinedHelperDefaultToClass() { - try { - ClassPool cp = ClassPool.getDefault(); - CtClass c = cp.makeClass("a.b.D"); - byte[] bc = c.toBytecode(); - Class<?> bcCls = DefineClassHelper.toClass("a.b.D", new ClassLoader() {}, null, bc); - assertThat(bcCls.getName(), equalTo("a.b.D")); - assertThat(bcCls.getDeclaredConstructor().newInstance(), - not(equalTo(bcCls.getDeclaredConstructor().newInstance()))); - } catch (Throwable t) {t.printStackTrace();} - - } -} diff --git a/src/test/test/javassist/tools/DefineClassCapability.java b/src/test/test/javassist/tools/DefineClassCapability.java new file mode 100644 index 00000000..fc3dc4e4 --- /dev/null +++ b/src/test/test/javassist/tools/DefineClassCapability.java @@ -0,0 +1,7 @@ +/* + * This is used as a capability for running CtClass#toClass(). + */ +package test.javassist.tools; + +public class DefineClassCapability { +} diff --git a/src/test/test1/DefineClassCapability.java b/src/test/test1/DefineClassCapability.java new file mode 100644 index 00000000..fe386f06 --- /dev/null +++ b/src/test/test1/DefineClassCapability.java @@ -0,0 +1,7 @@ +/* + * This is used as a capability for running CtClass#toClass(). + */ +package test1; + +public class DefineClassCapability { +} diff --git a/src/test/test2/DefineClassCapability.java b/src/test/test2/DefineClassCapability.java new file mode 100644 index 00000000..303ffcc7 --- /dev/null +++ b/src/test/test2/DefineClassCapability.java @@ -0,0 +1,7 @@ +/* + * This is used as a capability for running CtClass#toClass(). + */ +package test2; + +public class DefineClassCapability { +} diff --git a/src/test/test3/DefineClassCapability.java b/src/test/test3/DefineClassCapability.java new file mode 100644 index 00000000..60b91835 --- /dev/null +++ b/src/test/test3/DefineClassCapability.java @@ -0,0 +1,7 @@ +/* + * This is used as a capability for running CtClass#toClass(). + */ +package test3; + +public class DefineClassCapability { +} diff --git a/src/test/test4/DefineClassCapability.java b/src/test/test4/DefineClassCapability.java new file mode 100644 index 00000000..d0bef62e --- /dev/null +++ b/src/test/test4/DefineClassCapability.java @@ -0,0 +1,7 @@ +/* + * This is used as a capability for running CtClass#toClass(). + */ +package test4; + +public class DefineClassCapability { +} diff --git a/src/test/test5/DefineClassCapability.java b/src/test/test5/DefineClassCapability.java new file mode 100644 index 00000000..1bb573c8 --- /dev/null +++ b/src/test/test5/DefineClassCapability.java @@ -0,0 +1,7 @@ +/* + * This is used as a capability for running CtClass#toClass(). + */ +package test5; + +public class DefineClassCapability { +} |