This is an automated email from the ASF dual-hosted git repository. sunlan pushed a commit to branch danielsun/jointcompilation-20200516 in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 43ba5f8eb393d9090b0bc7c0f13c69281e0a3175 Author: Daniel Sun <sun...@apache.org> AuthorDate: Sat May 16 16:13:45 2020 +0800 GROOVY-9556: Stub generated without the effect of AST transformation makes joint compilation fail --- .../tools/javac/JavaAwareCompilationUnit.java | 1 + .../groovy/tools/javac/JavacJavaCompiler.java | 16 +++++ src/test/groovy/bugs/Groovy9556.groovy | 84 ++++++++++++++++++++++ 3 files changed, 101 insertions(+) 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 d2b7800..cce5faf 100644 --- a/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareCompilationUnit.java +++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareCompilationUnit.java @@ -74,6 +74,7 @@ public class JavaAwareCompilationUnit extends CompilationUnit { Object memStub = options.get(CompilerConfiguration.MEM_STUB); if (memStub == null) { memStub = SystemUtil.getSystemPropertySafe("groovy.generate.stub.in.memory", "false"); + options.put(CompilerConfiguration.MEM_STUB, Boolean.parseBoolean((String) memStub)); } this.keepStubs = Boolean.TRUE.equals(options.get("keepStubs")); 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 cb35ad2..a31fe2d 100644 --- a/src/main/java/org/codehaus/groovy/tools/javac/JavacJavaCompiler.java +++ b/src/main/java/org/codehaus/groovy/tools/javac/JavacJavaCompiler.java @@ -21,6 +21,7 @@ package org.codehaus.groovy.tools.javac; import groovy.lang.GroovyClassLoader; import groovy.lang.GroovyObject; import org.apache.groovy.io.StringBuilderWriter; +import org.codehaus.groovy.GroovyBugError; import org.codehaus.groovy.control.CompilationUnit; import org.codehaus.groovy.control.CompilerConfiguration; import org.codehaus.groovy.control.messages.ExceptionMessage; @@ -38,6 +39,7 @@ import java.security.CodeSource; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -93,6 +95,20 @@ public class JavacJavaCompiler implements JavaCompiler { try (javax.tools.StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, DEFAULT_LOCALE, charset)) { Set<javax.tools.JavaFileObject> compilationUnitSet = cu.getJavaCompilationUnitSet(); // java stubs already added + Map<String, Object> options = this.config.getJointCompilationOptions(); + if (!Boolean.parseBoolean(options.get(CompilerConfiguration.MEM_STUB).toString())) { + // clear the java stubs in the source set of Java compilation + compilationUnitSet = new HashSet<>(); + + // use sourcepath to specify the root directory of java stubs + javacParameters.add("-sourcepath"); + final File stubDir = (File) options.get("stubDir"); + if (null == stubDir) { + throw new GroovyBugError("stubDir is not specified"); + } + javacParameters.add(stubDir.getAbsolutePath()); + } + // add java source files to compile fileManager.getJavaFileObjectsFromFiles( files.stream().map(File::new).collect(Collectors.toList()) diff --git a/src/test/groovy/bugs/Groovy9556.groovy b/src/test/groovy/bugs/Groovy9556.groovy new file mode 100644 index 0000000..978c1d6 --- /dev/null +++ b/src/test/groovy/bugs/Groovy9556.groovy @@ -0,0 +1,84 @@ +/* + * 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 + +final class Groovy9556 { +// .\gradlew --no-daemon --max-workers 2 :test --tests groovy.bugs.Groovy9556 --debug-jvm + @Test + void testInheritConstructors() { + def config = new CompilerConfiguration( + targetDirectory: File.createTempDir(), + jointCompilationOptions: [memStub: false] + ) + + def parentDir = File.createTempDir() + config.jointCompilationOptions.stubDir = parentDir + + try { + def a = new File(parentDir, 'CreateSignatureBase.java') + a.write ''' +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; + +public abstract class CreateSignatureBase implements SignatureInterface +{ + public CreateSignatureBase(KeyStore keystore, char[] pin) + throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, IOException, CertificateException + { } + @Override + public byte[] sign(InputStream content) throws IOException + { + return null; + } +} + +interface SignatureInterface { + byte[] sign(InputStream content) throws IOException; +} + ''' + def b = new File(parentDir, 'B.groovy') + b.write ''' +import groovy.transform.* + +@InheritConstructors class CreateSignature extends CreateSignatureBase { + void signPDF(String pdDocument, String out) { + + } +} + ''' + + def loader = new GroovyClassLoader(this.class.classLoader) + def cu = new JavaAwareCompilationUnit(config, loader) + cu.addSources(a, b) + cu.compile() + } finally { + parentDir.deleteDir() + config.targetDirectory.deleteDir() + } + } +}