Skip to content

Commit

Permalink
An attempt to allow source > 8 for javac-based modules.
Browse files Browse the repository at this point in the history
  • Loading branch information
undisclosed committed Mar 26, 2024
1 parent 3be92f1 commit c10394f
Show file tree
Hide file tree
Showing 5 changed files with 257 additions and 7 deletions.
212 changes: 212 additions & 0 deletions nbbuild/antsrc/org/netbeans/nbbuild/extlibs/SetupLimitModules.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/*
* 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.netbeans.nbbuild.extlibs;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.ProcessBuilder.Redirect;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

/**
*
*/
public class SetupLimitModules extends Task {

private String limitModulesProperty;
private String releaseVersion;
private String excludedModules;
private String nbjdkHome;
private File buildDir;
private File cacheFile;

public void setLimitModulesProperty(String limitModulesProperty) {
this.limitModulesProperty = limitModulesProperty;
}

public void setReleaseVersion(String releaseVersion) {
this.releaseVersion = releaseVersion;
}

public void setExcludedModules(String excludedModules) {
this.excludedModules = excludedModules;
}

public void setNbjdkHome(String nbjdkHome) {
this.nbjdkHome = nbjdkHome;
}

public void setBuildDir(File buildDir) {
this.buildDir = buildDir;
}

public void setCacheFile(File cacheFile) {
this.cacheFile = cacheFile;
}

@Override
public void execute() throws BuildException {
try {
Properties cache = new Properties();

if (cacheFile != null && cacheFile.canRead()) {
try (InputStream in = new FileInputStream(cacheFile)) {
cache.load(in);
}
}

String cacheKey = nbjdkHome + "-" + releaseVersion;
String limitedModules = cache.getProperty(cacheKey);

if (limitedModules == null) {
Path executable = buildDir.toPath().resolve("LimitModulesFromExcludeModules.java");
try (OutputStream out = Files.newOutputStream(executable);
Writer w = new OutputStreamWriter(out)) {
w.write(COMPUTE_LIMIT_MODULES);
}
List<String> command = new ArrayList<>();
command.add(new File(new File(nbjdkHome, "bin"), "java").getAbsolutePath());
command.add(executable.toFile().getAbsolutePath());
command.add(releaseVersion);
command.addAll(Arrays.asList(excludedModules.split(",")));
Process p = new ProcessBuilder(command).redirectError(Redirect.INHERIT).start();
p.waitFor();
StringBuilder limitModulesText = new StringBuilder();
InputStream in = p.getInputStream();
int r;
while ((r = in.read()) != (-1)) {
limitModulesText.append((char) r);
}
limitedModules = limitModulesText.toString().trim();
if (cacheFile != null) {
cache.put(cacheKey, limitedModules);

try (OutputStream out = new FileOutputStream(cacheFile)) {
cache.store(out, "");
}
}
}

getProject().setNewProperty(limitModulesProperty, limitedModules);
} catch (IOException | InterruptedException ex) {
throw new BuildException(ex);
}
}

private static final String COMPUTE_LIMIT_MODULES =
"""
import com.sun.source.util.JavacTask;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.ModuleElement.RequiresDirective;
import javax.lang.model.util.ElementFilter;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
public class LimitModulesFromExcludeModules {
public static void main(String[] args) throws IOException {
String release = args[0];
Set<String> excludedModules = new HashSet<>();
Arrays.stream(args)
.skip(1)
.forEach(excludedModules::add);
JavacTask task = (JavacTask)
ToolProvider.getSystemJavaCompiler()
.getTask(null, null, null, List.of("--release", release), null, List.of(new JFOImpl(URI.create("mem://Test.java"), "")));
task.analyze();
String limitModules =
task.getElements()
.getAllModuleElements()
.stream()
.filter(m -> !m.getQualifiedName().toString().startsWith("jdk.internal."))
.filter(m -> canInclude(m, excludedModules))
.map(m -> m.getQualifiedName())
.collect(Collectors.joining(","));
System.out.println(limitModules);
}
private static boolean canInclude(ModuleElement m, Set<String> excludes) {
return Collections.disjoint(transitiveDependencies(m), excludes);
}
private static Set<String> transitiveDependencies(ModuleElement m) {
List<ModuleElement> todo = new LinkedList<>();
Set<ModuleElement> seenModules = new HashSet<>();
todo.add(m);
while (!todo.isEmpty()) {
ModuleElement current = todo.remove(0);
if (seenModules.add(current)) {
for (RequiresDirective rd : ElementFilter.requiresIn(current.getDirectives())) {
todo.add(rd.getDependency());
}
}
}
return seenModules.stream()
.map(c -> c.getQualifiedName().toString())
.collect(Collectors.toSet());
}
private static final class JFOImpl extends SimpleJavaFileObject {
private final String content;
public JFOImpl(URI uri, String content) {
super(uri, Kind.SOURCE);
this.content = content;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return content;
}
}
}
""";
}
4 changes: 2 additions & 2 deletions nbbuild/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

<property name="build.ant.classes.dir" location="${nb.build.dir}/antclasses"/>
<mkdir dir="${build.ant.classes.dir}"/>
<javac srcdir="antsrc" destdir="${build.ant.classes.dir}" deprecation="true" debug="${build.compiler.debug}" source="1.8" target="1.8">
<javac srcdir="antsrc" destdir="${build.ant.classes.dir}" deprecation="true" debug="${build.compiler.debug}" release="17">
<classpath>
<pathelement location="${ant.core.lib}"/>
</classpath>
Expand Down Expand Up @@ -99,7 +99,7 @@
<include name="nbbuild/external/jsoup*.jar"/>
</fileset>
</path>
<javac srcdir="antsrc" destdir="${build.ant.classes.dir}" deprecation="true" debug="${build.compiler.debug}" source="1.8" target="1.8">
<javac srcdir="antsrc" destdir="${build.ant.classes.dir}" deprecation="true" debug="${build.compiler.debug}" release="17">
<classpath refid="bootstrap-cp"/>
<compilerarg line="-Xlint -Xlint:-serial"/>
</javac>
Expand Down
4 changes: 2 additions & 2 deletions nbbuild/nbproject/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,14 @@
<classpath mode="compile">${ant.core.lib}:${nb_all}/platform/javahelp/external/jhall-2.0_05.jar:${nb_all}/nbbuild/external/json-simple-1.1.1.jar:${nb_all}/nbbuild/external/external/jsoup-1.15.3.jar</classpath>
<built-to>${nb.build.dir}/antclasses</built-to>
<built-to>${nbantext.jar}</built-to>
<source-level>1.8</source-level>
<source-level>17</source-level>
</compilation-unit>
<compilation-unit>
<package-root>test/unit/src</package-root>
<unit-tests/>
<classpath mode="compile">${test.unit.cp}</classpath>
<built-to>${nb.build.dir}/test/unit/classes</built-to>
<source-level>1.8</source-level>
<source-level>17</source-level>
</compilation-unit>
</java-data>
</configuration>
Expand Down
15 changes: 14 additions & 1 deletion nbbuild/templates/common.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,22 @@
<compilerarg value="-Xbootclasspath/p:${bootclasspath.prepend}" />
</custom-javac>
</presetdef>
<property name="custom.javac.set" value="true" />
</target>

<target name="-javac-init-no-bootclasspath-prepend" depends="build-init" unless="bootclasspath.prepend">
<target name="-javac-init-limit-modules" depends="build-init" if="limit.modules.option.list">
<presetdef name="nb-javac">
<custom-javac>
<bootclasspath>
<path path="${nbjdk.bootclasspath}"/>
</bootclasspath>
<compilerarg value="--limit-modules=${limit.modules.option.list}" />
</custom-javac>
</presetdef>
<property name="custom.javac.set" value="true" />
</target>

<target name="-javac-init-no-bootclasspath-prepend" depends="build-init,-javac-init-bootclasspath-prepend,-javac-init-limit-modules" unless="custom.javac.set">
<presetdef name="nb-javac">
<custom-javac>
<bootclasspath>
Expand Down
29 changes: 27 additions & 2 deletions nbbuild/templates/projectized.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,35 @@
</fileset>
</path>
</pathconvert>
<taskdef name="setuplimitmodules" classname="org.netbeans.nbbuild.extlibs.SetupLimitModules" classpath="${nbantext.jar}"/>
<setuplimitmodules limitModulesProperty="nb.javac.limit.modules.nb"
releaseVersion="${javac.source}"
excludedModules="java.compiler,jdk.compiler"
nbjdkHome="${nbjdk.home}"
buildDir="${nb_all}/nbbuild/build"
cacheFile="${nb_all}/nbbuild/build/limit-modules-cache.properties" />
</target>
<target name="-init-bootclasspath-prepend-compile" depends="-init-compile-bootclasspath-nb">
<condition property="javac.source.8" value="true" else="false">
<or>
<equals arg1="${javac.source}" arg2="1.6" />
<equals arg1="${javac.source}" arg2="1.7" />
<equals arg1="${javac.source}" arg2="1.8" />
</or>
</condition>
<condition property="bootclasspath.prepend" value="${bootclasspath.prepend.nb}">
<istrue value="${requires.nb.javac}"/>
<and>
<istrue value="${requires.nb.javac}"/>
<istrue value="${javac.source.8}"/>
</and>
</condition>
<condition property="limit.modules.option.list" value="${nb.javac.limit.modules.nb}">
<and>
<istrue value="${requires.nb.javac}"/>
<not>
<istrue value="${javac.source.8}"/>
</not>
</and>
</condition>
</target>
<target name="-init-bootclasspath-prepend-run" depends="-init-bootclasspath-prepend-compile,-init-bootclasspath-prepend-run8,-init-bootclasspath-prepend-run9"/>
Expand All @@ -123,7 +148,7 @@
</condition>
</target>
<target name="-init-bootclasspath-prepend-run9" depends="-init-bootclasspath-prepend-compile" if="have-jdk-1.9">
<condition property="test.bootclasspath.prepend.args" value="--limit-modules=java.base,java.logging,java.xml,java.prefs,java.desktop,java.management,java.instrument,jdk.zipfs,java.scripting,java.naming,jdk.jdi,jdk.unsupported,java.sql">
<condition property="test.bootclasspath.prepend.args" value="--limit-modules=${nb.javac.limit.modules.nb}">
<and>
<istrue value="${requires.nb.javac}"/>
<not>
Expand Down

0 comments on commit c10394f

Please sign in to comment.