1 /*
2 * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.internal.jimage;
27
28 import java.io.IOException;
29 import java.io.UncheckedIOException;
30 import java.nio.file.FileSystem;
31 import java.nio.file.FileSystems;
32 import java.nio.file.Path;
33 import java.util.concurrent.ConcurrentHashMap;
34 import java.util.Map;
35 import java.util.Objects;
36 import java.util.function.Function;
37
38 /**
39 * Factory to get ImageReader
40 *
41 * @implNote This class needs to maintain JDK 8 source compatibility.
42 *
43 * It is used internally in the JDK to implement jimage/jrtfs access,
44 * but also compiled and delivered as part of the jrtfs.jar to support access
45 * to the jimage file provided by the shipped JDK by tools running on JDK 8.
46 */
47 public class ImageReaderFactory {
48 private ImageReaderFactory() {}
49
50 private static final String JAVA_HOME = System.getProperty("java.home");
51 private static final Path BOOT_MODULES_JIMAGE;
52
53 static {
54 FileSystem fs;
55 if (ImageReaderFactory.class.getClassLoader() == null) {
56 try {
57 fs = (FileSystem) Class.forName("sun.nio.fs.DefaultFileSystemProvider")
58 .getMethod("theFileSystem")
59 .invoke(null);
60 } catch (Exception e) {
61 throw new ExceptionInInitializerError(e);
62 }
63 } else {
64 fs = FileSystems.getDefault();
65 }
66 BOOT_MODULES_JIMAGE = fs.getPath(JAVA_HOME, "lib", "modules");
67 }
68
69 private static final Map<Path, ImageReader> readers = new ConcurrentHashMap<>();
70
71 /**
72 * Returns an {@code ImageReader} to read from the given image file
73 */
74 public static ImageReader get(Path jimage) throws IOException {
75 Objects.requireNonNull(jimage);
76 try {
77 return readers.computeIfAbsent(jimage, OPENER);
78 } catch (UncheckedIOException io) {
79 throw io.getCause();
80 }
81 }
82
83 private static Function<Path, ImageReader> OPENER = new Function<Path, ImageReader>() {
84 public ImageReader apply(Path path) {
85 try {
86 return ImageReader.open(path);
87 } catch (IOException io) {
88 throw new UncheckedIOException(io);
89 }
90 }
91 };
92
93 /**
94 * Returns the {@code ImageReader} to read the image file in this
95 * run-time image.
96 *
97 * @throws UncheckedIOException if an I/O error occurs
98 */
99 public static ImageReader getImageReader() {
100 try {
101 return get(BOOT_MODULES_JIMAGE);
102 } catch (IOException ioe) {
103 throw new UncheckedIOException(ioe);
104 }
105 }
106 }