8318913: The module-infos for --release data do not contain pre-set versions

Co-authored-by: Erik Joelsson <erikj@openjdk.org>
Reviewed-by: vromero, ihse
This commit is contained in:
Jan Lahoda 2023-11-24 06:30:08 +00:00
parent df1b896e01
commit fc314740e9
14 changed files with 549 additions and 263 deletions

View File

@ -608,11 +608,11 @@ endif
ifeq ($(CREATING_BUILDJDK), true)
# This target is only called by the recursive call below.
create-buildjdk-interim-image-helper: interim-image jdk.jlink-launchers \
java.base-copy jdk.jdeps-launchers
java.base-copy jdk.jdeps-launchers jdk.compiler-launchers
endif
BUILDJDK_MODULES := $(sort $(foreach m, jdk.jlink $(INTERIM_IMAGE_MODULES), \
$(call FindTransitiveDepsForModule, $m) $m))
BUILDJDK_MODULES := $(sort $(foreach m, jdk.jlink jdk.compiler \
$(INTERIM_IMAGE_MODULES), $(call FindTransitiveDepsForModule, $m) $m))
$(eval $(call SetupTarget, create-buildjdk-interim-image, \
MAKEFILE := Main, \
@ -971,7 +971,20 @@ else
jdk.jdeps-gendata: java
# The ct.sym generation uses all the moduleinfos as input
jdk.compiler-gendata: $(GENSRC_MODULEINFO_TARGETS)
jdk.compiler-gendata: $(GENSRC_MODULEINFO_TARGETS) $(JAVA_TARGETS)
# jdk.compiler-gendata needs the BUILD_JDK. If the BUILD_JDK was supplied
# externally, no extra prerequisites are needed.
ifeq ($(CREATE_BUILDJDK), true)
ifneq ($(CREATING_BUILDJDK), true)
# When cross compiling and an external BUILD_JDK wasn't supplied, it's
# produced by the create-buildjdk target.
jdk.compiler-gendata: create-buildjdk
endif
else ifeq ($(EXTERNAL_BUILDJDK), false)
# When not cross compiling, the BUILD_JDK is the interim jdk image, and
# the javac launcher is needed.
jdk.compiler-gendata: jdk.compiler-launchers
endif
# Declare dependencies between jmod targets.
# java.base jmod needs jrt-fs.jar and access to the jmods for all non

View File

@ -520,8 +520,8 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
# Don't presuppose SerialGC is present in the buildjdk. Also, we cannot test
# the buildjdk, but on the other hand we know what it will support.
BUILDJDK_JAVA_FLAGS_SMALL="-Xms32M -Xmx512M -XX:TieredStopAtLevel=1"
AC_SUBST(BUILDJDK_JAVA_FLAGS_SMALL)
BUILD_JAVA_FLAGS_SMALL="-Xms32M -Xmx512M -XX:TieredStopAtLevel=1"
AC_SUBST(BUILD_JAVA_FLAGS_SMALL)
JAVA_TOOL_FLAGS_SMALL=""
for f in $JAVA_FLAGS_SMALL; do

View File

@ -663,7 +663,7 @@ STRIPFLAGS:=@STRIPFLAGS@
JAVA_FLAGS:=@JAVA_FLAGS@
JAVA_FLAGS_BIG:=@JAVA_FLAGS_BIG@
JAVA_FLAGS_SMALL:=@JAVA_FLAGS_SMALL@
BUILDJDK_JAVA_FLAGS_SMALL:=@BUILDJDK_JAVA_FLAGS_SMALL@
BUILD_JAVA_FLAGS_SMALL:=@BUILD_JAVA_FLAGS_SMALL@
JAVA_TOOL_FLAGS_SMALL:=@JAVA_TOOL_FLAGS_SMALL@
# The *_CMD variables are defined separately to be easily overridden in bootcycle-spec.gmk
@ -690,6 +690,7 @@ JTREG_JAVA = @FIXPATH@ $(JTREG_JDK)/bin/java $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
BUILD_JAVA_FLAGS := @BOOTCYCLE_JVM_ARGS_BIG@
BUILD_JAVA=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS)
BUILD_JAVA_SMALL=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS_SMALL)
BUILD_JAVAC=@FIXPATH@ $(BUILD_JDK)/bin/javac
BUILD_JAR=@FIXPATH@ $(BUILD_JDK)/bin/jar

View File

@ -150,7 +150,9 @@ import com.sun.tools.javac.jvm.Target;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Pair;
import java.nio.file.DirectoryStream;
import java.util.Optional;
import java.util.function.Consumer;
/**
* A tool for processing the .sym.txt files.
@ -228,11 +230,25 @@ public class CreateSymbols {
*/
@SuppressWarnings("unchecked")
public void createSymbols(String ctDescriptionFileExtra, String ctDescriptionFile, String ctSymLocation,
long timestamp, String currentVersion, String systemModules) throws IOException {
long timestamp, String currentVersion, String preReleaseTag, String moduleClasses) throws IOException {
LoadDescriptions data = load(ctDescriptionFileExtra != null ? Paths.get(ctDescriptionFileExtra)
: null,
Paths.get(ctDescriptionFile));
int currentVersionParsed = Integer.parseInt(currentVersion);
currentVersion = Integer.toString(currentVersionParsed, Character.MAX_RADIX);
currentVersion = currentVersion.toUpperCase(Locale.ROOT);
String previousVersion = Integer.toString(currentVersionParsed - 1, Character.MAX_RADIX);
previousVersion = previousVersion.toUpperCase(Locale.ROOT);
//load current version classes:
Path moduleClassPath = Paths.get(moduleClasses);
loadVersionClassesFromDirectory(data.classes, data.modules, moduleClassPath, currentVersion, previousVersion);
stripNonExistentAnnotations(data);
splitHeaders(data.classes);
@ -241,12 +257,19 @@ public class CreateSymbols {
for (ModuleDescription md : data.modules.values()) {
for (ModuleHeaderDescription mhd : md.header) {
List<String> versionsList =
Collections.singletonList(mhd.versions);
writeModulesForVersions(directory2FileData,
md,
mhd,
versionsList);
mhd.versions,
version -> {
String versionString = Character.toString(version);
int versionNumber = Integer.parseInt(versionString, Character.MAX_RADIX);
versionString = Integer.toString(versionNumber);
if (versionNumber == currentVersionParsed && !preReleaseTag.isEmpty()) {
versionString = versionString + "-" + preReleaseTag;
}
return versionString;
});
List<String> packages = new ArrayList<>();
mhd.exports.stream()
.map(ExportsDescription::packageName)
@ -293,13 +316,6 @@ public class CreateSymbols {
}
}
currentVersion = Integer.toString(Integer.parseInt(currentVersion), Character.MAX_RADIX);
currentVersion = currentVersion.toUpperCase(Locale.ROOT);
openDirectory(directory2FileData, currentVersion + "/")
.add(new FileData(currentVersion + "/system-modules",
Files.readAllBytes(Paths.get(systemModules))));
try (OutputStream fos = new FileOutputStream(ctSymLocation);
OutputStream bos = new BufferedOutputStream(fos);
ZipOutputStream jos = new ZipOutputStream(bos)) {
@ -788,10 +804,14 @@ public class CreateSymbols {
void writeModulesForVersions(Map<String, Set<FileData>> directory2FileData,
ModuleDescription moduleDescription,
ModuleHeaderDescription header,
Iterable<String> versions)
String versions,
Function<Character, String> version2ModuleVersion)
throws IOException {
for (String ver : versions) {
writeModule(directory2FileData, moduleDescription, header, ver);
//ensure every module-info.class is written separatelly,
//so that the correct version is used for it:
for (char ver : versions.toCharArray()) {
writeModule(directory2FileData, moduleDescription, header, ver,
version2ModuleVersion);
}
}
@ -799,7 +819,8 @@ public class CreateSymbols {
void writeModule(Map<String, Set<FileData>> directory2FileData,
ModuleDescription moduleDescription,
ModuleHeaderDescription header,
String version) throws IOException {
char version,
Function<Character, String> version2ModuleVersion) throws IOException {
List<CPInfo> constantPool = new ArrayList<>();
constantPool.add(null);
int currentClass = addClass(constantPool, "module-info");
@ -807,7 +828,9 @@ public class CreateSymbols {
int[] interfaces = new int[0];
AccessFlags flags = new AccessFlags(header.flags);
Map<String, Attribute> attributesMap = new HashMap<>();
addAttributes(moduleDescription, header, constantPool, attributesMap);
String versionString = Character.toString(version);
addAttributes(moduleDescription, header, constantPool, attributesMap,
version2ModuleVersion.apply(version));
Attributes attributes = new Attributes(attributesMap);
CPInfo[] cpData = constantPool.toArray(new CPInfo[constantPool.size()]);
ConstantPool cp = new ConstantPool(cpData);
@ -823,7 +846,7 @@ public class CreateSymbols {
new Method[0],
attributes);
doWrite(directory2FileData, version, moduleDescription.name, "module-info" + EXTENSION, classFile);
doWrite(directory2FileData, versionString, moduleDescription.name, "module-info" + EXTENSION, classFile);
}
void writeClass(Map<String, Set<FileData>> directory2FileData,
@ -924,7 +947,8 @@ public class CreateSymbols {
private void addAttributes(ModuleDescription md,
ModuleHeaderDescription header,
List<CPInfo> cp,
Map<String, Attribute> attributes) {
Map<String, Attribute> attributes,
String moduleVersion) {
addGenericAttributes(header, cp, attributes);
if (header.moduleResolution != null) {
int attrIdx = addString(cp, Attribute.ModuleResolution);
@ -945,12 +969,13 @@ public class CreateSymbols {
attributes.put(Attribute.ModuleMainClass,
new ModuleMainClass_attribute(attrIdx, targetIdx));
}
int versionIdx = addString(cp, moduleVersion);
int attrIdx = addString(cp, Attribute.Module);
attributes.put(Attribute.Module,
new Module_attribute(attrIdx,
addModuleName(cp, md.name),
0,
0,
versionIdx,
header.requires
.stream()
.map(r -> createRequiresEntry(cp, r))
@ -1123,8 +1148,9 @@ public class CreateSymbols {
MethodParameters_attribute.Entry[] entries =
desc.methodParameters
.stream()
.map(p -> new MethodParameters_attribute.Entry(addString(constantPool, p.name),
p.flags))
.map(p -> new MethodParameters_attribute.Entry(p.name == null || p.name.isEmpty() ? 0
: addString(constantPool, p.name),
p.flags))
.toArray(s -> new MethodParameters_attribute.Entry[s]);
attributes.put(Attribute.MethodParameters,
new MethodParameters_attribute(attributeString, entries));
@ -1492,7 +1518,7 @@ public class CreateSymbols {
}
}
ExcludeIncludeList currentEIList = excludesIncludes;
ExcludeIncludeList currentEIList;
if (!currentVersionModules.isEmpty()) {
Set<String> privateIncludes =
@ -1509,19 +1535,182 @@ public class CreateSymbols {
currentEIList = new ExcludeIncludeList(includes,
privateIncludes,
Collections.emptySet());
} else {
currentEIList = excludesIncludes;
}
ClassList currentVersionClasses = new ClassList();
Map<String, String> extraModulesPackagesToDerive = new HashMap<>();
for (byte[] classFileData : classData) {
try (InputStream in = new ByteArrayInputStream(classFileData)) {
inspectClassFile(in, currentVersionClasses,
currentEIList, version);
currentEIList, version,
cf -> {
PermittedSubclasses_attribute permitted = (PermittedSubclasses_attribute) cf.getAttribute(Attribute.PermittedSubclasses);
if (permitted != null) {
try {
String currentPack = cf.getName().substring(0, cf.getName().lastIndexOf('/'));
for (int i = 0; i < permitted.subtypes.length; i++) {
String permittedClassName = cf.constant_pool.getClassInfo(permitted.subtypes[i]).getName();
if (!currentEIList.accepts(permittedClassName, false)) {
String permittedPack = permittedClassName.substring(0, permittedClassName.lastIndexOf('/'));
extraModulesPackagesToDerive.put(permittedPack, currentPack);
}
}
} catch (ConstantPoolException ex) {
throw new IllegalStateException(ex);
}
}
});
} catch (IOException | ConstantPoolException ex) {
throw new IllegalStateException(ex);
}
}
//derive extra module packages for permitted types based on on their supertypes:
boolean modified;
do {
modified = false;
for (Iterator<Entry<String, String>> it = extraModulesPackagesToDerive.entrySet().iterator(); it.hasNext();) {
Entry<String, String> e = it.next();
Optional<ModuleHeaderDescription> module = currentVersionModules.values().stream().map(md -> md.header.get(0)).filter(d -> containsPackage(d, e.getValue())).findAny();
if (module.isPresent()) {
if (!module.get().extraModulePackages.contains(e.getKey())) {
module.get().extraModulePackages.add(e.getKey());
}
it.remove();
modified = true;
}
}
} while (modified);
if (!extraModulesPackagesToDerive.isEmpty()) {
throw new AssertionError("Cannot derive some owning modules: " + extraModulesPackagesToDerive);
}
finishClassLoading(classes, modules, currentVersionModules, currentVersionClasses, currentEIList, version, baseline);
}
private boolean containsPackage(ModuleHeaderDescription module, String pack) {
return module.exports.stream().filter(ed -> ed.packageName().equals(pack)).findAny().isPresent() ||
module.extraModulePackages.contains(pack);
}
private void loadVersionClassesFromDirectory(ClassList classes,
Map<String, ModuleDescription> modules,
Path modulesDirectory,
String version,
String baseline) {
Map<String, ModuleDescription> currentVersionModules =
new HashMap<>();
ClassList currentVersionClasses = new ClassList();
Set<String> privateIncludes = new HashSet<>();
Set<String> includes = new HashSet<>();
ExcludeIncludeList currentEIList = new ExcludeIncludeList(includes,
privateIncludes,
Collections.emptySet());
try {
Map<Path, ModuleHeaderDescription> modulePath2Header = new HashMap<>();
List<Path> pendingExportedDirectories = new ArrayList<>();
try (DirectoryStream<Path> ds = Files.newDirectoryStream(modulesDirectory)) {
for (Path p : ds) {
Path moduleInfo = p.resolve("module-info.class");
if (Files.isReadable(moduleInfo)) {
ModuleDescription md;
try (InputStream in = Files.newInputStream(moduleInfo)) {
md = inspectModuleInfoClassFile(in,
currentVersionModules, version);
}
if (md == null) {
continue;
}
modulePath2Header.put(p, md.header.get(0));
Set<String> currentModuleExports =
md.header.get(0).exports.stream()
.filter(e -> !e.isQualified())
.map(e -> e.packageName + '/')
.collect(Collectors.toSet());
for (String dir : currentModuleExports) {
includes.add(dir);
pendingExportedDirectories.add(p.resolve(dir));
}
}
}
}
List<String> pendingExtraClasses = new ArrayList<>();
for (Path exported : pendingExportedDirectories) {
try (DirectoryStream<Path> ds = Files.newDirectoryStream(exported)) {
for (Path p2 : ds) {
if (!Files.isRegularFile(p2) || !p2.getFileName().toString().endsWith(".class")) {
continue;
}
loadFromDirectoryHandleClassFile(p2, currentVersionClasses,
currentEIList, version,
pendingExtraClasses);
}
}
}
while (!pendingExtraClasses.isEmpty()) {
String current = pendingExtraClasses.remove(pendingExtraClasses.size() - 1);
if (currentVersionClasses.find(current, true) != null) {
continue;
}
for (Entry<Path, ModuleHeaderDescription> e : modulePath2Header.entrySet()) {
Path currentPath = e.getKey().resolve(current + ".class");
if (Files.isReadable(currentPath)) {
String pack = current.substring(0, current.lastIndexOf('/'));
e.getValue().extraModulePackages.add(pack);
loadFromDirectoryHandleClassFile(currentPath, currentVersionClasses,
currentEIList, version,
pendingExtraClasses);
}
}
}
} catch (IOException | ConstantPoolException ex) {
throw new IllegalStateException(ex);
}
finishClassLoading(classes, modules, currentVersionModules, currentVersionClasses, currentEIList, version, baseline);
}
private void loadFromDirectoryHandleClassFile(Path path, ClassList currentVersionClasses,
ExcludeIncludeList currentEIList, String version,
List<String> todo) throws IOException, ConstantPoolException {
try (InputStream in = Files.newInputStream(path)) {
inspectClassFile(in, currentVersionClasses,
currentEIList, version,
cf -> {
Set<String> superTypes = otherRelevantTypesWithOwners(cf);
currentEIList.privateIncludeList.addAll(superTypes);
todo.addAll(superTypes);
});
}
}
private void finishClassLoading(ClassList classes, Map<String, ModuleDescription> modules, Map<String, ModuleDescription> currentVersionModules, ClassList currentVersionClasses, ExcludeIncludeList currentEIList, String version,
String baseline) {
ModuleDescription unsupported =
currentVersionModules.get("jdk.unsupported");
@ -1563,6 +1752,11 @@ public class CreateSymbols {
for (String i : header.implementsAttr) {
modified |= include(includedClasses, currentVersionClasses, i);
}
if (header.permittedSubclasses != null) {
for (String i : header.permittedSubclasses) {
modified |= include(includedClasses, currentVersionClasses, i);
}
}
modified |= includeOutputType(Collections.singleton(header),
h -> "",
@ -1962,6 +2156,11 @@ public class CreateSymbols {
public static boolean ALLOW_NON_EXISTING_CLASSES = false;
private void inspectClassFile(InputStream in, ClassList classes, ExcludeIncludeList excludesIncludes, String version) throws IOException, ConstantPoolException {
inspectClassFile(in, classes, excludesIncludes, version, cf -> {});
}
private void inspectClassFile(InputStream in, ClassList classes, ExcludeIncludeList excludesIncludes, String version,
Consumer<ClassFile> extraTask) throws IOException, ConstantPoolException {
ClassFile cf = ClassFile.read(in);
if (cf.access_flags.is(AccessFlags.ACC_MODULE)) {
@ -1972,6 +2171,8 @@ public class CreateSymbols {
return ;
}
extraTask.accept(cf);
ClassHeaderDescription headerDesc = new ClassHeaderDescription();
headerDesc.flags = cf.access_flags.flags;
@ -2032,13 +2233,13 @@ public class CreateSymbols {
}
}
private void inspectModuleInfoClassFile(InputStream in,
private ModuleDescription inspectModuleInfoClassFile(InputStream in,
Map<String, ModuleDescription> modules,
String version) throws IOException, ConstantPoolException {
ClassFile cf = ClassFile.read(in);
if (!cf.access_flags.is(AccessFlags.ACC_MODULE)) {
return ;
return null;
}
ModuleHeaderDescription headerDesc = new ModuleHeaderDescription();
@ -2048,7 +2249,7 @@ public class CreateSymbols {
for (Attribute attr : cf.attributes) {
if (!readAttribute(cf, headerDesc, attr))
return ;
return null;
}
String name = headerDesc.name;
@ -2062,6 +2263,8 @@ public class CreateSymbols {
}
addModuleHeader(moduleDesc, headerDesc, version);
return moduleDesc;
}
private Set<String> enhancedIncludesListBasedOnClassHeaders(ClassList classes,
@ -2072,29 +2275,7 @@ public class CreateSymbols {
try (InputStream in = new ByteArrayInputStream(classFileData)) {
ClassFile cf = ClassFile.read(in);
if (cf.access_flags.is(AccessFlags.ACC_MODULE)) {
continue;
}
Set<String> additionalClasses = new HashSet<>();
if (cf.super_class != 0) {
additionalClasses.add(cf.getSuperclassName());
}
for (int i = 0; i < cf.interfaces.length; i++) {
additionalClasses.add(cf.getInterfaceName(i));
}
for (String additional : additionalClasses) {
int dollar;
additionalIncludes.add(additional);
while ((dollar = additional.lastIndexOf('$')) != (-1)) {
additional = additional.substring(0, dollar);
additionalIncludes.add(additional);
}
}
additionalIncludes.addAll(otherRelevantTypesWithOwners(cf));
} catch (IOException | ConstantPoolException ex) {
throw new IllegalStateException(ex);
}
@ -2103,6 +2284,46 @@ public class CreateSymbols {
return additionalIncludes;
}
private Set<String> otherRelevantTypesWithOwners(ClassFile cf) {
Set<String> supertypes = new HashSet<>();
try {
if (cf.access_flags.is(AccessFlags.ACC_MODULE)) {
return supertypes;
}
Set<String> additionalClasses = new HashSet<>();
if (cf.super_class != 0) {
additionalClasses.add(cf.getSuperclassName());
}
for (int i = 0; i < cf.interfaces.length; i++) {
additionalClasses.add(cf.getInterfaceName(i));
}
PermittedSubclasses_attribute permitted = (PermittedSubclasses_attribute) cf.getAttribute(Attribute.PermittedSubclasses);
if (permitted != null) {
for (int i = 0; i < permitted.subtypes.length; i++) {
additionalClasses.add(cf.constant_pool.getClassInfo(permitted.subtypes[i]).getName());
}
}
for (String additional : additionalClasses) {
int dollar;
supertypes.add(additional);
while ((dollar = additional.lastIndexOf('$')) != (-1)) {
additional = additional.substring(0, dollar);
supertypes.add(additional);
}
}
return supertypes;
} catch (ConstantPoolException ex) {
throw new IllegalStateException(ex);
}
}
private void addModuleHeader(ModuleDescription moduleDesc,
ModuleHeaderDescription headerDesc,
String version) {
@ -2115,7 +2336,9 @@ public class CreateSymbols {
}
}
headerDesc.versions += version;
if (!headerDesc.versions.contains(version)) {
headerDesc.versions += version;
}
if (!existed) {
moduleDesc.header.add(headerDesc);
@ -2159,7 +2382,9 @@ public class CreateSymbols {
}
}
headerDesc.versions += version;
if (!headerDesc.versions.contains(version)) {
headerDesc.versions += version;
}
if (!existed) {
clazzDesc.header.add(headerDesc);
@ -4415,22 +4640,25 @@ public class CreateSymbols {
String ctSymLocation;
String timestampSpec;
String currentVersion;
String systemModules;
String preReleaseTag;
String moduleClasses;
if (args.length == 6) {
if (args.length == 7) {
ctDescriptionFileExtra = null;
ctDescriptionFile = args[1];
ctSymLocation = args[2];
timestampSpec = args[3];
currentVersion = args[4];
systemModules = args[5];
} else if (args.length == 7) {
preReleaseTag = args[5];
moduleClasses = args[6];
} else if (args.length == 8) {
ctDescriptionFileExtra = args[1];
ctDescriptionFile = args[2];
ctSymLocation = args[3];
timestampSpec = args[4];
currentVersion = args[5];
systemModules = args[6];
preReleaseTag = args[6];
moduleClasses = args[7];
} else {
help();
return ;
@ -4446,7 +4674,8 @@ public class CreateSymbols {
ctSymLocation,
timestamp,
currentVersion,
systemModules);
preReleaseTag,
moduleClasses);
break;
}
case "build-javadoc-data": {

View File

@ -1,123 +0,0 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package build.tools.symbolgenerator;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import javax.lang.model.element.ModuleElement.RequiresDirective;
import javax.lang.model.util.Elements;
import javax.tools.JavaCompiler;
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.api.JavacTool;
import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.jvm.Target;
/**
* Write reflexive transitive closure of the given modules along their requires transitive edges into
* file <version>/system-modules in the specified directory.
*/
public class TransitiveDependencies {
private static void help() {
System.err.println("java TransitiveDependencies <target-directory> <module-source-path> <root-modules>");
}
public static void main(String... args) throws IOException {
if (args.length < 2) {
help();
return ;
}
JavaCompiler compiler = JavacTool.create();
List<String> options = List.of("-source", Source.DEFAULT.name,
"-target", Target.DEFAULT.name,
"-proc:only",
"--system", "none",
"--module-source-path", args[1],
"--add-modules", Arrays.stream(args)
.skip(2)
.collect(Collectors.joining(",")));
List<String> jlObjectList = List.of("java.lang.Object");
JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, null, null, options, jlObjectList, null);
task.enter();
Elements elements = task.getElements();
Deque<String> todo = new ArrayDeque<>();
Arrays.stream(args).skip(2).forEach(todo::add);
Set<String> allModules = new HashSet<>();
while (!todo.isEmpty()) {
String current = todo.removeFirst();
if (!allModules.add(current))
continue;
ModuleSymbol mod = (ModuleSymbol) elements.getModuleElement(current);
if (mod == null) {
throw new IllegalStateException("Missing: " + current);
}
//use the internal structure to avoid unnecessarily completing the symbol using the UsesProvidesVisitor:
for (RequiresDirective rd : mod.requires) {
if (rd.isTransitive()) {
todo.offerLast(rd.getDependency().getQualifiedName().toString());
}
}
}
allModules.add("java.base");
allModules.add("jdk.unsupported");
Path targetFile = Paths.get(args[0]);
Files.createDirectories(targetFile.getParent());
try (Writer w = Files.newBufferedWriter(targetFile);
PrintWriter out = new PrintWriter(w)) {
allModules.stream()
.sorted()
.forEach(out::println);
}
}
}

View File

@ -35,59 +35,54 @@ $(eval $(call IncludeCustomExtension, modules/jdk.compiler/Gendata.gmk))
# This is needed to properly setup DOCS_MODULES.
$(eval $(call ReadImportMetaData))
# Modules that should be visible for 9 - the documented modules:
CT_MODULES := $(DOCS_MODULES)
# Modules that should be visible - the documented modules:
CT_MODULES := $(filter-out $(MODULES_FILTER), $(DOCS_MODULES))
CT_TRANSITIVE_MODULES := $(call FindTransitiveIndirectDepsForModules, $(CT_MODULES))
CT_MODULES_API_TARGETS := \
$(foreach m, $(CT_MODULES) $(CT_TRANSITIVE_MODULES), \
$(call SetupJavaCompilationApiTarget, $m, $(JDK_OUTPUTDIR)/modules/$m))
# Get the complete module source path:
CT_MODULESOURCEPATH := $(call GetModuleSrcPath)
SYMBOL_FILES := $(wildcard $(MODULE_SRC)/share/data/symbols/*)
CT_DATA_DESCRIPTION += $(MODULE_SRC)/share/data/symbols/symbols
COMPILECREATESYMBOLS_ADD_EXPORTS := \
--add-exports java.base/jdk.internal.javac=java.compiler.interim,jdk.compiler.interim \
--add-exports jdk.internal.opt/jdk.internal.opt=jdk.compiler.interim,jdk.javadoc.interim \
--add-exports jdk.compiler.interim/com.sun.tools.javac.api=ALL-UNNAMED \
--add-exports jdk.compiler.interim/com.sun.tools.javac.code=ALL-UNNAMED \
--add-exports jdk.compiler.interim/com.sun.tools.javac.util=ALL-UNNAMED \
--add-exports jdk.compiler.interim/com.sun.tools.javac.jvm=ALL-UNNAMED \
--add-modules jdk.compiler,jdk.jdeps \
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED \
--add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
#
# TODO: Unify with jdk.javadoc-gendata. Should only compile this once and share.
$(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \
TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \
SRC := $(TOPDIR)/make/langtools/src/classes \
$(TOPDIR)/src/jdk.jdeps/share/classes, \
TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK), \
COMPILER := buildjdk, \
SRC := $(TOPDIR)/make/langtools/src/classes, \
INCLUDES := build/tools/symbolgenerator com/sun/tools/classfile, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javac, \
DISABLED_WARNINGS := options this-escape, \
JAVAC_FLAGS := \
$(INTERIM_LANGTOOLS_ARGS) \
$(COMPILECREATESYMBOLS_ADD_EXPORTS), \
))
$(SUPPORT_OUTPUTDIR)/symbols/ct.sym: \
$(COMPILE_CREATE_SYMBOLS) \
$(wildcard $(MODULE_SRC)/share/data/symbols/*) \
$(MODULE_INFOS)
$(SUPPORT_OUTPUTDIR)/symbols/ct.sym: $(COMPILE_CREATE_SYMBOLS) $(SYMBOL_FILES) \
$(MODULE_INFOS) $(CT_MODULES_API_TARGETS)
$(RM) -r $(@D)
$(MKDIR) -p $(@D)
$(ECHO) Creating ct.sym classes
$(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \
$(BUILD_JAVA_SMALL) \
$(COMPILECREATESYMBOLS_ADD_EXPORTS) \
-classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols \
build.tools.symbolgenerator.TransitiveDependencies \
$(@D)/system-modules \
$(CT_MODULESOURCEPATH) \
$(CT_MODULES)
$(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \
$(COMPILECREATESYMBOLS_ADD_EXPORTS) \
-classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols \
-classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javac \
build.tools.symbolgenerator.CreateSymbols \
build-ctsym \
$(CT_DATA_DESCRIPTION) \
$(@D)/ct.sym \
$(SOURCE_DATE_EPOCH) \
$(JDK_SOURCE_TARGET_VERSION) \
$(@D)/system-modules
"$(VERSION_PRE)" \
$(JDK_OUTPUTDIR)/modules/
$(TOUCH) $@
# Copy ct.sym to the modules libs dir

View File

@ -27,7 +27,6 @@ package com.sun.tools.javac.platform;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URI;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
@ -48,8 +47,6 @@ import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.processing.Processor;
import javax.tools.ForwardingJavaFileObject;
@ -71,8 +68,6 @@ import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.StringUtils;
import static java.nio.charset.StandardCharsets.UTF_8;
/** PlatformProvider for JDK N.
*
* <p><b>This is NOT part of any supported API.
@ -173,17 +168,8 @@ public class JDKPlatformProvider implements PlatformProvider {
"",
fileName + ".sig");
if (result == null) {
//in jrt://, the classfile may have the .class extension:
result = (JavaFileObject) getFileForInput(location,
"",
fileName + ".class");
}
if (result != null) {
return new SigJavaFileObject(result);
} else {
return null;
}
}
@ -262,7 +248,6 @@ public class JDKPlatformProvider implements PlatformProvider {
Path root = fs.getRootDirectories().iterator().next();
boolean hasModules =
Feature.MODULES.allowedInSource(Source.lookup(sourceVersion));
Path systemModules = root.resolve(ctSymVersion).resolve("system-modules");
if (!hasModules) {
List<Path> paths = new ArrayList<>();
@ -281,18 +266,6 @@ public class JDKPlatformProvider implements PlatformProvider {
}
fm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, paths);
} else if (Files.isRegularFile(systemModules)) {
fm.handleOption("--system", Arrays.asList("none").iterator());
Path jrtModules =
FileSystems.getFileSystem(URI.create("jrt:/"))
.getPath("modules");
try (Stream<String> lines =
Files.lines(systemModules, UTF_8)) {
lines.map(line -> jrtModules.resolve(line))
.filter(mod -> Files.exists(mod))
.forEach(mod -> setModule(fm, mod));
}
} else {
Map<String, List<Path>> module2Paths = new HashMap<>();
@ -327,16 +300,6 @@ public class JDKPlatformProvider implements PlatformProvider {
}
}
private static void setModule(StandardJavaFileManager fm, Path mod) {
try {
fm.setLocationForModule(StandardLocation.SYSTEM_MODULES,
mod.getFileName().toString(),
Collections.singleton(mod));
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
private static class SigJavaFileObject extends ForwardingJavaFileObject<JavaFileObject> {
public SigJavaFileObject(JavaFileObject fileObject) {

View File

@ -109,10 +109,10 @@ public class CanHandleClassFilesTest {
var createSymbolsClass = Class.forName("build.tools.symbolgenerator.CreateSymbols", false, cl);
var main = createSymbolsClass.getMethod("main", String[].class);
var symbols = targetDir.resolve("symbols");
var systemModules = targetDir.resolve("system-modules");
var modules = targetDir.resolve("modules");
try (Writer w = Files.newBufferedWriter(symbols)) {}
try (Writer w = Files.newBufferedWriter(systemModules)) {}
Files.createDirectories(modules);
main.invoke(null,
(Object) new String[] {"build-description-incremental",
@ -126,7 +126,8 @@ public class CanHandleClassFilesTest {
targetDir.resolve("ct.sym").toAbsolutePath().toString(),
Long.toString(System.currentTimeMillis() / 1000),
"" + SourceVersion.latest().ordinal(),
systemModules.toAbsolutePath().toString()});
"",
modules.toAbsolutePath().toString()});
}
}

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8318913
* @summary Verify correct module versions are recorded when --release is used.
* @library /tools/lib
* @modules
* java.base/jdk.internal.classfile
* java.base/jdk.internal.classfile.attribute
* java.base/jdk.internal.classfile.constantpool
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.platform
* jdk.compiler/com.sun.tools.javac.util:+open
* @run junit ModuleVersionTest
*/
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jdk.internal.classfile.Attributes;
import jdk.internal.classfile.ClassModel;
import jdk.internal.classfile.Classfile;
import jdk.internal.classfile.attribute.ModuleAttribute;
import jdk.internal.classfile.attribute.ModuleRequireInfo;
import org.junit.Test;
import toolbox.JavacTask;
import toolbox.ToolBox;
import static org.junit.Assert.*;
public class ModuleVersionTest {
private static final Pattern VERSION_PATTERN =
Pattern.compile("^([0-9]+)(.[0-9]+)*(-.*)?");
@Test
public void testVersionInDependency() throws Exception {
doTestVersionInDependency("11", "11");
String expectedVersion = System.getProperty("java.version");
Matcher m = VERSION_PATTERN.matcher(expectedVersion);
if (m.find()) {
String preRelease = m.group(3);
expectedVersion = m.group(1);
if (preRelease != null) {
expectedVersion += preRelease;
}
}
doTestVersionInDependency(System.getProperty("java.specification.version"), expectedVersion);
}
private void doTestVersionInDependency(String specificationVersion,
String expectedVersion) throws Exception {
Path root = Paths.get(".");
Path classes = root.resolve("classes");
Files.createDirectories(classes);
ToolBox tb = new ToolBox();
new JavacTask(tb)
.outdir(classes)
.options("--release", specificationVersion)
.sources("""
module test {}
""",
"""
package test;
public class Test {
}
""")
.run()
.writeAll();
Path moduleInfo = classes.resolve("module-info.class");
ClassModel clazz = Classfile.of().parse(moduleInfo);
assertTrue(clazz.isModuleInfo());
ModuleAttribute module = clazz.findAttribute(Attributes.MODULE).get();
ModuleRequireInfo req = module.requires().get(0);
assertEquals("java.base", req.requires().name().stringValue());
assertEquals(expectedVersion, req.requiresVersion().get().stringValue());
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8318913
* @summary Verify no error is when compiling a class whose permitted types are not exported
* @modules jdk.compiler
* @compile/fail/ref=NonExportedPermittedTypes.out -XDrawDiagnostics NonExportedPermittedTypes.java
* @compile/fail/ref=NonExportedPermittedTypes.out --release 21 -XDrawDiagnostics NonExportedPermittedTypes.java
* @compile/fail/ref=NonExportedPermittedTypes.out --release ${jdk.version} -XDrawDiagnostics NonExportedPermittedTypes.java
*/
import java.lang.constant.ConstantDesc;
public class NonExportedPermittedTypes {
public void test1(ConstantDesc cd) {
switch (cd) {
case String s -> {}
}
}
public void test2(ConstantDesc cd) {
switch (cd) {
case String s -> {}
default -> {}
}
}
}

View File

@ -0,0 +1,2 @@
NonExportedPermittedTypes.java:40:9: compiler.err.not.exhaustive.statement
1 error

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,7 @@
* @modules jdk.compiler
* jdk.jfr
* @compile --release 17 NonExportedSuperTypes.java
* @compile --release ${jdk.version} NonExportedSuperTypes.java
*/
import jdk.jfr.Event;

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8318913
* @summary Ensure release and enable-preview work well together.
* @modules jdk.compiler
* @compile --release ${jdk.version} --enable-preview ReleaseAndEnablePreview.java
*/
public class ReleaseAndEnablePreview {
public String evt(String str) {
return str.length() + "" + str.charAt(0);
}
}

View File

@ -751,14 +751,14 @@ public class CreateSymbolsTestImpl {
};
new CreateSymbols().createBaseLine(versions, acceptAll, ctSym, new String[0]);
Path symbolsDesc = ctSym.resolve("symbols");
Path systemModules = ctSym.resolve("systemModules");
Path modules = ctSym.resolve("modules");
Files.newBufferedWriter(systemModules).close();
Files.createDirectories(modules);
Path classesZip = output.resolve("classes.zip");
Path classesDir = output.resolve("classes");
new CreateSymbols().createSymbols(null, symbolsDesc.toAbsolutePath().toString(), classesZip.toAbsolutePath().toString(), 0, "9", systemModules.toString());
new CreateSymbols().createSymbols(null, symbolsDesc.toAbsolutePath().toString(), classesZip.toAbsolutePath().toString(), 0, "9", "", modules.toString());
try (JarFile jf = new JarFile(classesZip.toFile())) {
Enumeration<JarEntry> en = jf.entries();
@ -1037,12 +1037,12 @@ public class CreateSymbolsTestImpl {
}
}.createBaseLine(versions, acceptAll, descDest, new String[0]);
Path symbolsDesc = descDest.resolve("symbols");
Path systemModules = descDest.resolve("systemModules");
Path modules = descDest.resolve("modules");
Files.newBufferedWriter(systemModules).close();
Files.createDirectories(modules);
try {
new CreateSymbols().createSymbols(null, symbolsDesc.toAbsolutePath().toString(), classDest, 0, "8", systemModules.toString());
new CreateSymbols().createSymbols(null, symbolsDesc.toAbsolutePath().toString(), classDest, 0, "8", "", modules.toString());
} catch (Throwable t) {
t.printStackTrace();
throw t;