From 0f4969b60a5a9ad20400058d118b4ea99f93e72d Mon Sep 17 00:00:00 2001 From: Ivan Dubrov Date: Thu, 1 May 2014 22:39:50 -0700 Subject: [PATCH] Allow classes to reside outside of test class. Adding support for extra classes being redefined to the test framework. Rewriting lambda test a little, extracting classes with lambda's to top level. --- .../java/com/github/dcevm/HotSwapTool.java | 23 +++++++++---- .../dcevm/test/util/HotSwapTestHelper.java | 4 +-- .../github/dcevm/test/lambdas/LambdaA.java | 13 ++++++++ .../dcevm/test/lambdas/LambdaA___1.java | 14 ++++++++ .../github/dcevm/test/lambdas/LambdaTest.java | 33 ++++--------------- 5 files changed, 53 insertions(+), 34 deletions(-) create mode 100644 dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaA.java create mode 100644 dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaA___1.java diff --git a/dcevm/src/main/java/com/github/dcevm/HotSwapTool.java b/dcevm/src/main/java/com/github/dcevm/HotSwapTool.java index 72d77590..43baa850 100644 --- a/dcevm/src/main/java/com/github/dcevm/HotSwapTool.java +++ b/dcevm/src/main/java/com/github/dcevm/HotSwapTool.java @@ -131,7 +131,7 @@ public class HotSwapTool { * @param outerClass the outer class whose inner classes should be redefined * @param versionNumber the target version number */ - public static void toVersion(Class outerClass, int versionNumber) { + public static void toVersion(Class outerClass, int versionNumber, Class... extraClasses) { assert versionNumber >= 0; if (versionNumber == getCurrentVersion(outerClass)) { @@ -141,6 +141,18 @@ public class HotSwapTool { Map files = findClassesWithVersion(outerClass, versionNumber); + for (Class extra : extraClasses) { + if (parseClassVersion(extra.getSimpleName()) == versionNumber) { + String packageName = extra.getPackage().getName().replace('.', '/'); + URL url = extra.getClassLoader().getResource(packageName); + if (url == null) { + throw new IllegalArgumentException("Cannot find URL corresponding to the package '" + packageName + "'"); + } + File file = new File(url.getFile(), extra.getSimpleName() + ".class"); + files.put(extra.getName(), file); + } + } + try { Map, byte[]> map = buildRedefinitionMap(files); @@ -171,11 +183,10 @@ public class HotSwapTool { } File folder = new File(url.getFile()); for (File f : folder.listFiles(IsClassFile.INSTANCE)) { - String fileName = f.getName(); String simpleName = f.getName().substring(0, f.getName().length() - CLASS_FILE_SUFFIX.length()); String name = baseClass.getPackage().getName() + '.' + simpleName; - if (isInnerClass(name, baseClass) && parseClassVersion(fileName) == version) { + if (isInnerClass(name, baseClass) && parseClassVersion(simpleName) == version) { classes.put(name, f); } } @@ -202,12 +213,12 @@ public class HotSwapTool { /** * Parse version of the class from the class name. Classes are named in the form of [Name]___[Version] */ - private static int parseClassVersion(String name) { - int index = name.indexOf(IDENTIFIER); + private static int parseClassVersion(String simpleName) { + int index = simpleName.indexOf(IDENTIFIER); if (index == -1) { return 0; } - return Integer.valueOf(name.substring(index + IDENTIFIER.length(), name.length() - CLASS_FILE_SUFFIX.length())); + return Integer.valueOf(simpleName.substring(index + IDENTIFIER.length(), simpleName.length())); } private static String stripVersion(String className) { diff --git a/dcevm/src/test/java7/com/github/dcevm/test/util/HotSwapTestHelper.java b/dcevm/src/test/java7/com/github/dcevm/test/util/HotSwapTestHelper.java index b6fc4ff0..8ba4217b 100644 --- a/dcevm/src/test/java7/com/github/dcevm/test/util/HotSwapTestHelper.java +++ b/dcevm/src/test/java7/com/github/dcevm/test/util/HotSwapTestHelper.java @@ -49,8 +49,8 @@ public class HotSwapTestHelper { * * @param versionNumber the target version number */ - public static void __toVersion__(int versionNumber) { - HotSwapTool.toVersion(determineOuter(0), versionNumber); + public static void __toVersion__(int versionNumber, Class... extra) { + HotSwapTool.toVersion(determineOuter(0), versionNumber, extra); } /** diff --git a/dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaA.java b/dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaA.java new file mode 100644 index 00000000..670cf8b7 --- /dev/null +++ b/dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaA.java @@ -0,0 +1,13 @@ +package com.github.dcevm.test.lambdas; + +import java.util.concurrent.Callable; + +public class LambdaA { + public Callable createLambda() { + return () -> 10; + } + + public Callable createLambda2() { + return () -> 20; + } +} diff --git a/dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaA___1.java b/dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaA___1.java new file mode 100644 index 00000000..37697150 --- /dev/null +++ b/dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaA___1.java @@ -0,0 +1,14 @@ +package com.github.dcevm.test.lambdas; + +import java.util.concurrent.Callable; + +public class LambdaA___1 { + + public Callable createLambda() { + return () -> 30; + } + + public Callable createLambda2() { + return () -> 40; + } +} diff --git a/dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaTest.java b/dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaTest.java index ba04fa73..efacdbbc 100644 --- a/dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaTest.java +++ b/dcevm/src/test/java8/com/github/dcevm/test/lambdas/LambdaTest.java @@ -36,7 +36,11 @@ import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; import static org.junit.Assert.assertEquals; /** - * Tests for lambda expressions + * Tests for lambda expressions. + * + * These lambdas are sneaky. First, it seems like generated lambda method names are arbitrary and depend + * on the compilation order. However, for redefinition test we want to make sure that generated method names would + * actually match in old and new versions, so we have keep classes being redefined outside of this inner class. * * @author Ivan Dubrov */ @@ -48,39 +52,16 @@ public class LambdaTest { __toVersion__(0); } - // Version 0 - public static class A { - public Callable createLambda() { - return () -> 10; - } - - public Callable createLambda2() { - return () -> 20; - } - } - - // Version 1 - public static class A___1 { - public Callable createLambda2() { - return () -> 40; - } - - public Callable createLambda() { - return () -> 30; - } - } - @Test - @Ignore public void testMethodLambda() throws Exception { - A a = new A(); + LambdaA a = new LambdaA(); Callable lambda = a.createLambda(); Callable lambda2 = a.createLambda2(); assertEquals(10, (int) lambda.call()); assertEquals(20, (int) lambda2.call()); - __toVersion__(1); + __toVersion__(1, LambdaA___1.class); assertEquals(30, (int) lambda.call()); assertEquals(40, (int) lambda2.call()); -- 2.39.5