Skip to content

Commit e400e2d

Browse files
committed
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)
1 parent 526a4d0 commit e400e2d

20 files changed

+140
-55
lines changed

Diff for: settings.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
include "springloaded"
22
include "testdata"
33
include "testdata-java8"
4+
include "testdata-aspectj"
45
include "testdata-groovy"
56
include "testdata-plugin"
67
include "testdata-subloader"

Diff for: springloaded/.classpath

-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@
66
<classpathentry kind="lib" path="lib/asm-tree-5.0_BETA.jar"/>
77
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J180_b128"/>
88
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
9-
<classpathentry combineaccessrules="false" kind="src" path="/springloaded-java8"/>
109
<classpathentry kind="output" path="bin"/>
1110
</classpath>

Diff for: springloaded/build.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ dependencies {
4646

4747
testCompileOnly files("../testdata-groovy/groovy-all-1.8.6.jar")
4848
testCompileOnly project(':testdata')
49+
testCompileOnly project(':testdata-aspectj')
4950
testCompileOnly project(':testdata-groovy')
51+
testCompileOnly project(':testdata-java8')
5052
testCompileOnly project(':testdata-plugin')
5153
testCompileOnly project(':testdata-subloader')
5254
testCompileOnly project(':testdata-superloader')

Diff for: springloaded/src/main/java/org/springsource/loaded/ClassRenamer.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,15 @@ private String renameRetargetIfNecessary(String string) {
111111
}
112112
return string;
113113
}
114-
114+
115115
@Override
116116
public MethodVisitor visitMethod(int flags, String name, String descriptor, String signature, String[] exceptions) {
117117
if (descriptor.indexOf(oldname) != -1) {
118118
descriptor = descriptor.replace(oldname, newname);
119119
} else {
120+
if (descriptor.indexOf(oldname) != -1) {
121+
descriptor = descriptor.replace(oldname, newname);
122+
}
120123
for (String s : retargets.keySet()) {
121124
if (descriptor.indexOf(s) != -1) {
122125
descriptor = descriptor.replace(s, retargets.get(s));

Diff for: springloaded/src/main/java/org/springsource/loaded/ExecutorBuilder.java

+9
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,16 @@ public MethodVisitor visitMethod(int flags, String name, String descriptor, Stri
129129
if (name.charAt(1) != 'c') {
130130
// regular constructor
131131
// want to create the ___init___ handler for this constructor
132+
133+
// With the JDT compiler the inner class constructor gets an extra first parameter that is the type of
134+
// containing class. But with javac the inner class constructor gets an extra first parameter that is of
135+
// a special anonymous type (inner class of the containing class)
136+
// For example: class Foo { class Bar {}}
137+
// JDT: ctor in Bar is <init>(Foo) {}
138+
// JAVAC: ctor in Bar is <init>(Foo$1) {}
139+
132140
descriptor = Utils.insertExtraParameter(classname, descriptor);
141+
133142
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC_STATIC, mInitializerName, descriptor, signature, exceptions);
134143

135144
ConstructorCopier cc = new ConstructorCopier(mv, typeDescriptor, suffix, classname);

Diff for: springloaded/src/main/java/org/springsource/loaded/TypeDiffComputer.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,10 @@ private static void computeTypeDelta(ClassNode oldClassNode, ClassNode newClassN
625625
// td.setTypeVersionChange(oldClassNode.version, newClassNode.version);
626626
// }
627627
if (oldClassNode.access != newClassNode.access) {
628-
td.setTypeAccessChange(oldClassNode.access, newClassNode.access);
628+
// Is it only because of 0x20000 - that appears to represent Deprecated!
629+
if ((oldClassNode.access & 0xffff) != (newClassNode.access&0xffff)) {
630+
td.setTypeAccessChange(oldClassNode.access, newClassNode.access);
631+
}
629632
}
630633
if (!oldClassNode.name.equals(newClassNode.name)) {
631634
td.setTypeNameChange(oldClassNode.name, newClassNode.name);

Diff for: springloaded/src/main/java/org/springsource/loaded/support/Java8.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public class Java8 {
8787
* @param lookup
8888
* @return
8989
*/
90-
public static Object emulateInvokeDynamic(Class executorClass, Handle handle, Object[] bsmArgs, Object lookup, String indyNameAndDescriptor, Object[] indyParams) {
90+
public static Object emulateInvokeDynamic(Class<?> executorClass, Handle handle, Object[] bsmArgs, Object lookup, String indyNameAndDescriptor, Object[] indyParams) {
9191
try {
9292
CallSite callsite = callLambdaMetaFactory(bsmArgs,lookup,indyNameAndDescriptor,executorClass);
9393
return callsite.dynamicInvoker().invokeWithArguments(indyParams);
@@ -98,7 +98,7 @@ public static Object emulateInvokeDynamic(Class executorClass, Handle handle, Ob
9898
// 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!
9999

100100
// TODO [lambda] Need to handle altMetaFactory which is used when the lambdas are more 'complex' (e.g. Serializable)
101-
public static CallSite callLambdaMetaFactory(Object[] bsmArgs, Object lookup, String indyNameAndDescriptor,Class executorClass) throws Exception {
101+
public static CallSite callLambdaMetaFactory(Object[] bsmArgs, Object lookup, String indyNameAndDescriptor,Class<?> executorClass) throws Exception {
102102
MethodHandles.Lookup caller = (MethodHandles.Lookup)lookup;
103103

104104
ClassLoader callerLoader = caller.lookupClass().getClassLoader();

Diff for: springloaded/src/test/java/org/springsource/loaded/test/ExecutorBuilderTests.java

+20-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import static org.junit.Assert.assertEquals;
1919
import static org.junit.Assert.assertNotNull;
20+
import static org.junit.Assert.fail;
2021

2122
import java.lang.annotation.Annotation;
2223
import java.lang.reflect.Method;
@@ -262,7 +263,10 @@ public void typeLevelAnnotations2() {
262263
s.add(anno.toString());
263264
}
264265
Assert.assertTrue(s.remove("@common.Marker()"));
265-
Assert.assertTrue(s.remove("@common.Anno(someValue=37, longValue=2, id=abc)"));
266+
// Allow for alternate toString() variant
267+
if (!s.remove("@common.Anno(someValue=37, longValue=2, id=abc)")) {
268+
Assert.assertTrue(s.remove("@common.Anno(longValue=2, someValue=37, id=abc)"));
269+
}
266270
Assert.assertEquals(0, s.size());
267271
}
268272

@@ -296,7 +300,21 @@ public void methodLevelAnnotationsOnInterfaces() throws Exception {
296300
checkAnnotations(rtype.getLatestExecutorBytes(), "m2(Lexecutor/I;)V", "@common.Marker()", "@common.Anno(id=abc)");
297301
Method m = rtype.getLatestExecutorClass().getDeclaredMethod("m2", rtype.getClazz());
298302
assertEquals("@common.Marker()", m.getAnnotations()[0].toString());
299-
assertEquals("@common.Anno(someValue=37, longValue=2, id=abc)", printAnnotation(m.getAnnotations()[1]));
303+
assertIsOneOfThese(printAnnotation(m.getAnnotations()[1]),"@common.Anno(someValue=37, longValue=2, id=abc)", "@common.Anno(longValue=2, someValue=37, id=abc)");
304+
}
305+
306+
/**
307+
* Check the actual value is one of the possible options.
308+
*/
309+
private void assertIsOneOfThese(String actual, String... possibleValues) {
310+
StringBuilder buf = new StringBuilder();
311+
for (int i=0;i<possibleValues.length;i++) {
312+
if (actual.equals(possibleValues[i])) {
313+
return;
314+
}
315+
buf.append("'"+possibleValues[i]+"'").append("\n");
316+
}
317+
fail("The value:\n'"+actual+"'\n does not match one of these possible options:\n"+buf.toString());
300318
}
301319
//
302320
private String printAnnotation(Annotation a) {

Diff for: springloaded/src/test/java/org/springsource/loaded/test/FieldReloadingTests.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,11 @@ public void changingFieldFromStaticToNonstaticWithSubtypes() throws Exception {
564564
} catch (ResultException re) {
565565
assertTrue(re.getCause() instanceof InvocationTargetException);
566566
assertTrue(re.getCause().getCause() instanceof IncompatibleClassChangeError);
567-
assertEquals("Expected static field fields.Yb.j", re.getCause().getCause().getMessage());
567+
// When compiled with AspectJ vs Eclipse JDT the GETSTATIC actually varies.
568+
// With AspectJ it is: PUTSTATIC fields/Yb.j : I
569+
// With JDT (4.3) it is: PUTSTATIC fields/Zb.j : I
570+
// hence the error is different
571+
assertEquals("Expected static field fields.Zb.j", re.getCause().getCause().getMessage());
568572
}
569573

570574
// Now should be an IncompatibleClassChangeError
@@ -574,7 +578,11 @@ public void changingFieldFromStaticToNonstaticWithSubtypes() throws Exception {
574578
} catch (ResultException re) {
575579
assertTrue(re.getCause() instanceof InvocationTargetException);
576580
assertTrue(re.getCause().getCause() instanceof IncompatibleClassChangeError);
577-
assertEquals("Expected static field fields.Yb.j", re.getCause().getCause().getMessage());
581+
// When compiled with AspectJ vs Eclipse JDT the GETSTATIC actually varies.
582+
// With AspectJ it is: GETSTATIC fields/Yb.j : I
583+
// With JDT (4.3) it is: GETSTATIC fields/Zb.j : I
584+
// hence the error is different
585+
assertEquals("Expected static field fields.Zb.j", re.getCause().getCause().getMessage());
578586
}
579587
}
580588

Diff for: springloaded/src/test/java/org/springsource/loaded/test/InnerClassesTests.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.junit.Test;
1919
import org.springsource.loaded.ReloadableType;
2020
import org.springsource.loaded.TypeRegistry;
21+
import org.springsource.loaded.test.infra.ClassPrinter;
2122

2223

2324
/**
@@ -68,11 +69,15 @@ public void reloadDefaultVisClass() throws Exception {
6869
public void reloadPrivateVisInner() throws Exception {
6970
String tclass = "inners.Three";
7071
TypeRegistry typeRegistry = getTypeRegistry("inners..*");
71-
typeRegistry.addType("inners.Three$Inner", retrieveRename("inners.Three$Inner", "inners.Three2$Inner"));
72+
73+
7274
ReloadableType rtype = typeRegistry.addType(tclass, loadBytesForClass(tclass));
7375
runUnguarded(rtype.getClazz(), "runner");
7476

75-
rtype.loadNewVersion("2", retrieveRename(tclass, tclass + "2", "inners.Three2$Inner:inners.Three$Inner"));
77+
// ReloadableType rtypeInner =
78+
typeRegistry.addType("inners.Three$Inner", retrieveRename("inners.Three$Inner", "inners.Three2$Inner","inners.Three2:inners.Three"));
79+
80+
rtype.loadNewVersion("2", retrieveRename(tclass, tclass + "2", "inners.Three2$Inner:inners.Three$Inner","inners.Three2:inners.Three"));
7681
runUnguarded(rtype.getClazz(), "runner");
7782
}
7883

@@ -84,11 +89,11 @@ public void reloadPrivateVisInner() throws Exception {
8489
public void reloadProtectedVisInner() throws Exception {
8590
String tclass = "inners.Four";
8691
TypeRegistry typeRegistry = getTypeRegistry("inners..*");
87-
typeRegistry.addType("inners.Four$Inner", retrieveRename("inners.Four$Inner", "inners.Four2$Inner"));
92+
typeRegistry.addType("inners.Four$Inner", retrieveRename("inners.Four$Inner", "inners.Four2$Inner","inners.Four2:inners.Four"));
8893
ReloadableType rtype = typeRegistry.addType(tclass, loadBytesForClass(tclass));
8994
runUnguarded(rtype.getClazz(), "runner");
9095

91-
rtype.loadNewVersion("2", retrieveRename(tclass, tclass + "2", "inners.Four2$Inner:inners.Four$Inner"));
96+
rtype.loadNewVersion("2", retrieveRename(tclass, tclass + "2", "inners.Four2$Inner:inners.Four$Inner","inners.Four2:inners.Four"));
9297
runUnguarded(rtype.getClazz(), "runner");
9398
}
9499
}

Diff for: springloaded/src/test/java/org/springsource/loaded/test/SpringLoadedTests.java

+2-7
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,7 @@
4747
import org.junit.After;
4848
import org.junit.Assert;
4949
import org.junit.Before;
50-
import org.objectweb.asm.AnnotationVisitor;
51-
import org.objectweb.asm.Attribute;
5250
import org.objectweb.asm.ClassReader;
53-
import org.objectweb.asm.ClassVisitor;
54-
import org.objectweb.asm.FieldVisitor;
55-
import org.objectweb.asm.MethodVisitor;
5651
import org.objectweb.asm.Type;
5752
import org.objectweb.asm.tree.AnnotationNode;
5853
import org.objectweb.asm.tree.ClassNode;
@@ -61,7 +56,6 @@
6156
import org.objectweb.asm.tree.MethodNode;
6257
import org.springsource.loaded.ClassRenamer;
6358
import org.springsource.loaded.Constants;
64-
import org.springsource.loaded.GlobalConfiguration;
6559
import org.springsource.loaded.ISMgr;
6660
import org.springsource.loaded.MethodMember;
6761
import org.springsource.loaded.NameRegistry;
@@ -92,6 +86,7 @@ public abstract class SpringLoadedTests implements Constants {
9286
protected ClassLoader binLoader;
9387

9488
protected String TestDataPath = TestUtils.getPathToClasses("../testdata");
89+
protected String TestDataAspectJPath = TestUtils.getPathToClasses("../testdata-aspectj");
9590
protected String GroovyTestDataPath = TestUtils.getPathToClasses("../testdata-groovy");
9691
protected String AspectjrtJar = "../testdata/aspectjrt.jar";
9792
protected String CodeJar = "../testdata/code.jar";
@@ -105,7 +100,7 @@ public abstract class SpringLoadedTests implements Constants {
105100
public void setup() throws Exception {
106101
SpringLoadedPreProcessor.disabled = true;
107102
NameRegistry.reset();
108-
binLoader = new TestClassLoader(toURLs(TestDataPath, AspectjrtJar, CodeJar, Java8CodeJar), this.getClass().getClassLoader());
103+
binLoader = new TestClassLoader(toURLs(TestDataPath, TestDataAspectJPath, AspectjrtJar, CodeJar, Java8CodeJar), this.getClass().getClassLoader());
109104
}
110105

111106
@After

Diff for: springloaded/src/test/java/org/springsource/loaded/test/TestInfrastructureTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void loading() {
4747
TestClassLoader tcl = new TestClassLoader(toURLs(TestDataPath), this.getClass().getClassLoader());
4848
byte[] classdata = Utils.loadDottedClassAsBytes(tcl, "data.SimpleClass");
4949
Assert.assertNotNull(classdata);
50-
Assert.assertEquals(394, classdata.length);
50+
Assert.assertEquals(331, classdata.length);
5151
}
5252

5353
}

Diff for: testdata-aspectj/.classpath

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="src" path="src/main/java"/>
4+
<classpathentry kind="lib" path="/springloaded/lib/asm-3.2.jar"/>
5+
<classpathentry kind="lib" path="/springloaded/lib/asm-tree-3.2.jar"/>
6+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
7+
<classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/>
8+
<classpathentry kind="output" path="bin"/>
9+
</classpath>

Diff for: testdata-aspectj/.project

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>testdata-aspectj</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.ajdt.core.ajbuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
</buildSpec>
14+
<natures>
15+
<nature>org.eclipse.ajdt.ui.ajnature</nature>
16+
<nature>org.eclipse.jdt.core.javanature</nature>
17+
</natures>
18+
</projectDescription>

Diff for: testdata-aspectj/build.gradle

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
def aspectjVersion = "1.8.0.M1"
2+
3+
configurations {
4+
aspects
5+
ajInpath
6+
}
7+
8+
dependencies {
9+
tools "org.aspectj:aspectjtools:$aspectjVersion"
10+
compile "org.aspectj:aspectjrt:$aspectjVersion"
11+
compile("cglib:cglib:2.2.2") { exclude group: 'asm' } // cglib 2.2.2 depends on asm 3.3
12+
compile 'org.ow2.asm:asm:5.0_BETA'
13+
compile 'org.ow2.asm:asm-tree:5.0_BETA'
14+
compile files("code.jar")
15+
}
16+
17+
compileJava.deleteAllActions()
18+
19+
task aspectJ(dependsOn: JavaPlugin.PROCESS_RESOURCES_TASK_NAME) {
20+
dependsOn configurations.tools.getTaskDependencyFromProjectDependency(true, "compileJava")
21+
def srcDirs = sourceSets.main.java.srcDirs
22+
srcDirs.each { inputs.dir it }
23+
def destDir = sourceSets.main.output.classesDir
24+
outputs.dir destDir
25+
doLast {
26+
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.tools.asPath)
27+
28+
ant.iajc(source:sourceCompatibility, target:targetCompatibility, destDir: destDir.absolutePath, maxmem:"512m", fork:"true",
29+
aspectPath: configurations.aspects.asPath, inpath:configurations.ajInpath.asPath, sourceRootCopyFilter:"**/.svn/*,**/*.java",classpath:configurations.compile.asPath ){
30+
sourceroots {
31+
srcDirs.each {
32+
if (it.exists()) pathelement location: it.absolutePath
33+
}
34+
}
35+
}
36+
}
37+
}
38+
39+
compileJava.dependsOn aspectJ
40+

Diff for: testdata/.classpath

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<classpath>
33
<classpathentry kind="src" path="src/main/java"/>
4-
<classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/>
54
<classpathentry kind="lib" path="code.jar"/>
65
<classpathentry kind="lib" path="lib/cglib-nodep-2.2.jar"/>
76
<classpathentry kind="lib" path="/springloaded/lib/asm-3.2.jar"/>

Diff for: testdata/.project

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@
66
</projects>
77
<buildSpec>
88
<buildCommand>
9-
<name>org.eclipse.ajdt.core.ajbuilder</name>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
1010
<arguments>
1111
</arguments>
1212
</buildCommand>
1313
</buildSpec>
1414
<natures>
15-
<nature>org.eclipse.ajdt.ui.ajnature</nature>
1615
<nature>org.eclipse.jdt.core.javanature</nature>
1716
</natures>
1817
</projectDescription>

Diff for: testdata/build.gradle

+8-31
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,17 @@
1-
def aspectjVersion = "1.8.0.M1"
2-
3-
configurations {
4-
aspects
5-
ajInpath
6-
}
7-
81
dependencies {
2+
/*
93
tools "org.aspectj:aspectjtools:$aspectjVersion"
104
compile "org.aspectj:aspectjrt:$aspectjVersion"
5+
*/
116
compile("cglib:cglib:2.2.2") { exclude group: 'asm' } // cglib 2.2.2 depends on asm 3.3
127
compile 'org.ow2.asm:asm:5.0_BETA'
138
compile 'org.ow2.asm:asm-tree:5.0_BETA'
149
compile files("code.jar")
1510
}
16-
17-
compileJava.deleteAllActions()
18-
19-
task aspectJ(dependsOn: JavaPlugin.PROCESS_RESOURCES_TASK_NAME) {
20-
dependsOn configurations.tools.getTaskDependencyFromProjectDependency(true, "compileJava")
21-
def srcDirs = sourceSets.main.java.srcDirs
22-
srcDirs.each { inputs.dir it }
23-
def destDir = sourceSets.main.output.classesDir
24-
outputs.dir destDir
25-
doLast {
26-
ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.tools.asPath)
27-
28-
ant.iajc(source:sourceCompatibility, target:targetCompatibility, destDir: destDir.absolutePath, maxmem:"512m", fork:"true",
29-
aspectPath: configurations.aspects.asPath, inpath:configurations.ajInpath.asPath, sourceRootCopyFilter:"**/.svn/*,**/*.java",classpath:configurations.compile.asPath ){
30-
sourceroots {
31-
srcDirs.each {
32-
if (it.exists()) pathelement location: it.absolutePath
33-
}
34-
}
35-
}
36-
}
11+
sourceSets {
12+
main {
13+
java {
14+
srcDir 'src'
15+
}
16+
}
3717
}
38-
39-
compileJava.dependsOn aspectJ
40-

0 commit comments

Comments
 (0)