Working Java8 build!
- Split the AspectJ testcode out of the general testdata project. - Adjusted tests to handle that JDT produces different code to AspectJ. - Modified some tests to work better with javac compiled testdata (which is what happens when building on the command line or build machine)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
include "springloaded"
|
||||
include "testdata"
|
||||
include "testdata-java8"
|
||||
include "testdata-aspectj"
|
||||
include "testdata-groovy"
|
||||
include "testdata-plugin"
|
||||
include "testdata-subloader"
|
||||
|
||||
@@ -6,6 +6,5 @@
|
||||
<classpathentry kind="lib" path="lib/asm-tree-5.0_BETA.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J180_b128"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/springloaded-java8"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
||||
@@ -46,7 +46,9 @@ dependencies {
|
||||
|
||||
testCompileOnly files("../testdata-groovy/groovy-all-1.8.6.jar")
|
||||
testCompileOnly project(':testdata')
|
||||
testCompileOnly project(':testdata-aspectj')
|
||||
testCompileOnly project(':testdata-groovy')
|
||||
testCompileOnly project(':testdata-java8')
|
||||
testCompileOnly project(':testdata-plugin')
|
||||
testCompileOnly project(':testdata-subloader')
|
||||
testCompileOnly project(':testdata-superloader')
|
||||
|
||||
@@ -111,12 +111,15 @@ public class ClassRenamer {
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int flags, String name, String descriptor, String signature, String[] exceptions) {
|
||||
if (descriptor.indexOf(oldname) != -1) {
|
||||
descriptor = descriptor.replace(oldname, newname);
|
||||
} else {
|
||||
if (descriptor.indexOf(oldname) != -1) {
|
||||
descriptor = descriptor.replace(oldname, newname);
|
||||
}
|
||||
for (String s : retargets.keySet()) {
|
||||
if (descriptor.indexOf(s) != -1) {
|
||||
descriptor = descriptor.replace(s, retargets.get(s));
|
||||
|
||||
@@ -129,7 +129,16 @@ public class ExecutorBuilder {
|
||||
if (name.charAt(1) != 'c') {
|
||||
// regular constructor
|
||||
// want to create the ___init___ handler for this constructor
|
||||
|
||||
// With the JDT compiler the inner class constructor gets an extra first parameter that is the type of
|
||||
// containing class. But with javac the inner class constructor gets an extra first parameter that is of
|
||||
// a special anonymous type (inner class of the containing class)
|
||||
// For example: class Foo { class Bar {}}
|
||||
// JDT: ctor in Bar is <init>(Foo) {}
|
||||
// JAVAC: ctor in Bar is <init>(Foo$1) {}
|
||||
|
||||
descriptor = Utils.insertExtraParameter(classname, descriptor);
|
||||
|
||||
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC_STATIC, mInitializerName, descriptor, signature, exceptions);
|
||||
|
||||
ConstructorCopier cc = new ConstructorCopier(mv, typeDescriptor, suffix, classname);
|
||||
|
||||
@@ -625,7 +625,10 @@ public class TypeDiffComputer implements Opcodes {
|
||||
// td.setTypeVersionChange(oldClassNode.version, newClassNode.version);
|
||||
// }
|
||||
if (oldClassNode.access != newClassNode.access) {
|
||||
td.setTypeAccessChange(oldClassNode.access, newClassNode.access);
|
||||
// Is it only because of 0x20000 - that appears to represent Deprecated!
|
||||
if ((oldClassNode.access & 0xffff) != (newClassNode.access&0xffff)) {
|
||||
td.setTypeAccessChange(oldClassNode.access, newClassNode.access);
|
||||
}
|
||||
}
|
||||
if (!oldClassNode.name.equals(newClassNode.name)) {
|
||||
td.setTypeNameChange(oldClassNode.name, newClassNode.name);
|
||||
|
||||
@@ -87,7 +87,7 @@ public class Java8 {
|
||||
* @param lookup
|
||||
* @return
|
||||
*/
|
||||
public static Object emulateInvokeDynamic(Class executorClass, Handle handle, Object[] bsmArgs, Object lookup, String indyNameAndDescriptor, Object[] indyParams) {
|
||||
public static Object emulateInvokeDynamic(Class<?> executorClass, Handle handle, Object[] bsmArgs, Object lookup, String indyNameAndDescriptor, Object[] indyParams) {
|
||||
try {
|
||||
CallSite callsite = callLambdaMetaFactory(bsmArgs,lookup,indyNameAndDescriptor,executorClass);
|
||||
return callsite.dynamicInvoker().invokeWithArguments(indyParams);
|
||||
@@ -98,7 +98,7 @@ public class Java8 {
|
||||
// TODO [perf] How about a table of CallSites indexed by invokedynamic number through the class file. Computed on first reference but cleared on reload. Possibly extend this to all invoke types!
|
||||
|
||||
// TODO [lambda] Need to handle altMetaFactory which is used when the lambdas are more 'complex' (e.g. Serializable)
|
||||
public static CallSite callLambdaMetaFactory(Object[] bsmArgs, Object lookup, String indyNameAndDescriptor,Class executorClass) throws Exception {
|
||||
public static CallSite callLambdaMetaFactory(Object[] bsmArgs, Object lookup, String indyNameAndDescriptor,Class<?> executorClass) throws Exception {
|
||||
MethodHandles.Lookup caller = (MethodHandles.Lookup)lookup;
|
||||
|
||||
ClassLoader callerLoader = caller.lookupClass().getClassLoader();
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springsource.loaded.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -262,7 +263,10 @@ public class ExecutorBuilderTests extends SpringLoadedTests {
|
||||
s.add(anno.toString());
|
||||
}
|
||||
Assert.assertTrue(s.remove("@common.Marker()"));
|
||||
Assert.assertTrue(s.remove("@common.Anno(someValue=37, longValue=2, id=abc)"));
|
||||
// Allow for alternate toString() variant
|
||||
if (!s.remove("@common.Anno(someValue=37, longValue=2, id=abc)")) {
|
||||
Assert.assertTrue(s.remove("@common.Anno(longValue=2, someValue=37, id=abc)"));
|
||||
}
|
||||
Assert.assertEquals(0, s.size());
|
||||
}
|
||||
|
||||
@@ -296,7 +300,21 @@ public class ExecutorBuilderTests extends SpringLoadedTests {
|
||||
checkAnnotations(rtype.getLatestExecutorBytes(), "m2(Lexecutor/I;)V", "@common.Marker()", "@common.Anno(id=abc)");
|
||||
Method m = rtype.getLatestExecutorClass().getDeclaredMethod("m2", rtype.getClazz());
|
||||
assertEquals("@common.Marker()", m.getAnnotations()[0].toString());
|
||||
assertEquals("@common.Anno(someValue=37, longValue=2, id=abc)", printAnnotation(m.getAnnotations()[1]));
|
||||
assertIsOneOfThese(printAnnotation(m.getAnnotations()[1]),"@common.Anno(someValue=37, longValue=2, id=abc)", "@common.Anno(longValue=2, someValue=37, id=abc)");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the actual value is one of the possible options.
|
||||
*/
|
||||
private void assertIsOneOfThese(String actual, String... possibleValues) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (int i=0;i<possibleValues.length;i++) {
|
||||
if (actual.equals(possibleValues[i])) {
|
||||
return;
|
||||
}
|
||||
buf.append("'"+possibleValues[i]+"'").append("\n");
|
||||
}
|
||||
fail("The value:\n'"+actual+"'\n does not match one of these possible options:\n"+buf.toString());
|
||||
}
|
||||
//
|
||||
private String printAnnotation(Annotation a) {
|
||||
|
||||
@@ -564,7 +564,11 @@ public class FieldReloadingTests extends SpringLoadedTests {
|
||||
} catch (ResultException re) {
|
||||
assertTrue(re.getCause() instanceof InvocationTargetException);
|
||||
assertTrue(re.getCause().getCause() instanceof IncompatibleClassChangeError);
|
||||
assertEquals("Expected static field fields.Yb.j", re.getCause().getCause().getMessage());
|
||||
// When compiled with AspectJ vs Eclipse JDT the GETSTATIC actually varies.
|
||||
// With AspectJ it is: PUTSTATIC fields/Yb.j : I
|
||||
// With JDT (4.3) it is: PUTSTATIC fields/Zb.j : I
|
||||
// hence the error is different
|
||||
assertEquals("Expected static field fields.Zb.j", re.getCause().getCause().getMessage());
|
||||
}
|
||||
|
||||
// Now should be an IncompatibleClassChangeError
|
||||
@@ -574,7 +578,11 @@ public class FieldReloadingTests extends SpringLoadedTests {
|
||||
} catch (ResultException re) {
|
||||
assertTrue(re.getCause() instanceof InvocationTargetException);
|
||||
assertTrue(re.getCause().getCause() instanceof IncompatibleClassChangeError);
|
||||
assertEquals("Expected static field fields.Yb.j", re.getCause().getCause().getMessage());
|
||||
// When compiled with AspectJ vs Eclipse JDT the GETSTATIC actually varies.
|
||||
// With AspectJ it is: GETSTATIC fields/Yb.j : I
|
||||
// With JDT (4.3) it is: GETSTATIC fields/Zb.j : I
|
||||
// hence the error is different
|
||||
assertEquals("Expected static field fields.Zb.j", re.getCause().getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springsource.loaded.test;
|
||||
import org.junit.Test;
|
||||
import org.springsource.loaded.ReloadableType;
|
||||
import org.springsource.loaded.TypeRegistry;
|
||||
import org.springsource.loaded.test.infra.ClassPrinter;
|
||||
|
||||
|
||||
/**
|
||||
@@ -68,11 +69,15 @@ public class InnerClassesTests extends SpringLoadedTests {
|
||||
public void reloadPrivateVisInner() throws Exception {
|
||||
String tclass = "inners.Three";
|
||||
TypeRegistry typeRegistry = getTypeRegistry("inners..*");
|
||||
typeRegistry.addType("inners.Three$Inner", retrieveRename("inners.Three$Inner", "inners.Three2$Inner"));
|
||||
|
||||
|
||||
ReloadableType rtype = typeRegistry.addType(tclass, loadBytesForClass(tclass));
|
||||
runUnguarded(rtype.getClazz(), "runner");
|
||||
|
||||
rtype.loadNewVersion("2", retrieveRename(tclass, tclass + "2", "inners.Three2$Inner:inners.Three$Inner"));
|
||||
// ReloadableType rtypeInner =
|
||||
typeRegistry.addType("inners.Three$Inner", retrieveRename("inners.Three$Inner", "inners.Three2$Inner","inners.Three2:inners.Three"));
|
||||
|
||||
rtype.loadNewVersion("2", retrieveRename(tclass, tclass + "2", "inners.Three2$Inner:inners.Three$Inner","inners.Three2:inners.Three"));
|
||||
runUnguarded(rtype.getClazz(), "runner");
|
||||
}
|
||||
|
||||
@@ -84,11 +89,11 @@ public class InnerClassesTests extends SpringLoadedTests {
|
||||
public void reloadProtectedVisInner() throws Exception {
|
||||
String tclass = "inners.Four";
|
||||
TypeRegistry typeRegistry = getTypeRegistry("inners..*");
|
||||
typeRegistry.addType("inners.Four$Inner", retrieveRename("inners.Four$Inner", "inners.Four2$Inner"));
|
||||
typeRegistry.addType("inners.Four$Inner", retrieveRename("inners.Four$Inner", "inners.Four2$Inner","inners.Four2:inners.Four"));
|
||||
ReloadableType rtype = typeRegistry.addType(tclass, loadBytesForClass(tclass));
|
||||
runUnguarded(rtype.getClazz(), "runner");
|
||||
|
||||
rtype.loadNewVersion("2", retrieveRename(tclass, tclass + "2", "inners.Four2$Inner:inners.Four$Inner"));
|
||||
rtype.loadNewVersion("2", retrieveRename(tclass, tclass + "2", "inners.Four2$Inner:inners.Four$Inner","inners.Four2:inners.Four"));
|
||||
runUnguarded(rtype.getClazz(), "runner");
|
||||
}
|
||||
}
|
||||
@@ -47,12 +47,7 @@ import java.util.StringTokenizer;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Attribute;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.AnnotationNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
@@ -61,7 +56,6 @@ import org.objectweb.asm.tree.LocalVariableNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.springsource.loaded.ClassRenamer;
|
||||
import org.springsource.loaded.Constants;
|
||||
import org.springsource.loaded.GlobalConfiguration;
|
||||
import org.springsource.loaded.ISMgr;
|
||||
import org.springsource.loaded.MethodMember;
|
||||
import org.springsource.loaded.NameRegistry;
|
||||
@@ -92,6 +86,7 @@ public abstract class SpringLoadedTests implements Constants {
|
||||
protected ClassLoader binLoader;
|
||||
|
||||
protected String TestDataPath = TestUtils.getPathToClasses("../testdata");
|
||||
protected String TestDataAspectJPath = TestUtils.getPathToClasses("../testdata-aspectj");
|
||||
protected String GroovyTestDataPath = TestUtils.getPathToClasses("../testdata-groovy");
|
||||
protected String AspectjrtJar = "../testdata/aspectjrt.jar";
|
||||
protected String CodeJar = "../testdata/code.jar";
|
||||
@@ -105,7 +100,7 @@ public abstract class SpringLoadedTests implements Constants {
|
||||
public void setup() throws Exception {
|
||||
SpringLoadedPreProcessor.disabled = true;
|
||||
NameRegistry.reset();
|
||||
binLoader = new TestClassLoader(toURLs(TestDataPath, AspectjrtJar, CodeJar, Java8CodeJar), this.getClass().getClassLoader());
|
||||
binLoader = new TestClassLoader(toURLs(TestDataPath, TestDataAspectJPath, AspectjrtJar, CodeJar, Java8CodeJar), this.getClass().getClassLoader());
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
@@ -47,7 +47,7 @@ public class TestInfrastructureTests extends SpringLoadedTests {
|
||||
TestClassLoader tcl = new TestClassLoader(toURLs(TestDataPath), this.getClass().getClassLoader());
|
||||
byte[] classdata = Utils.loadDottedClassAsBytes(tcl, "data.SimpleClass");
|
||||
Assert.assertNotNull(classdata);
|
||||
Assert.assertEquals(394, classdata.length);
|
||||
Assert.assertEquals(331, classdata.length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
9
testdata-aspectj/.classpath
Normal file
9
testdata-aspectj/.classpath
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/main/java"/>
|
||||
<classpathentry kind="lib" path="/springloaded/lib/asm-3.2.jar"/>
|
||||
<classpathentry kind="lib" path="/springloaded/lib/asm-tree-3.2.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
18
testdata-aspectj/.project
Normal file
18
testdata-aspectj/.project
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>testdata-aspectj</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ajdt.core.ajbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.ajdt.ui.ajnature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
40
testdata-aspectj/build.gradle
Normal file
40
testdata-aspectj/build.gradle
Normal file
@@ -0,0 +1,40 @@
|
||||
def aspectjVersion = "1.8.0.M1"
|
||||
|
||||
configurations {
|
||||
aspects
|
||||
ajInpath
|
||||
}
|
||||
|
||||
dependencies {
|
||||
tools "org.aspectj:aspectjtools:$aspectjVersion"
|
||||
compile "org.aspectj:aspectjrt:$aspectjVersion"
|
||||
compile("cglib:cglib:2.2.2") { exclude group: 'asm' } // cglib 2.2.2 depends on asm 3.3
|
||||
compile 'org.ow2.asm:asm:5.0_BETA'
|
||||
compile 'org.ow2.asm:asm-tree:5.0_BETA'
|
||||
compile files("code.jar")
|
||||
}
|
||||
|
||||
compileJava.deleteAllActions()
|
||||
|
||||
task aspectJ(dependsOn: JavaPlugin.PROCESS_RESOURCES_TASK_NAME) {
|
||||
dependsOn configurations.tools.getTaskDependencyFromProjectDependency(true, "compileJava")
|
||||
def srcDirs = sourceSets.main.java.srcDirs
|
||||
srcDirs.each { inputs.dir it }
|
||||
def destDir = sourceSets.main.output.classesDir
|
||||
outputs.dir destDir
|
||||
doLast {
|
||||
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.tools.asPath)
|
||||
|
||||
ant.iajc(source:sourceCompatibility, target:targetCompatibility, destDir: destDir.absolutePath, maxmem:"512m", fork:"true",
|
||||
aspectPath: configurations.aspects.asPath, inpath:configurations.ajInpath.asPath, sourceRootCopyFilter:"**/.svn/*,**/*.java",classpath:configurations.compile.asPath ){
|
||||
sourceroots {
|
||||
srcDirs.each {
|
||||
if (it.exists()) pathelement location: it.absolutePath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compileJava.dependsOn aspectJ
|
||||
|
||||
1
testdata/.classpath
vendored
1
testdata/.classpath
vendored
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/main/java"/>
|
||||
<classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="code.jar"/>
|
||||
<classpathentry kind="lib" path="lib/cglib-nodep-2.2.jar"/>
|
||||
<classpathentry kind="lib" path="/springloaded/lib/asm-3.2.jar"/>
|
||||
|
||||
3
testdata/.project
vendored
3
testdata/.project
vendored
@@ -6,13 +6,12 @@
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ajdt.core.ajbuilder</name>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.ajdt.ui.ajnature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
39
testdata/build.gradle
vendored
39
testdata/build.gradle
vendored
@@ -1,40 +1,17 @@
|
||||
def aspectjVersion = "1.8.0.M1"
|
||||
|
||||
configurations {
|
||||
aspects
|
||||
ajInpath
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/*
|
||||
tools "org.aspectj:aspectjtools:$aspectjVersion"
|
||||
compile "org.aspectj:aspectjrt:$aspectjVersion"
|
||||
*/
|
||||
compile("cglib:cglib:2.2.2") { exclude group: 'asm' } // cglib 2.2.2 depends on asm 3.3
|
||||
compile 'org.ow2.asm:asm:5.0_BETA'
|
||||
compile 'org.ow2.asm:asm-tree:5.0_BETA'
|
||||
compile files("code.jar")
|
||||
}
|
||||
|
||||
compileJava.deleteAllActions()
|
||||
|
||||
task aspectJ(dependsOn: JavaPlugin.PROCESS_RESOURCES_TASK_NAME) {
|
||||
dependsOn configurations.tools.getTaskDependencyFromProjectDependency(true, "compileJava")
|
||||
def srcDirs = sourceSets.main.java.srcDirs
|
||||
srcDirs.each { inputs.dir it }
|
||||
def destDir = sourceSets.main.output.classesDir
|
||||
outputs.dir destDir
|
||||
doLast {
|
||||
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.tools.asPath)
|
||||
|
||||
ant.iajc(source:sourceCompatibility, target:targetCompatibility, destDir: destDir.absolutePath, maxmem:"512m", fork:"true",
|
||||
aspectPath: configurations.aspects.asPath, inpath:configurations.ajInpath.asPath, sourceRootCopyFilter:"**/.svn/*,**/*.java",classpath:configurations.compile.asPath ){
|
||||
sourceroots {
|
||||
srcDirs.each {
|
||||
if (it.exists()) pathelement location: it.absolutePath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDir 'src'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compileJava.dependsOn aspectJ
|
||||
|
||||
|
||||
Reference in New Issue
Block a user