You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2019/11/11 21:12:16 UTC

[groovy] 01/01: GROOVY-9197: Ant: separate compiler classpath from compilation classpath

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY-9197
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit a9201098a2d0898314a449ccc5a8161f80a6a4d4
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Nov 11 15:02:53 2019 -0600

    GROOVY-9197: Ant: separate compiler classpath from compilation classpath
---
 src/test/groovy/bugs/Groovy9197.groovy             |  61 +++++++++++++++++++++
 .../main/java/org/codehaus/groovy/ant/Groovyc.java |  46 ++++++++--------
 .../org/codehaus/groovy/ant/GroovycTest.xml        |  20 +++++++
 .../groovy/ant/MakesExternalReference.java         |  39 +++++++++++++
 .../org/codehaus/groovy/ant/commons-lang3-3.4.jar  | Bin 0 -> 434678 bytes
 .../org/codehaus/groovy/ant/GroovycTest.java       |   7 +++
 6 files changed, 150 insertions(+), 23 deletions(-)

diff --git a/src/test/groovy/bugs/Groovy9197.groovy b/src/test/groovy/bugs/Groovy9197.groovy
new file mode 100644
index 0000000..f752f35
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9197.groovy
@@ -0,0 +1,61 @@
+/*
+ *  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 org.codehaus.groovy.control.CompilerConfiguration
+import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit
+import org.junit.Test
+
+import static groovy.grape.Grape.resolve
+
+final class Groovy9197 {
+
+    @Test
+    void testJointCompilationClasspathPropagation() {
+        def uris = resolve(autoDownload:true, classLoader:new GroovyClassLoader(null),
+            [groupId:'org.apache.commons', artifactId:'commons-lang3', version:'3.9'])
+
+        def config = new CompilerConfiguration(
+            classpath: new File(uris[0]).path,
+            targetDirectory: File.createTempDir(),
+            jointCompilationOptions: [memStub: true]
+        )
+
+        def parentDir = File.createTempDir()
+        try {
+            def pojo = new File(parentDir, 'Pojo.java')
+            pojo.write '''
+                import static org.apache.commons.lang3.StringUtils.isEmpty;
+                public class Pojo {
+                    public static void main(String[] args) {
+                        assert !isEmpty(" ");
+                        assert isEmpty("");
+                    }
+                }
+            '''
+
+            def unit = new JavaAwareCompilationUnit(config)
+            unit.addSources(pojo)
+            unit.compile()
+        } finally {
+            parentDir.deleteDir()
+            config.targetDirectory.deleteDir()
+        }
+    }
+}
diff --git a/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/Groovyc.java b/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/Groovyc.java
index a7d41af..2f69931 100644
--- a/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/Groovyc.java
+++ b/subprojects/groovy-ant/src/main/java/org/codehaus/groovy/ant/Groovyc.java
@@ -31,6 +31,7 @@ import org.apache.tools.ant.types.Path;
 import org.apache.tools.ant.types.Reference;
 import org.apache.tools.ant.util.GlobPatternMapper;
 import org.apache.tools.ant.util.SourceFileScanner;
+import org.codehaus.groovy.GroovyBugError;
 import org.codehaus.groovy.control.CompilationUnit;
 import org.codehaus.groovy.control.CompilerConfiguration;
 import org.codehaus.groovy.control.SourceExtensionHandler;
@@ -38,7 +39,6 @@ import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 import org.codehaus.groovy.runtime.DefaultGroovyStaticMethods;
 import org.codehaus.groovy.tools.ErrorReporter;
 import org.codehaus.groovy.tools.FileSystemCompiler;
-import org.codehaus.groovy.tools.RootLoader;
 import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit;
 import picocli.CommandLine;
 
@@ -47,7 +47,6 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.Writer;
-import java.net.URL;
 import java.nio.charset.Charset;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -165,7 +164,6 @@ import java.util.StringTokenizer;
  * Can also be used from {@link groovy.ant.AntBuilder} to allow the build file to be scripted in Groovy.
  */
 public class Groovyc extends MatchingTask {
-    private static final URL[] EMPTY_URL_ARRAY = new URL[0];
     private static final File[] EMPTY_FILE_ARRAY = new File[0];
     private static final String[] EMPTY_STRING_ARRAY = new String[0];
 
@@ -1023,13 +1021,6 @@ public class Groovyc extends MatchingTask {
     }
 
     private void doForkCommandLineList(List<String> commandLineList, Path classpath, String separator) {
-        if (includeAntRuntime) {
-            classpath.addExisting(new Path(getProject()).concatSystemClasspath("last"));
-        }
-        if (includeJavaRuntime) {
-            classpath.addJavaRuntime();
-        }
-
         if (forkedExecutable != null && !forkedExecutable.isEmpty()) {
             commandLineList.add(forkedExecutable);
         } else {
@@ -1041,8 +1032,15 @@ public class Groovyc extends MatchingTask {
             }
             commandLineList.add(javaHome + separator + "bin" + separator + "java");
         }
-        commandLineList.add("-classpath");
-        commandLineList.add(getClasspathRelative(classpath));
+
+        ClassLoader parent = getClass().getClassLoader();
+        if (parent instanceof AntClassLoader) {
+            commandLineList.add("-classpath");
+            commandLineList.add(((AntClassLoader) parent).getClasspath());
+        } else {
+            // TODO: add enough classpath entries to support execution of FileSystemCompilerFacade
+            throw new AssertionError("not yet implemented");//getRuntimeConfigurableWrapper()?
+        }
 
         String fileEncoding = System.getProperty("file.encoding");
         if (fileEncoding != null && !fileEncoding.isEmpty()) {
@@ -1064,6 +1062,14 @@ public class Groovyc extends MatchingTask {
             commandLineList.add("-Dgroovy.default.scriptExtension=" + tmpExtension);
         }
         commandLineList.add(FileSystemCompilerFacade.class.getName());
+        commandLineList.add("--classpath");
+        if (includeAntRuntime) {
+            classpath.addExisting(new Path(getProject()).concatSystemClasspath("last"));
+        }
+        if (includeJavaRuntime) {
+            classpath.addJavaRuntime();
+        }
+        commandLineList.add(getClasspathRelative(classpath));
         if (forceLookupUnnamedFiles) {
             commandLineList.add("--forceLookupUnnamedFiles");
         }
@@ -1311,21 +1317,15 @@ public class Groovyc extends MatchingTask {
     }
 
     protected GroovyClassLoader buildClassLoaderFor() {
+        if (fork) {
+            throw new GroovyBugError("Cannot use Groovyc#buildClassLoaderFor() for forked compilation");
+        }
         // GROOVY-5044
-        if (!fork && !getIncludeantruntime()) {
+        if (!getIncludeantruntime()) {
             throw new IllegalArgumentException("The includeAntRuntime=false option is not compatible with fork=false");
         }
 
-        ClassLoader parent =
-                AccessController.doPrivileged(
-                        new PrivilegedAction<ClassLoader>() {
-                            @Override
-                            public ClassLoader run() {
-                                return getIncludeantruntime()
-                                        ? getClass().getClassLoader()
-                                        : new AntClassLoader(new RootLoader(EMPTY_URL_ARRAY, null), getProject(), getClasspath());
-                            }
-                        });
+        ClassLoader parent = getClass().getClassLoader();
         if (parent instanceof AntClassLoader) {
             AntClassLoader antLoader = (AntClassLoader) parent;
             String[] pathElm = antLoader.getClasspath().split(File.pathSeparator);
diff --git a/subprojects/groovy-ant/src/test-resources/org/codehaus/groovy/ant/GroovycTest.xml b/subprojects/groovy-ant/src/test-resources/org/codehaus/groovy/ant/GroovycTest.xml
index d4fb8d2..73bb824 100644
--- a/subprojects/groovy-ant/src/test-resources/org/codehaus/groovy/ant/GroovycTest.xml
+++ b/subprojects/groovy-ant/src/test-resources/org/codehaus/groovy/ant/GroovycTest.xml
@@ -187,6 +187,26 @@
         <groovyc srcdir="${srcPath}" destdir="${destPath}" includes="GroovycTest1.groovy" fork="false" includeAntRuntime="false"/>
     </target>
 
+    <!-- GROOVY-9197 -->
+    <target name="jointForkedCompilation_ExternalJarOnClasspath">
+        <presetdef name="compile">
+            <groovyc fork="true" includeantruntime="false">
+                <javac debug="true" source="${javaVersion}" target="${javaVersion}"/>
+            </groovyc>
+        </presetdef>
+
+        <path id="the.classpath">
+            <path refid="groovyMaterials"/>
+            <fileset file="commons-lang3-3.4.jar"/>
+        </path>
+
+        <compile srcdir="${srcPath}" destdir="${destPath}" includes="MakesExternalReference.java">
+            <classpath refid="the.classpath"/>
+        </compile>
+
+        <java classname="org.codehaus.groovy.ant.MakesExternalReference" classpathref="the.classpath"/>
+    </target>
+
     <target name="clean">
         <delete quiet="true">
             <fileset dir="${destPath}/org/codehaus/groovy/ant">
diff --git a/subprojects/groovy-ant/src/test-resources/org/codehaus/groovy/ant/MakesExternalReference.java b/subprojects/groovy-ant/src/test-resources/org/codehaus/groovy/ant/MakesExternalReference.java
new file mode 100644
index 0000000..e5d2c73
--- /dev/null
+++ b/subprojects/groovy-ant/src/test-resources/org/codehaus/groovy/ant/MakesExternalReference.java
@@ -0,0 +1,39 @@
+/*
+ *  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.ant;
+
+import java.io.*;
+
+import static org.apache.commons.lang3.StringUtils.isEmpty;
+
+public class MakesExternalReference {
+    public static void main(String[] args) throws IOException {
+        FileOutputStream fout = new FileOutputStream(
+            new File("target/classes/groovy/test/org/codehaus/groovy/ant/MakesExternalReference_Result.txt"));
+        try {
+            assert !isEmpty(" ");
+            fout.write("OK.".getBytes());
+        } finally {
+            try {
+                fout.close();
+            } catch (IOException ignore) {
+            }
+        }
+    }
+}
diff --git a/subprojects/groovy-ant/src/test-resources/org/codehaus/groovy/ant/commons-lang3-3.4.jar b/subprojects/groovy-ant/src/test-resources/org/codehaus/groovy/ant/commons-lang3-3.4.jar
new file mode 100644
index 0000000..8ec91d4
Binary files /dev/null and b/subprojects/groovy-ant/src/test-resources/org/codehaus/groovy/ant/commons-lang3-3.4.jar differ
diff --git a/subprojects/groovy-ant/src/test/groovy/org/codehaus/groovy/ant/GroovycTest.java b/subprojects/groovy-ant/src/test/groovy/org/codehaus/groovy/ant/GroovycTest.java
index cb60c5d..cec5dd6 100644
--- a/subprojects/groovy-ant/src/test/groovy/org/codehaus/groovy/ant/GroovycTest.java
+++ b/subprojects/groovy-ant/src/test/groovy/org/codehaus/groovy/ant/GroovycTest.java
@@ -252,6 +252,13 @@ public class GroovycTest extends GroovyTestCase {
         ensureFails("noForkNoAntRuntime");
     }
 
+    // GROOVY-9197
+    public void testJointCompilationPropagatesClasspath() {
+        ensureNotPresent("MakesExternalReference");
+        project.executeTarget("jointForkedCompilation_ExternalJarOnClasspath");
+        ensureResultOK("MakesExternalReference");
+    }
+
     private void ensureExecutes(String target) {
         ensureNotPresent("GroovycTest1");
         project.executeTarget(target);