|
12 | 12 | // See the License for the specific language governing permissions and
|
13 | 13 | // limitations under the License.
|
14 | 14 |
|
15 |
| -import static java.nio.charset.StandardCharsets.UTF_8; |
16 |
| -import static java.util.Comparator.comparing; |
17 |
| - |
18 | 15 | import java.io.BufferedOutputStream;
|
19 |
| -import java.io.ByteArrayOutputStream; |
20 | 16 | import java.io.IOException;
|
21 |
| -import java.io.InputStream; |
22 | 17 | 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; |
24 | 21 | import java.nio.file.FileVisitResult;
|
25 | 22 | import java.nio.file.Files;
|
26 | 23 | import java.nio.file.Path;
|
27 | 24 | import java.nio.file.Paths;
|
28 | 25 | import java.nio.file.SimpleFileVisitor;
|
29 | 26 | import java.nio.file.attribute.BasicFileAttributes;
|
30 |
| -import java.util.Arrays; |
31 |
| -import java.util.EnumSet; |
32 | 27 | import java.util.GregorianCalendar;
|
33 |
| -import java.util.HashMap; |
34 |
| -import java.util.Map; |
35 | 28 | import java.util.jar.JarEntry;
|
36 | 29 | import java.util.jar.JarOutputStream;
|
37 | 30 | import java.util.zip.CRC32;
|
38 | 31 | 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; |
46 | 32 |
|
47 | 33 | /**
|
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. |
50 | 35 | *
|
51 |
| - * <p>usage: DumpPlatformClassPath <target release> output.jar |
| 36 | + * <p>usage: DumpPlatformClassPath <output jar> |
52 | 37 | */
|
53 | 38 | public class DumpPlatformClassPath {
|
54 | 39 |
|
55 | 40 | 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>"); |
58 | 43 | System.exit(1);
|
59 | 44 | }
|
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; |
97 | 55 | }
|
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); |
99 | 58 | BufferedOutputStream bos = new BufferedOutputStream(os, 65536);
|
100 | 59 | 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 | + } |
118 | 77 | }
|
119 | 78 | }
|
120 | 79 |
|
121 | 80 | // Use a fixed timestamp for deterministic jar output.
|
122 | 81 | private static final long FIXED_TIMESTAMP =
|
123 | 82 | new GregorianCalendar(2010, 0, 1, 0, 0, 0).getTimeInMillis();
|
124 | 83 |
|
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); |
156 | 94 | }
|
157 | 95 | }
|
0 commit comments