From 160ffff9e9047d32adcaf451941d7f7a1ce61fff Mon Sep 17 00:00:00 2001 From: Carter Kozak Date: Sat, 2 Apr 2022 11:04:24 -0700 Subject: [PATCH] Compilation uses 'opens' values as 'exports' (#2167) Compilation uses 'opens' values as 'exports' --- changelog/@unreleased/pr-2167.v2.yml | 5 ++ .../plugins/BaselineModuleJvmArgs.java | 79 +++++++++---------- ...aselineModuleJvmArgsIntegrationTest.groovy | 50 ++++++++++++ 3 files changed, 94 insertions(+), 40 deletions(-) create mode 100644 changelog/@unreleased/pr-2167.v2.yml diff --git a/changelog/@unreleased/pr-2167.v2.yml b/changelog/@unreleased/pr-2167.v2.yml new file mode 100644 index 000000000..b87837738 --- /dev/null +++ b/changelog/@unreleased/pr-2167.v2.yml @@ -0,0 +1,5 @@ +type: improvement +improvement: + description: Compilation uses 'opens' values as 'exports' + links: + - https://github.com/palantir/gradle-baseline/pull/2167 diff --git a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineModuleJvmArgs.java b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineModuleJvmArgs.java index 0921cbecc..0c1d53d6b 100644 --- a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineModuleJvmArgs.java +++ b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/plugins/BaselineModuleJvmArgs.java @@ -94,9 +94,7 @@ public Iterable asArguments() { project); return ImmutableList.of(); } - // Annotation processors are executed at compile time - ImmutableList arguments = - collectAnnotationProcessorArgs(project, extension, sourceSet); + ImmutableList arguments = collectCompilationArgs(project, extension, sourceSet); project.getLogger() .debug( "BaselineModuleJvmArgs compiling {} on {} with exports: {}", @@ -130,39 +128,29 @@ public void execute(Task task) { CoreJavadocOptions coreOptions = (CoreJavadocOptions) options; ImmutableList info = collectClasspathInfo(project, sourceSet); List exportValues = Stream.concat( - extension.exports().get().stream(), - info.stream().flatMap(item -> item.exports().stream())) - .distinct() - .sorted() - .map(item -> item + "=ALL-UNNAMED") - .collect(ImmutableList.toImmutableList()); - List opens = Stream.concat( - extension.opens().get().stream(), - info.stream().flatMap(item -> item.opens().stream())) + // Compilation only supports exports, so we union with opens. + Stream.concat( + extension.exports().get().stream(), + extension.opens().get().stream()), + info.stream() + .flatMap(item -> Stream.concat( + item.exports().stream(), item.opens().stream()))) .distinct() .sorted() .map(item -> item + "=ALL-UNNAMED") .collect(ImmutableList.toImmutableList()); project.getLogger() .debug( - "BaselineModuleJvmArgs building {} on {} " - + "with exports: {} and opens: {}", + "BaselineModuleJvmArgs building {} on {} " + "with exports: {}", javadoc.getName(), project, - exportValues, - opens); + exportValues); if (!exportValues.isEmpty()) { coreOptions // options are automatically prefixed with '-' internally .addMultilineStringsOption("-add-exports") .setValue(exportValues); } - if (!opens.isEmpty()) { - coreOptions - // options are automatically prefixed with '-' internally - .addMultilineStringsOption("-add-opens") - .setValue(opens); - } } else { project.getLogger() .error( @@ -184,7 +172,7 @@ public void execute(Test test) { @Override public Iterable asArguments() { ImmutableList arguments = - collectClasspathArgs(project, extension, test.getClasspath()); + collectClasspathArgs(project, extension, test.getClasspath(), OpensMode.RUNTIME); project.getLogger() .debug( "BaselineModuleJvmArgs executing {} on {} with exports: {}", @@ -205,8 +193,8 @@ public void execute(JavaExec javaExec) { @Override public Iterable asArguments() { - ImmutableList arguments = - collectClasspathArgs(project, extension, javaExec.getClasspath()); + ImmutableList arguments = collectClasspathArgs( + project, extension, javaExec.getClasspath(), OpensMode.RUNTIME); project.getLogger() .debug( "BaselineModuleJvmArgs executing {} on {} with exports: {}", @@ -263,29 +251,35 @@ private static void addManifestAttribute( } } - private static ImmutableList collectAnnotationProcessorArgs( + private static ImmutableList collectCompilationArgs( Project project, BaselineModuleJvmArgsExtension extension, SourceSet sourceSet) { return collectClasspathArgs( project, extension, - project.getConfigurations().getByName(sourceSet.getAnnotationProcessorConfigurationName())); + project.getConfigurations().getByName(sourceSet.getAnnotationProcessorConfigurationName()), + OpensMode.COMPILATION); } private static ImmutableList collectClasspathArgs( - Project project, BaselineModuleJvmArgsExtension extension, FileCollection classpath) { + Project project, BaselineModuleJvmArgsExtension extension, FileCollection classpath, OpensMode mode) { ImmutableList classpathInfo = collectClasspathInfo(project, classpath); - Stream exports = Stream.concat( - extension.exports().get().stream(), - classpathInfo.stream().flatMap(info -> info.exports().stream())) - .distinct() - .sorted() - .flatMap(BaselineModuleJvmArgs::addExportArg); - Stream opens = Stream.concat( - extension.opens().get().stream(), classpathInfo.stream().flatMap(info -> info.opens().stream())) - .distinct() - .sorted() - .flatMap(BaselineModuleJvmArgs::addOpensArg); - return Stream.concat(exports, opens).collect(ImmutableList.toImmutableList()); + Stream allExports = Stream.concat( + extension.exports().get().stream(), classpathInfo.stream().flatMap(info -> info.exports().stream())); + Stream allOpens = Stream.concat( + extension.opens().get().stream(), classpathInfo.stream().flatMap(info -> info.opens().stream())); + switch (mode) { + case COMPILATION: + return Stream.concat(allExports, allOpens) + .distinct() + .sorted() + .flatMap(BaselineModuleJvmArgs::addExportArg) + .collect(ImmutableList.toImmutableList()); + case RUNTIME: + Stream exports = allExports.distinct().sorted().flatMap(BaselineModuleJvmArgs::addExportArg); + Stream opens = allOpens.distinct().sorted().flatMap(BaselineModuleJvmArgs::addOpensArg); + return Stream.concat(exports, opens).collect(ImmutableList.toImmutableList()); + } + throw new IllegalStateException("unknown mode: " + mode); } private static ImmutableList collectClasspathInfo(Project project, SourceSet sourceSet) { @@ -361,4 +355,9 @@ static Builder builder() { class Builder extends ImmutableJarManifestModuleInfo.Builder {} } + + enum OpensMode { + COMPILATION, + RUNTIME; + } } diff --git a/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineModuleJvmArgsIntegrationTest.groovy b/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineModuleJvmArgsIntegrationTest.groovy index bf479be39..32936f85e 100644 --- a/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineModuleJvmArgsIntegrationTest.groovy +++ b/gradle-baseline-java/src/test/groovy/com/palantir/baseline/BaselineModuleJvmArgsIntegrationTest.groovy @@ -75,6 +75,29 @@ class BaselineModuleJvmArgsIntegrationTest extends IntegrationSpec { runTasksSuccessfully('compileJava') } + def 'Compiles with locally defined opens'() { + when: + buildFile << ''' + application { + mainClass = 'com.Example' + } + moduleJvmArgs { + opens = ['jdk.compiler/com.sun.tools.javac.code'] + } + '''.stripIndent(true) + writeJavaSourceFile(''' + package com; + public class Example { + public static void main(String[] args) { + com.sun.tools.javac.code.Symbol.class.toString(); + } + } + '''.stripIndent(true)) + + then: + runTasksSuccessfully('compileJava') + } + def 'Builds javadoc with locally defined exports'() { when: buildFile << ''' @@ -102,6 +125,33 @@ class BaselineModuleJvmArgsIntegrationTest extends IntegrationSpec { runTasksSuccessfully('javadoc') } + def 'Builds javadoc with locally defined opens'() { + when: + buildFile << ''' + application { + mainClass = 'com.Example' + } + moduleJvmArgs { + opens = ['jdk.compiler/com.sun.tools.javac.code'] + } + '''.stripIndent(true) + writeJavaSourceFile(''' + package com; + public class Example { + /** + * Javadoc {@link com.sun.tools.javac.code.Symbol}. + * @param args Program arguments + */ + public static void main(String[] args) { + com.sun.tools.javac.code.Symbol.class.toString(); + } + } + '''.stripIndent(true)) + + then: + runTasksSuccessfully('javadoc') + } + def 'Runs with locally defined exports'() { when: buildFile << '''