This is an automated email from the ASF dual-hosted git repository. sunlan pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push: new 6616c35 GROOVY-8962: Provide an option to generate Java stubs in memory for better compilation performance (closes #855) 6616c35 is described below commit 6616c353b264e2c00d729d14983bcca53e6db950 Author: Daniel Sun <sun...@apache.org> AuthorDate: Mon Jan 21 21:21:11 2019 +0800 GROOVY-8962: Provide an option to generate Java stubs in memory for better compilation performance (closes #855) --- .../codehaus/groovy/control/CompilationUnit.java | 13 + .../groovy/control/CompilerConfiguration.java | 33 +- .../tools/javac/JavaAwareCompilationUnit.java | 17 +- .../groovy/tools/javac/JavaStubGenerator.java | 58 ++- .../groovy/tools/javac/JavacJavaCompiler.java | 112 ++++- .../groovy/tools/javac/MemJavaFileObject.java | 83 ++++ src/test/groovy/bugs/Groovy8962.groovy | 326 +++++++++++++++ .../groovy/control/CompilerConfigurationTest.java | 460 ++++++++++----------- .../TransformsAndCustomClassLoadersTest.groovy | 3 +- 9 files changed, 833 insertions(+), 272 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java index 5ecc461..765bb9e 100644 --- a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java +++ b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java @@ -53,6 +53,7 @@ import org.codehaus.groovy.transform.trait.TraitComposer; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; +import javax.tools.JavaFileObject; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -61,10 +62,12 @@ import java.net.URL; import java.security.CodeSource; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; /** * The CompilationUnit collects all compilation data as it is generated by the compiler system. @@ -111,6 +114,9 @@ public class CompilationUnit extends ProcessingUnit { LinkedList[] phaseOperations; LinkedList[] newPhaseOperations; + private Set<JavaFileObject> javaCompilationUnitSet = new HashSet<>(); + + /** * Initializes the CompilationUnit with defaults. */ @@ -1170,4 +1176,11 @@ public class CompilationUnit extends ProcessingUnit { this.classNodeResolver = classNodeResolver; } + public Set<JavaFileObject> getJavaCompilationUnitSet() { + return javaCompilationUnitSet; + } + + public void addJavaCompilationUnits(Set<JavaFileObject> javaCompilationUnitSet) { + this.javaCompilationUnitSet.addAll(javaCompilationUnitSet); + } } diff --git a/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java b/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java index 828bc31..34dc138 100644 --- a/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java +++ b/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java @@ -55,6 +55,9 @@ public class CompilerConfiguration { /** This (<code>"runtimeGroovydoc"</code>) is the Optimization Option value for enabling attaching {@link groovy.lang.Groovydoc} annotation*/ public static final String RUNTIME_GROOVYDOC = "runtimeGroovydoc"; + /** This (<code>"memStub"</code>) is the Optimization Option value for enabling generating stubs in memory*/ + public static final String MEM_STUB = "memStub"; + /** This (<code>"1.4"</code>) is the value for targetBytecode to compile for a JDK 1.4. **/ public static final String JDK4 = "1.4"; /** This (<code>"1.5"</code>) is the value for targetBytecode to compile for a JDK 1.5. **/ @@ -276,9 +279,12 @@ public class CompilerConfiguration { handleOptimizationOption(options, INVOKEDYNAMIC, "groovy.target.indy"); handleOptimizationOption(options, GROOVYDOC, "groovy.attach.groovydoc"); handleOptimizationOption(options, RUNTIME_GROOVYDOC, "groovy.attach.runtime.groovydoc"); - setOptimizationOptions(options); + Map<String, Object> jointCompilerOptions = new HashMap<>(4); + handleJointCompilationOption(jointCompilerOptions, MEM_STUB, "groovy.generate.stub.in.memory"); + setJointCompilationOptions(jointCompilerOptions); + try { String groovyAntlr4Opt = getSystemPropertySafe(GROOVY_ANTLR4_OPT); @@ -301,6 +307,16 @@ public class CompilerConfiguration { } } + private void handleJointCompilationOption(Map<String, Object> options, String optionName, String sysOptionName) { + boolean optionEnabled = getBooleanSafe(sysOptionName); + if (DEFAULT != null && Boolean.TRUE.equals(DEFAULT.getJointCompilationOptions().get(optionName))) { + optionEnabled = true; + } + if (optionEnabled) { + options.put(optionName, Boolean.TRUE); + } + } + /** * Copy constructor. Use this if you have a mostly correct configuration * for your compilation but you want to make a some changes programatically. @@ -972,6 +988,21 @@ public class CompilerConfiguration { return runtimeGroovydocEnabled; } + /** + * Check whether mem stub enabled + * @return the result + */ + public boolean isMemStubEnabled() { + Object memStubEnabled = this.getJointCompilationOptions().get(MEM_STUB); + + if (null == memStubEnabled) { + return false; + } + + return "true".equals(memStubEnabled.toString()); + } + + // See http://groovy.329449.n5.nabble.com/What-the-static-compile-by-default-tt5750118.html // https://issues.apache.org/jira/browse/GROOVY-8543 // diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareCompilationUnit.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareCompilationUnit.java index 5a26b4c..e8486d8 100644 --- a/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareCompilationUnit.java +++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareCompilationUnit.java @@ -48,6 +48,8 @@ public class JavaAwareCompilationUnit extends CompilationUnit { private JavaCompilerFactory compilerFactory = new JavacCompilerFactory(); private final File generationGoal; private final boolean keepStubs; + private final CompilerConfiguration configuration; + private final boolean memStubEnabled; public JavaAwareCompilationUnit(CompilerConfiguration configuration) { this(configuration, null, null); @@ -60,13 +62,16 @@ public class JavaAwareCompilationUnit extends CompilationUnit { public JavaAwareCompilationUnit(CompilerConfiguration configuration, GroovyClassLoader groovyClassLoader, GroovyClassLoader transformClassLoader) { super(configuration, null, groovyClassLoader, transformClassLoader); - javaSources = new LinkedList<String>(); + this.configuration = configuration; + this.memStubEnabled = configuration.isMemStubEnabled(); + this.javaSources = new LinkedList<String>(); Map options = configuration.getJointCompilationOptions(); - generationGoal = (File) options.get("stubDir"); + this.generationGoal = memStubEnabled ? null : (File) options.get("stubDir"); boolean useJava5 = CompilerConfiguration.isPostJDK5(configuration.getTargetBytecode()); String encoding = configuration.getSourceEncoding(); - stubGenerator = new JavaStubGenerator(generationGoal, false, useJava5, encoding); - keepStubs = Boolean.TRUE.equals(options.get("keepStubs")); + + this.stubGenerator = new JavaStubGenerator(generationGoal, false, useJava5, encoding); + this.keepStubs = Boolean.TRUE.equals(options.get("keepStubs")); addPhaseOperation(new PrimaryClassNodeOperation() { public void call(SourceUnit source, GeneratorContext context, ClassNode node) throws CompilationFailedException { @@ -106,6 +111,10 @@ public class JavaAwareCompilationUnit extends CompilationUnit { module.setImportsResolved(false); } try { + if (memStubEnabled) { + this.addJavaCompilationUnits(stubGenerator.getJavaStubCompilationUnitSet()); // add java stubs + } + JavaCompiler compiler = compilerFactory.createCompiler(getConfiguration()); compiler.compile(javaSources, this); } finally { diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java index 64b3ee9..8f4dabd 100644 --- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java +++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java @@ -53,6 +53,7 @@ import org.codehaus.groovy.tools.Utilities; import org.codehaus.groovy.transform.trait.Traits; import org.objectweb.asm.Opcodes; +import javax.tools.JavaFileObject; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; @@ -64,9 +65,11 @@ import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; public class JavaStubGenerator { private final boolean java5; @@ -84,7 +87,7 @@ public class JavaStubGenerator { this.requireSuperResolved = requireSuperResolved; this.java5 = java5; this.encoding = encoding; - outputPath.mkdirs(); + if (null != outputPath) outputPath.mkdirs(); // when outputPath is null, we generate stubs in memory } public JavaStubGenerator(final File outputPath) { @@ -98,6 +101,7 @@ public class JavaStubGenerator { dir.mkdirs(); } + private static final int DEFAULT_BUFFER_SIZE = 8 * 1024; // 8K public void generateClass(ClassNode classNode) throws FileNotFoundException { // Only attempt to render our self if our super-class is resolved, else wait for it @@ -112,22 +116,40 @@ public class JavaStubGenerator { // don't generate stubs for private classes, as they are only visible in the same file if ((classNode.getModifiers() & Opcodes.ACC_PRIVATE) != 0) return; + + if (null == outputPath) { + generateMemStub(classNode); + } else { + generateFileStub(classNode); + } + } + + private void generateMemStub(ClassNode classNode) { + Writer writer = new StringBuilderWriter(); + generateStubContent(classNode, writer); + + javaStubCompilationUnitSet.add(new MemJavaFileObject(classNode, writer.toString())); + } + + private void generateFileStub(ClassNode classNode) throws FileNotFoundException { String fileName = classNode.getName().replace('.', '/'); mkdirs(outputPath, fileName); toCompile.add(fileName); File file = new File(outputPath, fileName + ".java"); - Charset charset = Charset.forName(encoding); - - try (PrintWriter out = new PrintWriter( - new OutputStreamWriter( - new BufferedOutputStream( - new FileOutputStream(file), - DEFAULT_BUFFER_SIZE - ), - charset - ) - )) { + + Writer writer = new OutputStreamWriter( + new BufferedOutputStream( + new FileOutputStream(file), + DEFAULT_BUFFER_SIZE + ), + Charset.forName(encoding) + ); + generateStubContent(classNode, writer); + } + + private void generateStubContent(ClassNode classNode, Writer writer) { + try (PrintWriter out = new PrintWriter(writer)) { String packageName = classNode.getPackageName(); if (packageName != null) { out.println("package " + packageName + ";\n"); @@ -135,11 +157,10 @@ public class JavaStubGenerator { printImports(out, classNode); printClassContents(out, classNode); - } } - private void printClassContents(PrintWriter out, ClassNode classNode) throws FileNotFoundException { + private void printClassContents(PrintWriter out, ClassNode classNode) { if (classNode instanceof InnerClassNode && ((InnerClassNode) classNode).isAnonymous()) { // if it is an anonymous inner class, don't generate the stub code for it. return; @@ -988,6 +1009,8 @@ public class JavaStubGenerator { for (String path : toCompile) { new File(outputPath, path + ".java").delete(); } + + javaStubCompilationUnitSet.clear(); } private static String escapeSpecialChars(String value) { @@ -998,4 +1021,11 @@ public class JavaStubGenerator { private static boolean isInterfaceOrTrait(ClassNode cn) { return cn.isInterface() || Traits.isTrait(cn); } + + + private final Set<JavaFileObject> javaStubCompilationUnitSet = new HashSet<>(); + + public Set<JavaFileObject> getJavaStubCompilationUnitSet() { + return javaStubCompilationUnitSet; + } } diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavacJavaCompiler.java b/src/main/java/org/codehaus/groovy/tools/javac/JavacJavaCompiler.java index 908858c..c8a64b0 100644 --- a/src/main/java/org/codehaus/groovy/tools/javac/JavacJavaCompiler.java +++ b/src/main/java/org/codehaus/groovy/tools/javac/JavacJavaCompiler.java @@ -27,6 +27,9 @@ import org.codehaus.groovy.control.messages.ExceptionMessage; import org.codehaus.groovy.control.messages.SimpleMessage; import org.codehaus.groovy.runtime.DefaultGroovyMethods; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; import java.io.File; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; @@ -34,47 +37,107 @@ import java.lang.reflect.Method; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; +import java.nio.charset.Charset; import java.security.AccessController; import java.security.CodeSource; import java.security.PrivilegedAction; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; public class JavacJavaCompiler implements JavaCompiler { private static final String[] EMPTY_STRING_ARRAY = new String[0]; private final CompilerConfiguration config; + private final boolean memStubEnabled; + private final Charset charset; public JavacJavaCompiler(CompilerConfiguration config) { this.config = config; + this.memStubEnabled = config.isMemStubEnabled(); + this.charset = Charset.forName(config.getSourceEncoding()); + } + + private int doCompileWithJavac(CompilationUnit cu, String[] javacParameters, StringBuilderWriter javacOutput) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException { + int javacReturnValue = 0; + + Class javac = findJavac(cu); + Method method = null; + try { + method = javac.getMethod("compile", String[].class, PrintWriter.class); + PrintWriter writer = new PrintWriter(javacOutput); + Object ret = method.invoke(null, javacParameters, writer); + javacReturnValue = (Integer) ret; + } catch (NoSuchMethodException e) { } + if (method == null) { + method = javac.getMethod("compile", String[].class); + Object ret = method.invoke(null, new Object[]{javacParameters}); + javacReturnValue = (Integer) ret; + } + + return javacReturnValue; + } + + private boolean doCompileWithSystemJavaCompiler(CompilationUnit cu, List<String> files, String[] javacParameters, StringBuilderWriter javacOutput) { + javax.tools.JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, charset); + + final Set<JavaFileObject> compilationUnitSet = cu.getJavaCompilationUnitSet(); // java stubs already added + + // add java source files to compile + fileManager.getJavaFileObjectsFromFiles( + files.stream() + .map(File::new) + .collect(Collectors.toList()) + ).forEach(compilationUnitSet::add); + + javax.tools.JavaCompiler.CompilationTask compilationTask = compiler.getTask( + javacOutput, + fileManager, + null, + Arrays.asList(javacParameters), + Collections.emptyList(), + compilationUnitSet + ); + + return compilationTask.call(); } public void compile(List<String> files, CompilationUnit cu) { - String[] javacParameters = makeParameters(files, cu.getClassLoader()); - StringBuilderWriter javacOutput = null; + compile(files, cu, memStubEnabled); + } + + private void compile(List<String> files, CompilationUnit cu, boolean toCompileStubInMem) { + String[] javacParameters = makeParameters(files, cu.getClassLoader(), toCompileStubInMem); + StringBuilderWriter javacOutput = new StringBuilderWriter();; int javacReturnValue = 0; try { - Class javac = findJavac(cu); - Method method = null; - try { - method = javac.getMethod("compile", String[].class, PrintWriter.class); - javacOutput = new StringBuilderWriter(); - PrintWriter writer = new PrintWriter(javacOutput); - Object ret = method.invoke(null, javacParameters, writer); - javacReturnValue = (Integer) ret; - } catch (NoSuchMethodException e) { } - if (method == null) { - method = javac.getMethod("compile", String[].class); - Object ret = method.invoke(null, new Object[]{javacParameters}); - javacReturnValue = (Integer) ret; + if (toCompileStubInMem) { + try { + boolean successful = doCompileWithSystemJavaCompiler(cu, files, javacParameters, javacOutput); + if (!successful) { + javacReturnValue = 1; + } + } catch (IllegalArgumentException e) { + javacReturnValue = 2; // any of the options are invalid + cu.getErrorCollector().addFatalError(new ExceptionMessage(e, true, cu)); + } + } else { + try { + javacReturnValue = doCompileWithJavac(cu, javacParameters, javacOutput); + } catch (InvocationTargetException ite) { + cu.getErrorCollector().addFatalError(new ExceptionMessage((Exception) ite.getCause(), true, cu)); + } } - } catch (InvocationTargetException ite) { - cu.getErrorCollector().addFatalError(new ExceptionMessage((Exception) ite.getCause(), true, cu)); } catch (Exception e) { cu.getErrorCollector().addFatalError(new ExceptionMessage(e, true, cu)); } + if (javacReturnValue != 0) { switch (javacReturnValue) { case 1: addJavacError("Compile error during compilation with javac.", cu, javacOutput); break; @@ -101,7 +164,7 @@ public class JavacJavaCompiler implements JavaCompiler { cu.getErrorCollector().addFatalError(new SimpleMessage(header, cu)); } - private String[] makeParameters(List<String> files, GroovyClassLoader parentClassLoader) { + private String[] makeParameters(List<String> files, GroovyClassLoader parentClassLoader, boolean toCompileStubInMem) { Map options = config.getJointCompilationOptions(); LinkedList<String> paras = new LinkedList<String>(); @@ -111,8 +174,11 @@ public class JavacJavaCompiler implements JavaCompiler { // defaults paras.add("-d"); paras.add(target.getAbsolutePath()); - paras.add("-sourcepath"); - paras.add(((File) options.get("stubDir")).getAbsolutePath()); + + if (!toCompileStubInMem) { + paras.add("-sourcepath"); + paras.add(((File) options.get("stubDir")).getAbsolutePath()); + } // add flags String[] flags = (String[]) options.get("flags"); @@ -170,8 +236,10 @@ public class JavacJavaCompiler implements JavaCompiler { paras.add(DefaultGroovyMethods.join((Iterable) paths, File.pathSeparator)); } - // files to compile - paras.addAll(files); + if (!toCompileStubInMem) { + // files to compile + paras.addAll(files); + } return paras.toArray(EMPTY_STRING_ARRAY); } diff --git a/src/main/java/org/codehaus/groovy/tools/javac/MemJavaFileObject.java b/src/main/java/org/codehaus/groovy/tools/javac/MemJavaFileObject.java new file mode 100644 index 0000000..ca01472 --- /dev/null +++ b/src/main/java/org/codehaus/groovy/tools/javac/MemJavaFileObject.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.tools.javac; + +import groovy.lang.GroovyRuntimeException; +import org.codehaus.groovy.ast.ClassNode; + +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Objects; + +/** + * Represents a Java source file in memory to compile + * @since 3.0.0 + */ +public class MemJavaFileObject extends SimpleJavaFileObject { + private final String className; + private final String src; + + /** + * Construct a MemJavaFileObject instance with given groovy class node and stub source code + * + * @param classNode the groovy class node + * @param src the stub source code + */ + protected MemJavaFileObject(ClassNode classNode, String src) { + super(createURI(classNode), JavaFileObject.Kind.SOURCE); + this.className = classNode.getName(); + this.src = src; + } + + private static URI createURI(ClassNode classNode) { + try { + String packageName = classNode.getPackageName(); + String className = classNode.getNameWithoutPackage(); + + return new URI("string:///" + (null == packageName ? "" : (packageName.replace('.', '/') + "/")) + className + ".java"); + } catch (URISyntaxException e) { + throw new GroovyRuntimeException(e); + } + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return src; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof MemJavaFileObject)) return false; + MemJavaFileObject that = (MemJavaFileObject) o; + return Objects.equals(className, that.className); + } + + @Override + public int hashCode() { + return Objects.hash(className); + } + + @Override + public String toString() { + return className; + } +} diff --git a/src/test/groovy/bugs/Groovy8962.groovy b/src/test/groovy/bugs/Groovy8962.groovy new file mode 100644 index 0000000..1756dfa --- /dev/null +++ b/src/test/groovy/bugs/Groovy8962.groovy @@ -0,0 +1,326 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package groovy.bugs + +import junit.framework.TestCase +import org.codehaus.groovy.control.CompilerConfiguration +import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit + +class Groovy8962 extends GroovyTestCase { + void testShouldCompileProperly_memStub() { + def config = new CompilerConfiguration() + config.with { + targetDirectory = createTempDir() + jointCompilationOptions = [memStub: true] + } + + File parentDir = createTempDir() + try { + def a = new File(parentDir, 'A.groovy') + a.write ''' + class A { + Map<String, Map<String, Integer[]>> columnsMap = [:] + } + ''' + + def b = new File(parentDir, 'B.java') + b.write ''' + public class B { + public void f(A a) { + System.out.println(a.getColumnsMap()); + } + } + ''' + def loader = new GroovyClassLoader(this.class.classLoader) + def cu = new JavaAwareCompilationUnit(config, loader) + cu.addSources([a, b] as File[]) + cu.compile() + } finally { + parentDir.deleteDir() + config.targetDirectory?.deleteDir() + } + + } + + void testShouldCompileProperly2_memStub() { + def config = new CompilerConfiguration() + config.with { + targetDirectory = createTempDir() + jointCompilationOptions = [memStub: true] + } + + File parentDir = createTempDir() + try { + def a = new File(parentDir, 'A.groovy') + a.write ''' + class A { + Map<String, Map<String, List<Integer[]>[]>> columnsMap = [:] + } + ''' + + def b = new File(parentDir, 'B.java') + b.write ''' + public class B { + public void f(A a) { + System.out.println(a.getColumnsMap()); + } + } + ''' + def loader = new GroovyClassLoader(this.class.classLoader) + def cu = new JavaAwareCompilationUnit(config, loader) + cu.addSources([a, b] as File[]) + cu.compile() + } finally { + parentDir.deleteDir() + config.targetDirectory?.deleteDir() + } + + } + + void testShouldCompileProperly3_memStub() { + def config = new CompilerConfiguration() + config.with { + targetDirectory = createTempDir() + jointCompilationOptions = [memStub: true] + } + + File parentDir = createTempDir() + try { + def a = new File(parentDir, 'A.groovy') + a.write ''' + package x + import y.B + class A { + Map<String, Map<String, List<Integer[]>[]>> columnsMap = [:] + B b = null + } + ''' + + def b = new File(parentDir, 'B.java') + b.write ''' + package y; + import x.A; + public class B { + public void f(A a) { + System.out.println(a.getColumnsMap()); + } + } + ''' + def loader = new GroovyClassLoader(this.class.classLoader) + def cu = new JavaAwareCompilationUnit(config, loader) + cu.addSources([a, b] as File[]) + cu.compile() + } finally { + parentDir.deleteDir() + config.targetDirectory?.deleteDir() + } + + } + + void testShouldAllowConstantInSwitch_memStub() { + def config = new CompilerConfiguration() + config.with { + targetDirectory = createTempDir() + jointCompilationOptions = [memStub: true] + } + + File parentDir = createTempDir() + try { + def b = new File(parentDir, 'B.java') + b.write ''' + public class B { + public static void main(String...args) { + int x = 4; + switch (x) { + case groovy.bugs.Groovy8962.Constants.constant: x=1; + } + } + } + ''' + def loader = new GroovyClassLoader(this.class.classLoader) + addToClassPath(loader) + def cu = new JavaAwareCompilationUnit(config, loader) + cu.addSources([b] as File[]) + cu.compile() + } finally { + parentDir.deleteDir() + config.targetDirectory.deleteDir() + } + } + + void testShouldAllowConstantInSwitchWithStubs_memStub() { + def config = new CompilerConfiguration() + config.with { + targetDirectory = createTempDir() + jointCompilationOptions = [memStub: true] + } + + File parentDir = createTempDir() + try { + def a = new File(parentDir, 'A.groovy') + a.write ''' + class A { + public static final int constant = 1 + } + ''' + def b = new File(parentDir, 'B.java') + b.write ''' + public class B { + public static void main(String...args) { + int x = 4; + switch (x) { + case A.constant: x=1; + } + } + } + ''' + def loader = new GroovyClassLoader(this.class.classLoader) + addToClassPath(loader) + def cu = new JavaAwareCompilationUnit(config, loader) + cu.addSources([a, b] as File[]) + cu.compile() + } finally { + parentDir.deleteDir() + config.targetDirectory.deleteDir() + } + } + + static addToClassPath(GroovyClassLoader loader) { + loader.addURL(this.getProtectionDomain().getCodeSource().getLocation()) + loader.addURL(GroovyTestCase.class.getProtectionDomain().getCodeSource().getLocation()) + loader.addURL(TestCase.class.getProtectionDomain().getCodeSource().getLocation()) + } + + void testShouldAllowCharConstantInSwitchWithoutStubs_memStub() { + def config = new CompilerConfiguration() + config.with { + targetDirectory = createTempDir() + jointCompilationOptions = [memStub: true] + } + + File parentDir = createTempDir() + try { + def b = new File(parentDir, 'B.java') + b.write ''' + public class B { + public static void main(String...args) { + char x = 'z'; + switch (x) { + case groovy.bugs.Groovy8962.Constants.FOOCHAR: x='y'; + } + } + } + ''' + def loader = new GroovyClassLoader(this.class.classLoader) + config.setClasspathList([getClasspathElement(this.class), getClasspathElement(GroovyTestCase), getClasspathElement(TestCase)]) + def cu = new JavaAwareCompilationUnit(config, loader) + cu.addSources([b] as File[]) + cu.compile() + } finally { + parentDir.deleteDir() + config.targetDirectory.deleteDir() + } + } + + private static getClasspathElement(Class c) { + def codeSource = c.protectionDomain.codeSource + def file = new File(codeSource.getLocation().toURI()).getPath() + return file.toString() + } + + void testShouldAllowCharConstantInSwitchWithStubs_memStub() { + def config = new CompilerConfiguration() + config.with { + targetDirectory = createTempDir() + jointCompilationOptions = [memStub: true] + } + + File parentDir = createTempDir() + try { + def a = new File(parentDir, 'A.groovy') + a.write ''' + class A { + public static final char constant = 'x' + } + ''' + def b = new File(parentDir, 'B.java') + b.write ''' + public class B { + public static void main(String...args) { + char x = 'z'; + switch (x) { + case A.constant: x='y'; + } + } + } + ''' + def loader = new GroovyClassLoader(this.class.classLoader) + def cu = new JavaAwareCompilationUnit(config, loader) + cu.addSources([a, b] as File[]) + cu.compile() + } finally { + parentDir.deleteDir() + config.targetDirectory.deleteDir() + } + } + + void testAccessConstantStringFromJavaClass_memStub() { + def config = new CompilerConfiguration() + config.with { + targetDirectory = createTempDir() + jointCompilationOptions = [memStub: true] + } + + File parentDir = createTempDir() + try { + def a = new File(parentDir, 'A.groovy') + a.write ''' + class A { + public static final String CONSTANT = "hello, world!" + } + ''' + def b = new File(parentDir, 'B.java') + b.write ''' + public class B { + public static void main(String...args) { + if (!"hello, world!".equals(A.CONSTANT)) throw new RuntimeException("Constant should not be: ["+A.CONSTANT+"]"); + } + } + ''' + def loader = new GroovyClassLoader(this.class.classLoader) + def cu = new JavaAwareCompilationUnit(config, loader) + cu.addSources([a, b] as File[]) + cu.compile() + Class clazz = loader.loadClass("B") + clazz.newInstance().main() + } finally { + parentDir.deleteDir() + config.targetDirectory.deleteDir() + } + } + + private static File createTempDir() { + File.createTempDir("groovyTest${System.currentTimeMillis()}", "") + } + + static class Constants { + public static final int constant = 2 + public static final char FOOCHAR = 'x' + } +} diff --git a/src/test/org/codehaus/groovy/control/CompilerConfigurationTest.java b/src/test/org/codehaus/groovy/control/CompilerConfigurationTest.java index d1f7632..50816ab 100644 --- a/src/test/org/codehaus/groovy/control/CompilerConfigurationTest.java +++ b/src/test/org/codehaus/groovy/control/CompilerConfigurationTest.java @@ -1,230 +1,230 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.codehaus.groovy.control; - -import groovy.util.GroovyTestCase; -import org.codehaus.groovy.control.messages.WarningMessage; - -import java.io.File; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -/** - * Make sure CompilerConfiguration works. - */ -public class CompilerConfigurationTest extends GroovyTestCase { - Properties savedProperties; - - // Use setUp/tearDown to avoid mucking with system properties for other tests... - - public void setUp() { - savedProperties = System.getProperties(); - System.setProperties(new Properties(savedProperties)); - } - - public void tearDown() { - System.setProperties(savedProperties); - } - - public void testDefaultConstructor() { - final CompilerConfiguration config = CompilerConfiguration.DEFAULT; - - assertEquals(WarningMessage.LIKELY_ERRORS, config.getWarningLevel()); - assertEquals(Boolean.getBoolean("groovy.output.debug"), config.getDebug()); - assertEquals(Boolean.getBoolean("groovy.output.verbose"), config.getVerbose()); - assertEquals(false, config.getDebug()); - assertEquals(false, config.getVerbose()); - assertEquals(10, config.getTolerance()); - assertEquals(100, config.getMinimumRecompilationInterval()); - assertNull(config.getScriptBaseClass()); - assertEquals(getSystemEncoding(), config.getSourceEncoding()); - assertEquals(getVMVersion(), config.getTargetBytecode()); - assertEquals(false, config.getRecompileGroovySource()); - { - final List listCP = config.getClasspath(); - assertNotNull(listCP); - assertEquals(0, listCP.size()); - } - assertNull(config.getTargetDirectory()); - assertEquals(".groovy", config.getDefaultScriptExtension()); - assertNull(config.getJointCompilationOptions()); - assertNotNull(config.getPluginFactory()); - } - - private String getSystemEncoding() { - return System.getProperty("file.encoding", CompilerConfiguration.DEFAULT_SOURCE_ENCODING); - } - - private static String getVMVersion() { - return CompilerConfiguration.JDK8; - } - - public void testSetViaSystemProperties() { - System.setProperty("groovy.warnings", "PaRaNoiA"); - System.setProperty("groovy.output.verbose", "trUE"); - System.setProperty("groovy.recompile.minimumInterval", "867892345"); - - assertEquals("PaRaNoiA", System.getProperty("groovy.warnings")); - - final CompilerConfiguration config = new CompilerConfiguration(System.getProperties()); - - assertEquals(WarningMessage.PARANOIA, config.getWarningLevel()); - assertEquals(false, config.getDebug()); - assertEquals(true, config.getVerbose()); - assertEquals(10, config.getTolerance()); - assertEquals(867892345, config.getMinimumRecompilationInterval()); - assertNull(config.getScriptBaseClass()); - assertEquals(getSystemEncoding(), config.getSourceEncoding()); - assertEquals(getVMVersion(), config.getTargetBytecode()); - assertEquals(false, config.getRecompileGroovySource()); - { - final List listCP = config.getClasspath(); - assertNotNull(listCP); - assertEquals(0, listCP.size()); - } - assertNull(config.getTargetDirectory()); - assertEquals(".groovy", config.getDefaultScriptExtension()); - assertNull(config.getJointCompilationOptions()); - assertNotNull(config.getPluginFactory()); - } - - public void testCopyConstructor1() { - final CompilerConfiguration init = new CompilerConfiguration(); - - init.setWarningLevel(WarningMessage.POSSIBLE_ERRORS); - init.setDebug(true); - init.setParameters(true); - init.setVerbose(false); - init.setTolerance(720); - init.setMinimumRecompilationInterval(234); - init.setScriptBaseClass("blarg.foo.WhatSit"); - init.setSourceEncoding("LEAD-123"); - init.setTargetBytecode(CompilerConfiguration.POST_JDK5); - init.setRecompileGroovySource(true); - init.setClasspath("File1" + File.pathSeparator + "Somewhere"); - - final File initTDFile = new File("A wandering path"); - init.setTargetDirectory(initTDFile); - init.setDefaultScriptExtension(".jpp"); - - final Map initJoint = new HashMap(); - initJoint.put("somekey", "somevalue"); - init.setJointCompilationOptions(initJoint); - - final ParserPluginFactory initPPF = ParserPluginFactory.newInstance(); - init.setPluginFactory(initPPF); - - assertEquals(WarningMessage.POSSIBLE_ERRORS, init.getWarningLevel()); - assertEquals(true, init.getDebug()); - assertEquals(true, init.getParameters()); - assertEquals(false, init.getVerbose()); - assertEquals(720, init.getTolerance()); - assertEquals(234, init.getMinimumRecompilationInterval()); - assertEquals("blarg.foo.WhatSit", init.getScriptBaseClass()); - assertEquals("LEAD-123", init.getSourceEncoding()); - assertEquals(CompilerConfiguration.POST_JDK5, init.getTargetBytecode()); - assertEquals(true, init.getRecompileGroovySource()); - { - final List listCP = init.getClasspath(); - assertEquals("File1", listCP.get(0)); - assertEquals("Somewhere", listCP.get(1)); - } - assertEquals(initTDFile, init.getTargetDirectory()); - assertEquals(".jpp", init.getDefaultScriptExtension()); - assertEquals(initJoint, init.getJointCompilationOptions()); - assertEquals(initPPF, init.getPluginFactory()); - - final CompilerConfiguration config = new CompilerConfiguration(init); - - assertEquals(WarningMessage.POSSIBLE_ERRORS, config.getWarningLevel()); - assertEquals(true, config.getDebug()); - assertEquals(false, config.getVerbose()); - assertEquals(720, config.getTolerance()); - assertEquals(234, config.getMinimumRecompilationInterval()); - assertEquals("blarg.foo.WhatSit", config.getScriptBaseClass()); - assertEquals("LEAD-123", config.getSourceEncoding()); - assertEquals(CompilerConfiguration.POST_JDK5, config.getTargetBytecode()); - assertEquals(true, config.getRecompileGroovySource()); - { - final List listCP = config.getClasspath(); - assertEquals("File1", listCP.get(0)); - assertEquals("Somewhere", listCP.get(1)); - } - assertEquals(initTDFile, config.getTargetDirectory()); - assertEquals(".jpp", config.getDefaultScriptExtension()); - assertEquals(initJoint, config.getJointCompilationOptions()); - assertEquals(initPPF, config.getPluginFactory()); - - } - - public void testCopyConstructor2() { - final CompilerConfiguration init = new CompilerConfiguration(); - - init.setWarningLevel(WarningMessage.POSSIBLE_ERRORS); - init.setDebug(false); - init.setParameters(false); - init.setVerbose(true); - init.setTolerance(55); - init.setMinimumRecompilationInterval(975); - init.setScriptBaseClass(""); - init.setSourceEncoding("Gutenberg"); - init.setTargetBytecode(CompilerConfiguration.PRE_JDK5); - init.setRecompileGroovySource(false); - init.setClasspath(""); - - final File initTDFile = new File("A wandering path"); - init.setTargetDirectory(initTDFile); - - assertEquals(WarningMessage.POSSIBLE_ERRORS, init.getWarningLevel()); - assertEquals(false, init.getDebug()); - assertEquals(false, init.getParameters()); - assertEquals(true, init.getVerbose()); - assertEquals(55, init.getTolerance()); - assertEquals(975, init.getMinimumRecompilationInterval()); - assertEquals("", init.getScriptBaseClass()); - assertEquals("Gutenberg", init.getSourceEncoding()); - assertEquals(CompilerConfiguration.PRE_JDK5, init.getTargetBytecode()); - assertEquals(false, init.getRecompileGroovySource()); - { - final List listCP = init.getClasspath(); - assertNotNull(listCP); - assertEquals(0, listCP.size()); - } - assertEquals(initTDFile, init.getTargetDirectory()); - - final CompilerConfiguration config = new CompilerConfiguration(init); - - assertEquals(WarningMessage.POSSIBLE_ERRORS, config.getWarningLevel()); - assertEquals(false, config.getDebug()); - assertEquals(true, config.getVerbose()); - assertEquals(55, config.getTolerance()); - assertEquals(975, config.getMinimumRecompilationInterval()); - assertEquals("", config.getScriptBaseClass()); - assertEquals("Gutenberg", config.getSourceEncoding()); - assertEquals(CompilerConfiguration.PRE_JDK5, config.getTargetBytecode()); - assertEquals(false, config.getRecompileGroovySource()); - { - final List listCP = config.getClasspath(); - assertEquals(0, listCP.size()); - } - assertEquals(initTDFile, config.getTargetDirectory()); - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.control; + +import groovy.util.GroovyTestCase; +import org.codehaus.groovy.control.messages.WarningMessage; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * Make sure CompilerConfiguration works. + */ +public class CompilerConfigurationTest extends GroovyTestCase { + Properties savedProperties; + + // Use setUp/tearDown to avoid mucking with system properties for other tests... + + public void setUp() { + savedProperties = System.getProperties(); + System.setProperties(new Properties(savedProperties)); + } + + public void tearDown() { + System.setProperties(savedProperties); + } + + public void testDefaultConstructor() { + final CompilerConfiguration config = CompilerConfiguration.DEFAULT; + + assertEquals(WarningMessage.LIKELY_ERRORS, config.getWarningLevel()); + assertEquals(Boolean.getBoolean("groovy.output.debug"), config.getDebug()); + assertEquals(Boolean.getBoolean("groovy.output.verbose"), config.getVerbose()); + assertEquals(false, config.getDebug()); + assertEquals(false, config.getVerbose()); + assertEquals(10, config.getTolerance()); + assertEquals(100, config.getMinimumRecompilationInterval()); + assertNull(config.getScriptBaseClass()); + assertEquals(getSystemEncoding(), config.getSourceEncoding()); + assertEquals(getVMVersion(), config.getTargetBytecode()); + assertEquals(false, config.getRecompileGroovySource()); + { + final List listCP = config.getClasspath(); + assertNotNull(listCP); + assertEquals(0, listCP.size()); + } + assertNull(config.getTargetDirectory()); + assertEquals(".groovy", config.getDefaultScriptExtension()); + assertTrue(0 == config.getJointCompilationOptions().size()); + assertNotNull(config.getPluginFactory()); + } + + private String getSystemEncoding() { + return System.getProperty("file.encoding", CompilerConfiguration.DEFAULT_SOURCE_ENCODING); + } + + private static String getVMVersion() { + return CompilerConfiguration.JDK8; + } + + public void testSetViaSystemProperties() { + System.setProperty("groovy.warnings", "PaRaNoiA"); + System.setProperty("groovy.output.verbose", "trUE"); + System.setProperty("groovy.recompile.minimumInterval", "867892345"); + + assertEquals("PaRaNoiA", System.getProperty("groovy.warnings")); + + final CompilerConfiguration config = new CompilerConfiguration(System.getProperties()); + + assertEquals(WarningMessage.PARANOIA, config.getWarningLevel()); + assertEquals(false, config.getDebug()); + assertEquals(true, config.getVerbose()); + assertEquals(10, config.getTolerance()); + assertEquals(867892345, config.getMinimumRecompilationInterval()); + assertNull(config.getScriptBaseClass()); + assertEquals(getSystemEncoding(), config.getSourceEncoding()); + assertEquals(getVMVersion(), config.getTargetBytecode()); + assertEquals(false, config.getRecompileGroovySource()); + { + final List listCP = config.getClasspath(); + assertNotNull(listCP); + assertEquals(0, listCP.size()); + } + assertNull(config.getTargetDirectory()); + assertEquals(".groovy", config.getDefaultScriptExtension()); + assertTrue(0 == config.getJointCompilationOptions().size()); + assertNotNull(config.getPluginFactory()); + } + + public void testCopyConstructor1() { + final CompilerConfiguration init = new CompilerConfiguration(); + + init.setWarningLevel(WarningMessage.POSSIBLE_ERRORS); + init.setDebug(true); + init.setParameters(true); + init.setVerbose(false); + init.setTolerance(720); + init.setMinimumRecompilationInterval(234); + init.setScriptBaseClass("blarg.foo.WhatSit"); + init.setSourceEncoding("LEAD-123"); + init.setTargetBytecode(CompilerConfiguration.POST_JDK5); + init.setRecompileGroovySource(true); + init.setClasspath("File1" + File.pathSeparator + "Somewhere"); + + final File initTDFile = new File("A wandering path"); + init.setTargetDirectory(initTDFile); + init.setDefaultScriptExtension(".jpp"); + + final Map initJoint = new HashMap(); + initJoint.put("somekey", "somevalue"); + init.setJointCompilationOptions(initJoint); + + final ParserPluginFactory initPPF = ParserPluginFactory.newInstance(); + init.setPluginFactory(initPPF); + + assertEquals(WarningMessage.POSSIBLE_ERRORS, init.getWarningLevel()); + assertEquals(true, init.getDebug()); + assertEquals(true, init.getParameters()); + assertEquals(false, init.getVerbose()); + assertEquals(720, init.getTolerance()); + assertEquals(234, init.getMinimumRecompilationInterval()); + assertEquals("blarg.foo.WhatSit", init.getScriptBaseClass()); + assertEquals("LEAD-123", init.getSourceEncoding()); + assertEquals(CompilerConfiguration.POST_JDK5, init.getTargetBytecode()); + assertEquals(true, init.getRecompileGroovySource()); + { + final List listCP = init.getClasspath(); + assertEquals("File1", listCP.get(0)); + assertEquals("Somewhere", listCP.get(1)); + } + assertEquals(initTDFile, init.getTargetDirectory()); + assertEquals(".jpp", init.getDefaultScriptExtension()); + assertEquals(initJoint, init.getJointCompilationOptions()); + assertEquals(initPPF, init.getPluginFactory()); + + final CompilerConfiguration config = new CompilerConfiguration(init); + + assertEquals(WarningMessage.POSSIBLE_ERRORS, config.getWarningLevel()); + assertEquals(true, config.getDebug()); + assertEquals(false, config.getVerbose()); + assertEquals(720, config.getTolerance()); + assertEquals(234, config.getMinimumRecompilationInterval()); + assertEquals("blarg.foo.WhatSit", config.getScriptBaseClass()); + assertEquals("LEAD-123", config.getSourceEncoding()); + assertEquals(CompilerConfiguration.POST_JDK5, config.getTargetBytecode()); + assertEquals(true, config.getRecompileGroovySource()); + { + final List listCP = config.getClasspath(); + assertEquals("File1", listCP.get(0)); + assertEquals("Somewhere", listCP.get(1)); + } + assertEquals(initTDFile, config.getTargetDirectory()); + assertEquals(".jpp", config.getDefaultScriptExtension()); + assertEquals(initJoint, config.getJointCompilationOptions()); + assertEquals(initPPF, config.getPluginFactory()); + + } + + public void testCopyConstructor2() { + final CompilerConfiguration init = new CompilerConfiguration(); + + init.setWarningLevel(WarningMessage.POSSIBLE_ERRORS); + init.setDebug(false); + init.setParameters(false); + init.setVerbose(true); + init.setTolerance(55); + init.setMinimumRecompilationInterval(975); + init.setScriptBaseClass(""); + init.setSourceEncoding("Gutenberg"); + init.setTargetBytecode(CompilerConfiguration.PRE_JDK5); + init.setRecompileGroovySource(false); + init.setClasspath(""); + + final File initTDFile = new File("A wandering path"); + init.setTargetDirectory(initTDFile); + + assertEquals(WarningMessage.POSSIBLE_ERRORS, init.getWarningLevel()); + assertEquals(false, init.getDebug()); + assertEquals(false, init.getParameters()); + assertEquals(true, init.getVerbose()); + assertEquals(55, init.getTolerance()); + assertEquals(975, init.getMinimumRecompilationInterval()); + assertEquals("", init.getScriptBaseClass()); + assertEquals("Gutenberg", init.getSourceEncoding()); + assertEquals(CompilerConfiguration.PRE_JDK5, init.getTargetBytecode()); + assertEquals(false, init.getRecompileGroovySource()); + { + final List listCP = init.getClasspath(); + assertNotNull(listCP); + assertEquals(0, listCP.size()); + } + assertEquals(initTDFile, init.getTargetDirectory()); + + final CompilerConfiguration config = new CompilerConfiguration(init); + + assertEquals(WarningMessage.POSSIBLE_ERRORS, config.getWarningLevel()); + assertEquals(false, config.getDebug()); + assertEquals(true, config.getVerbose()); + assertEquals(55, config.getTolerance()); + assertEquals(975, config.getMinimumRecompilationInterval()); + assertEquals("", config.getScriptBaseClass()); + assertEquals("Gutenberg", config.getSourceEncoding()); + assertEquals(CompilerConfiguration.PRE_JDK5, config.getTargetBytecode()); + assertEquals(false, config.getRecompileGroovySource()); + { + final List listCP = config.getClasspath(); + assertEquals(0, listCP.size()); + } + assertEquals(initTDFile, config.getTargetDirectory()); + } +} diff --git a/src/test/org/codehaus/groovy/transform/classloading/TransformsAndCustomClassLoadersTest.groovy b/src/test/org/codehaus/groovy/transform/classloading/TransformsAndCustomClassLoadersTest.groovy index 456f8ab..18030fe 100644 --- a/src/test/org/codehaus/groovy/transform/classloading/TransformsAndCustomClassLoadersTest.groovy +++ b/src/test/org/codehaus/groovy/transform/classloading/TransformsAndCustomClassLoadersTest.groovy @@ -29,6 +29,7 @@ import org.codehaus.groovy.transform.GroovyASTTransformationClass import org.codehaus.groovy.transform.ASTTransformation import org.codehaus.groovy.transform.GroovyASTTransformation import org.codehaus.groovy.transform.GlobalTestTransformClassLoader +import org.codehaus.groovy.vmplugin.VMPluginFactory import org.objectweb.asm.ClassVisitor import java.lang.annotation.Retention @@ -43,7 +44,7 @@ import java.lang.annotation.ElementType */ class TransformsAndCustomClassLoadersTest extends GroovyTestCase { URL[] urls = collectUrls(getClass().classLoader) + addGroovyUrls() - GroovyClassLoader dependencyLoader = new GroovyClassLoader(new URLClassLoader(urls, (ClassLoader)null)) + GroovyClassLoader dependencyLoader = new GroovyClassLoader(new URLClassLoader(urls, (ClassLoader) ( VMPluginFactory.getPlugin().getVersion() >= 9 ? ClassLoader.getPlatformClassLoader() : null ))) GroovyClassLoader transformLoader = new GroovyClassLoader(new URLClassLoader(urls, new GroovyOnlyClassLoader())) private static addGroovyUrls() {