From 05bbf3c41936ef2a1ba382ecbf4aea2e36b8c97c Mon Sep 17 00:00:00 2001 From: Ivan Dubrov Date: Mon, 5 May 2014 12:47:54 -0700 Subject: Handle removed/changed fields in DMH In case matching field is not found, clear (set to null) references to faulty DMH. Long term, should replace such DMH's with instances that will throw more meaningful error messages at runtime. --- .../dcevm/test/fields/InstanceFieldHandleTest.java | 69 +++++++++++++++++----- .../dcevm/test/fields/StaticFieldHandleTest.java | 64 +++++++++++++++----- 2 files changed, 103 insertions(+), 30 deletions(-) (limited to 'dcevm/src') diff --git a/dcevm/src/test/java7/com/github/dcevm/test/fields/InstanceFieldHandleTest.java b/dcevm/src/test/java7/com/github/dcevm/test/fields/InstanceFieldHandleTest.java index 48f3f46f..4253c3b8 100644 --- a/dcevm/src/test/java7/com/github/dcevm/test/fields/InstanceFieldHandleTest.java +++ b/dcevm/src/test/java7/com/github/dcevm/test/fields/InstanceFieldHandleTest.java @@ -24,8 +24,8 @@ package com.github.dcevm.test.fields; import org.junit.After; +import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import java.lang.invoke.MethodHandle; @@ -45,13 +45,21 @@ public class InstanceFieldHandleTest { public static class A { public int fieldA; public int fieldB; + + public int getFieldA() { + return -1; + } } // Version 1 (fields swapped and new one is added) public static class A___1 { - public String fieldC; public int fieldB; public int fieldA; + public String fieldC; + + public int getFieldA() { + return fieldA; + } } // Version 2 (fields removed) @@ -73,41 +81,72 @@ public class InstanceFieldHandleTest { @Test public void testFieldChangeOrder() throws Throwable { A a = new A(); - MethodHandle handle = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); + MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class); a.fieldA = 3; - assertEquals(3, handle.invoke(a)); + assertEquals(3, getter.invoke(a)); // Swap fields __toVersion__(1); - assertEquals(3, handle.invoke(a)); + + assertEquals(3, getter.invoke(a)); + setter.invoke(a, 53); + assertEquals(53, a.getFieldA()); + assertEquals(53, getter.invoke(a)); } @Test - @Ignore - public void testStaticFieldRemoved() throws Throwable { - MethodHandle handle = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); + public void testFieldRemoved() throws Throwable { A a = new A(); + MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class); + a.fieldA = 3; - assertEquals(3, handle.invoke(a)); + assertEquals(3, getter.invoke(a)); // Remove fieldA __toVersion__(2); - handle.invoke(a); + try { + getter.invoke(a); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + + try { + setter.invoke(a, 10); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } } @Test - @Ignore - public void testStaticFieldTypeChange() throws Throwable { - MethodHandle handle = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); + public void testFieldTypeChange() throws Throwable { A a = new A(); + MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class); + a.fieldA = 3; - assertEquals(3, handle.invoke(a)); + assertEquals(3, getter.invoke(a)); // Remove fieldA __toVersion__(3); - handle.invoke(a); + try { + getter.invoke(a); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + + try { + setter.invoke(a, 10); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } } } \ No newline at end of file diff --git a/dcevm/src/test/java7/com/github/dcevm/test/fields/StaticFieldHandleTest.java b/dcevm/src/test/java7/com/github/dcevm/test/fields/StaticFieldHandleTest.java index 6f565252..237cff25 100644 --- a/dcevm/src/test/java7/com/github/dcevm/test/fields/StaticFieldHandleTest.java +++ b/dcevm/src/test/java7/com/github/dcevm/test/fields/StaticFieldHandleTest.java @@ -23,19 +23,15 @@ */ package com.github.dcevm.test.fields; -import com.github.dcevm.test.TestUtil; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; -import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; import static org.junit.Assert.assertEquals; /** @@ -49,12 +45,21 @@ public class StaticFieldHandleTest { public static class A { public static int fieldA; public static int fieldB; + + public static int getFieldA() { + return -1; + } } // Version 1 (fields swapped) public static class A___1 { public static int fieldB; public static int fieldA; + public static String fieldC; + + public static int getFieldA() { + return fieldA; + } } // Version 2 (fields removed) @@ -75,44 +80,73 @@ public class StaticFieldHandleTest { @Test public void testStaticFieldChangeOrder() throws Throwable { - MethodHandle handle = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class); + MethodHandle getter = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findStaticSetter(A.class, "fieldA", int.class); A.fieldA = 3; A.fieldB = 5; - assertEquals(3, handle.invoke()); + assertEquals(3, getter.invoke()); // Swap fields A and B __toVersion__(1); - assertEquals(3, handle.invoke()); + + assertEquals(3, getter.invoke()); + setter.invoke(12); + assertEquals(12, A.getFieldA()); + assertEquals(12, getter.invoke()); } @Test - @Ignore public void testStaticFieldRemoved() throws Throwable { - MethodHandle handle = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class); + MethodHandle getter = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findStaticSetter(A.class, "fieldA", int.class); A.fieldA = 3; A.fieldB = 5; - assertEquals(3, handle.invoke()); + assertEquals(3, getter.invoke()); // Remove fieldA __toVersion__(2); - handle.invoke(); + try { + getter.invoke(); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + + try { + setter.invoke(15); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } } @Test - @Ignore public void testStaticFieldTypeChange() throws Throwable { - MethodHandle handle = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class); + MethodHandle getter = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class); + MethodHandle setter = MethodHandles.publicLookup().findStaticSetter(A.class, "fieldA", int.class); A.fieldA = 3; A.fieldB = 5; - assertEquals(3, handle.invoke()); + assertEquals(3, getter.invoke()); // Remove fieldA __toVersion__(3); - handle.invoke(); + try { + getter.invoke(); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } + + try { + setter.invoke(15); + Assert.fail("Handle should have been cleared!"); + } catch (NullPointerException e) { + // Handle was cleared! + } } } \ No newline at end of file -- cgit v1.2.3