Skip to content

Commit 06e0549

Browse files
cushonbuchgr
authored andcommitted
'DumpPlatformClasspath' now dumps the current JDK's default platform classpath
instead of indirecting through javac's bootclasspath handling and attempting to pin to a particular source version. This is a stop-gap until we can just use javac's --release flag. Using the output of DumpPlatformClasspath as the bootclasspath for the default java_toolchain side-steps issues with @local_jdk (see #5744, #5594). PiperOrigin-RevId: 207890272
1 parent 0e84b67 commit 06e0549

File tree

4 files changed

+62
-146
lines changed

4 files changed

+62
-146
lines changed

src/java_tools/buildjar/BUILD

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ java_toolchain(
7777
# class path after -bootclasspath. For convenience, we currently have a
7878
# single jar that contains the contents of both the bootclasspath and
7979
# extdirs.
80-
bootclasspath = ["//tools/jdk:platformclasspath-impl.jar"],
81-
encoding = "UTF-8",
80+
bootclasspath = ["//tools/jdk:platformclasspath.jar"],
8281
extclasspath = [],
8382
genclass = ["bootstrap_genclass_deploy.jar"],
8483
ijar = ["//third_party/ijar"],

tools/android/BUILD.tools

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -97,26 +97,21 @@ java_binary(
9797
)
9898

9999
gen_java_lang_extras_jar_cmd = """
100-
for jar in $(locations @local_jdk//:bootclasspath); do
101-
if [[ "$${jar}" == *"/rt.jar" ]]; then
102-
$(location %s) \
103-
--exclude_build_data \
104-
--dont_change_compression \
105-
--sources $${jar} \
106-
--include_prefixes "java/lang/invoke/" \
107-
--include_prefixes "java/lang/annotation/" \
108-
--output $@
109-
break
110-
fi
111-
done
100+
$(location %s) \
101+
--exclude_build_data \
102+
--dont_change_compression \
103+
--sources $(location @bazel_tools//tools/jdk:platformclasspath) \
104+
--include_prefixes "java/lang/invoke/" \
105+
--include_prefixes "java/lang/annotation/" \
106+
--output $@
112107
"""
113108

114109
# javac needs this Jar to compile lambdas, method references, and type annotations.
115110
# These classes are not part of the android.jar.
116111
genrule(
117112
name = "gen_java_lang_extras_jar",
118113
srcs = [
119-
"@local_jdk//:bootclasspath"
114+
"@bazel_tools//tools/jdk:platformclasspath"
120115
],
121116
tools = select({
122117
"//src/conditions:windows": [":singlejar_javabin"],
@@ -178,15 +173,10 @@ genrule(
178173
srcs = ["desugar_jdk_libs.jar"],
179174
outs = ["desugared_java8_legacy_libs.jar"],
180175
cmd = """
181-
classpath=()
182-
for j in $(locations //tools/jdk:bootclasspath); do
183-
classpath+=("--classpath_entry")
184-
classpath+=("$${j}")
185-
done
186176
$(location :desugar_java8) \
187177
--input $< \
188178
--output $@ \
189-
"$${classpath[@]}" \
179+
--classpath_entry "$(location @bazel_tools//tools/jdk:platformclasspath)" \
190180
--core_library --allow_empty_bootclasspath \
191181
--nobest_effort_tolerate_missing_deps \
192182
--noemit_dependency_metadata_as_needed \
@@ -225,7 +215,7 @@ genrule(
225215
--dont_rewrite_core_library_invocation "java/util/Iterator#remove" """,
226216
tools = [
227217
":desugar_java8",
228-
"//tools/jdk:bootclasspath",
218+
"@bazel_tools//tools/jdk:platformclasspath",
229219
],
230220
visibility = ["//visibility:private"],
231221
)

tools/jdk/BUILD

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -190,42 +190,31 @@ alias(
190190
)
191191

192192
genrule(
193-
name = "gen_platformclasspath",
193+
name = "platformclasspath",
194194
srcs = ["DumpPlatformClassPath.java"],
195-
outs = ["platformclasspath-impl.jar"],
195+
outs = ["platformclasspath.jar"],
196196
cmd = """
197197
set -eu
198198
TMPDIR=$$(mktemp -d -t tmp.XXXXXXXX)
199199
$(JAVABASE)/bin/javac $< -d $$TMPDIR
200-
$(JAVA) -cp $$TMPDIR DumpPlatformClassPath 8 $@
200+
$(JAVA) -cp $$TMPDIR DumpPlatformClassPath $@
201201
rm -rf $$TMPDIR
202202
""",
203203
toolchains = ["@bazel_tools//tools/jdk:current_host_java_runtime"],
204204
tools = ["@bazel_tools//tools/jdk:current_host_java_runtime"],
205205
)
206206

207-
# run ijar separately so we can skip it for bootstrapping
208-
genrule(
209-
name = "platformclasspath",
210-
srcs = ["platformclasspath-impl.jar"],
211-
outs = ["platformclasspath.jar"],
212-
cmd = "$(location @bazel_tools//tools/jdk:ijar) $< $@",
213-
tools = ["@bazel_tools//tools/jdk:ijar"],
214-
)
215-
216207
default_java_toolchain(
217208
name = "toolchain_hostjdk8",
218-
bootclasspath = [":bootclasspath"],
219-
extclasspath = [":extclasspath"],
209+
bootclasspath = [":platformclasspath"],
220210
jvm_opts = JDK8_JVM_OPTS,
221211
source_version = "8",
222212
target_version = "8",
223213
)
224214

225215
default_java_toolchain(
226216
name = "toolchain_hostjdk9",
227-
bootclasspath = [":bootclasspath"],
228-
extclasspath = [":extclasspath"],
217+
bootclasspath = [":platformclasspath"],
229218
jvm_opts = JDK9_JVM_OPTS,
230219
source_version = "8",
231220
target_version = "8",

tools/jdk/DumpPlatformClassPath.java

Lines changed: 46 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -12,146 +12,84 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
import static java.nio.charset.StandardCharsets.UTF_8;
16-
import static java.util.Comparator.comparing;
17-
1815
import java.io.BufferedOutputStream;
19-
import java.io.ByteArrayOutputStream;
2016
import java.io.IOException;
21-
import java.io.InputStream;
2217
import java.io.OutputStream;
23-
import java.io.UncheckedIOException;
18+
import java.net.URI;
19+
import java.nio.file.DirectoryStream;
20+
import java.nio.file.FileSystems;
2421
import java.nio.file.FileVisitResult;
2522
import java.nio.file.Files;
2623
import java.nio.file.Path;
2724
import java.nio.file.Paths;
2825
import java.nio.file.SimpleFileVisitor;
2926
import java.nio.file.attribute.BasicFileAttributes;
30-
import java.util.Arrays;
31-
import java.util.EnumSet;
3227
import java.util.GregorianCalendar;
33-
import java.util.HashMap;
34-
import java.util.Map;
3528
import java.util.jar.JarEntry;
3629
import java.util.jar.JarOutputStream;
3730
import java.util.zip.CRC32;
3831
import java.util.zip.ZipEntry;
39-
import javax.tools.JavaCompiler;
40-
import javax.tools.JavaFileManager.Location;
41-
import javax.tools.JavaFileObject;
42-
import javax.tools.JavaFileObject.Kind;
43-
import javax.tools.StandardJavaFileManager;
44-
import javax.tools.StandardLocation;
45-
import javax.tools.ToolProvider;
4632

4733
/**
48-
* Output a jar file containing all classes on the JDK 8 platform classpath of the default java
49-
* compiler of the current JDK.
34+
* Output a jar file containing all classes on the platform classpath of the current JDK.
5035
*
51-
* <p>usage: DumpPlatformClassPath <target release> output.jar
36+
* <p>usage: DumpPlatformClassPath <output jar>
5237
*/
5338
public class DumpPlatformClassPath {
5439

5540
public static void main(String[] args) throws IOException {
56-
if (args.length != 2) {
57-
System.err.println("usage: DumpPlatformClassPath <target release> <output jar>");
41+
if (args.length != 1) {
42+
System.err.println("usage: DumpPlatformClassPath <output jar>");
5843
System.exit(1);
5944
}
60-
String targetRelease = args[0];
61-
Map<String, byte[]> entries = new HashMap<>();
62-
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
63-
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, UTF_8);
64-
if (isJdk9OrLater()) {
65-
// this configures the filemanager to use a JDK 8 bootclasspath
66-
compiler.getTask(
67-
null, fileManager, null, Arrays.asList("--release", targetRelease), null, null);
68-
for (Path path : getLocationAsPaths(fileManager)) {
69-
Files.walkFileTree(
70-
path,
71-
new SimpleFileVisitor<Path>() {
72-
@Override
73-
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
74-
throws IOException {
75-
if (file.getFileName().toString().endsWith(".sig")) {
76-
String outputPath = path.relativize(file).toString();
77-
outputPath =
78-
outputPath.substring(0, outputPath.length() - ".sig".length()) + ".class";
79-
entries.put(outputPath, Files.readAllBytes(file));
80-
}
81-
return FileVisitResult.CONTINUE;
82-
}
83-
});
84-
}
85-
} else {
86-
for (JavaFileObject fileObject :
87-
fileManager.list(
88-
StandardLocation.PLATFORM_CLASS_PATH,
89-
"",
90-
EnumSet.of(Kind.CLASS),
91-
/* recurse= */ true)) {
92-
String binaryName =
93-
fileManager.inferBinaryName(StandardLocation.PLATFORM_CLASS_PATH, fileObject);
94-
entries.put(
95-
binaryName.replace('.', '/') + ".class", toByteArray(fileObject.openInputStream()));
96-
}
45+
Path output = Paths.get(args[0]);
46+
Path path = Paths.get(System.getProperty("java.home"));
47+
if (path.endsWith("jre")) {
48+
path = path.getParent();
49+
}
50+
Path rtJar = path.resolve("jre/lib/rt.jar");
51+
System.err.println(rtJar);
52+
if (Files.exists(rtJar)) {
53+
Files.copy(rtJar, output);
54+
return;
9755
}
98-
try (OutputStream os = Files.newOutputStream(Paths.get(args[1]));
56+
Path modules = FileSystems.getFileSystem(URI.create("jrt:/")).getPath("modules");
57+
try (OutputStream os = Files.newOutputStream(output);
9958
BufferedOutputStream bos = new BufferedOutputStream(os, 65536);
10059
JarOutputStream jos = new JarOutputStream(bos)) {
101-
entries
102-
.entrySet()
103-
.stream()
104-
.sorted(comparing(Map.Entry::getKey))
105-
.forEachOrdered(e -> addEntry(jos, e.getKey(), e.getValue()));
106-
}
107-
}
108-
109-
@SuppressWarnings("unchecked")
110-
private static Iterable<Path> getLocationAsPaths(StandardJavaFileManager fileManager) {
111-
try {
112-
return (Iterable<Path>)
113-
StandardJavaFileManager.class
114-
.getMethod("getLocationAsPaths", Location.class)
115-
.invoke(fileManager, StandardLocation.PLATFORM_CLASS_PATH);
116-
} catch (ReflectiveOperationException e) {
117-
throw new LinkageError(e.getMessage(), e);
60+
try (DirectoryStream<Path> modulePaths = Files.newDirectoryStream(modules)) {
61+
for (Path modulePath : modulePaths) {
62+
Files.walkFileTree(
63+
modulePath,
64+
new SimpleFileVisitor<Path>() {
65+
@Override
66+
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs)
67+
throws IOException {
68+
String name = path.getFileName().toString();
69+
if (name.endsWith(".class") && !name.equals("module-info.class")) {
70+
addEntry(jos, modulePath.relativize(path).toString(), Files.readAllBytes(path));
71+
}
72+
return super.visitFile(path, attrs);
73+
}
74+
});
75+
}
76+
}
11877
}
11978
}
12079

12180
// Use a fixed timestamp for deterministic jar output.
12281
private static final long FIXED_TIMESTAMP =
12382
new GregorianCalendar(2010, 0, 1, 0, 0, 0).getTimeInMillis();
12483

125-
private static void addEntry(JarOutputStream jos, String name, byte[] bytes) {
126-
try {
127-
JarEntry je = new JarEntry(name);
128-
je.setTime(FIXED_TIMESTAMP);
129-
je.setMethod(ZipEntry.STORED);
130-
je.setSize(bytes.length);
131-
CRC32 crc = new CRC32();
132-
crc.update(bytes);
133-
je.setCrc(crc.getValue());
134-
jos.putNextEntry(je);
135-
jos.write(bytes);
136-
} catch (IOException e) {
137-
throw new UncheckedIOException(e);
138-
}
139-
}
140-
141-
private static byte[] toByteArray(InputStream is) throws IOException {
142-
byte[] buffer = new byte[8192];
143-
ByteArrayOutputStream boas = new ByteArrayOutputStream();
144-
while (true) {
145-
int r = is.read(buffer);
146-
if (r == -1) {
147-
break;
148-
}
149-
boas.write(buffer, 0, r);
150-
}
151-
return boas.toByteArray();
152-
}
153-
154-
private static boolean isJdk9OrLater() {
155-
return Double.parseDouble(System.getProperty("java.class.version")) >= 53.0;
84+
private static void addEntry(JarOutputStream jos, String name, byte[] bytes) throws IOException {
85+
JarEntry je = new JarEntry(name);
86+
je.setTime(FIXED_TIMESTAMP);
87+
je.setMethod(ZipEntry.STORED);
88+
je.setSize(bytes.length);
89+
CRC32 crc = new CRC32();
90+
crc.update(bytes);
91+
je.setCrc(crc.getValue());
92+
jos.putNextEntry(je);
93+
jos.write(bytes);
15694
}
15795
}

0 commit comments

Comments
 (0)