29 import com.sun.tools.classfile.ConstantPool;
30 import com.sun.tools.classfile.ConstantPoolException;
31 import com.sun.tools.classfile.RuntimeAnnotations_attribute;
32 import com.sun.tools.classfile.Dependencies.ClassFileError;
33 import java.io.IOException;
34 import java.nio.file.FileVisitResult;
35 import java.nio.file.Files;
36 import java.nio.file.Path;
37 import java.nio.file.Paths;
38 import java.nio.file.SimpleFileVisitor;
39 import java.nio.file.attribute.BasicFileAttributes;
40 import java.util.*;
41
42 import static com.sun.tools.classfile.Attribute.*;
43
44 /**
45 * ClassPath for Java SE and JDK
46 */
47 class PlatformClassPath {
48 private static final List<String> NON_PLATFORM_JARFILES =
49 Arrays.asList("alt-rt.jar", "jfxrt.jar", "ant-javafx.jar", "javafx-mx.jar");
50 private static final List<Archive> javaHomeArchives = init();
51
52 static List<Archive> getArchives() {
53 return javaHomeArchives;
54 }
55
56 private static List<Archive> init() {
57 List<Archive> result = new ArrayList<>();
58 Path home = Paths.get(System.getProperty("java.home"));
59 try {
60 if (home.endsWith("jre")) {
61 // jar files in <javahome>/jre/lib
62 result.addAll(addJarFiles(home.resolve("lib")));
63 if (home.getParent() != null) {
64 // add tools.jar and other JDK jar files
65 Path lib = home.getParent().resolve("lib");
66 if (Files.exists(lib)) {
67 result.addAll(addJarFiles(lib));
68 }
69 }
107 String fn = p.getFileName().toString();
108 if (fn.endsWith(".jar")) {
109 // JDK may cobundle with JavaFX that doesn't belong to any profile
110 // Treat jfxrt.jar as regular Archive
111 result.add(NON_PLATFORM_JARFILES.contains(fn)
112 ? Archive.getInstance(p)
113 : new JDKArchive(p));
114 }
115 return FileVisitResult.CONTINUE;
116 }
117 });
118 return result;
119 }
120
121 /**
122 * A JDK archive is part of the JDK containing the Java SE API
123 * or implementation classes (i.e. JDK internal API)
124 */
125 static class JDKArchive extends Archive {
126 private static List<String> PROFILE_JARS = Arrays.asList("rt.jar", "jce.jar");
127 public static boolean isProfileArchive(Archive archive) {
128 if (archive instanceof JDKArchive) {
129 return PROFILE_JARS.contains(archive.getName());
130 }
131 return false;
132 }
133
134 private final Map<String,Boolean> exportedPackages = new HashMap<>();
135 private final Map<String,Boolean> exportedTypes = new HashMap<>();
136 JDKArchive(Path p) throws IOException {
137 super(p, ClassFileReader.newInstance(p));
138 }
139
140 /**
141 * Tests if a given fully-qualified name is an exported type.
142 */
143 public boolean isExported(String cn) {
144 int i = cn.lastIndexOf('.');
145 String pn = i > 0 ? cn.substring(0, i) : "";
146
147 boolean isJdkExported = isExportedPackage(pn);
148 if (exportedTypes.containsKey(cn)) {
149 return exportedTypes.get(cn);
150 }
151 return isJdkExported;
152 }
153
154 /**
155 * Tests if a given package name is exported.
156 */
157 public boolean isExportedPackage(String pn) {
158 if (Profile.getProfile(pn) != null || "javax.jnlp".equals(pn)) {
159 return true;
160 }
161 return exportedPackages.containsKey(pn) ? exportedPackages.get(pn) : false;
162 }
163
164 private static final String JDK_EXPORTED_ANNOTATION = "Ljdk/Exported;";
165 private Boolean isJdkExported(ClassFile cf) throws ConstantPoolException {
166 RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute)
167 cf.attributes.get(RuntimeVisibleAnnotations);
168 if (attr != null) {
169 for (int i = 0; i < attr.annotations.length; i++) {
170 Annotation ann = attr.annotations[i];
171 String annType = cf.constant_pool.getUTF8Value(ann.type_index);
172 if (JDK_EXPORTED_ANNOTATION.equals(annType)) {
173 boolean isJdkExported = true;
174 for (int j = 0; j < ann.num_element_value_pairs; j++) {
175 Annotation.element_value_pair pair = ann.element_value_pairs[j];
176 Annotation.Primitive_element_value ev = (Annotation.Primitive_element_value) pair.value;
177 ConstantPool.CONSTANT_Integer_info info = (ConstantPool.CONSTANT_Integer_info)
178 cf.constant_pool.get(ev.const_value_index);
|
29 import com.sun.tools.classfile.ConstantPool;
30 import com.sun.tools.classfile.ConstantPoolException;
31 import com.sun.tools.classfile.RuntimeAnnotations_attribute;
32 import com.sun.tools.classfile.Dependencies.ClassFileError;
33 import java.io.IOException;
34 import java.nio.file.FileVisitResult;
35 import java.nio.file.Files;
36 import java.nio.file.Path;
37 import java.nio.file.Paths;
38 import java.nio.file.SimpleFileVisitor;
39 import java.nio.file.attribute.BasicFileAttributes;
40 import java.util.*;
41
42 import static com.sun.tools.classfile.Attribute.*;
43
44 /**
45 * ClassPath for Java SE and JDK
46 */
47 class PlatformClassPath {
48 private static final List<String> NON_PLATFORM_JARFILES =
49 Arrays.asList("alt-rt.jar", "ant-javafx.jar", "javafx-mx.jar");
50 private static final List<Archive> javaHomeArchives = init();
51
52 static List<Archive> getArchives() {
53 return javaHomeArchives;
54 }
55
56 private static List<Archive> init() {
57 List<Archive> result = new ArrayList<>();
58 Path home = Paths.get(System.getProperty("java.home"));
59 try {
60 if (home.endsWith("jre")) {
61 // jar files in <javahome>/jre/lib
62 result.addAll(addJarFiles(home.resolve("lib")));
63 if (home.getParent() != null) {
64 // add tools.jar and other JDK jar files
65 Path lib = home.getParent().resolve("lib");
66 if (Files.exists(lib)) {
67 result.addAll(addJarFiles(lib));
68 }
69 }
107 String fn = p.getFileName().toString();
108 if (fn.endsWith(".jar")) {
109 // JDK may cobundle with JavaFX that doesn't belong to any profile
110 // Treat jfxrt.jar as regular Archive
111 result.add(NON_PLATFORM_JARFILES.contains(fn)
112 ? Archive.getInstance(p)
113 : new JDKArchive(p));
114 }
115 return FileVisitResult.CONTINUE;
116 }
117 });
118 return result;
119 }
120
121 /**
122 * A JDK archive is part of the JDK containing the Java SE API
123 * or implementation classes (i.e. JDK internal API)
124 */
125 static class JDKArchive extends Archive {
126 private static List<String> PROFILE_JARS = Arrays.asList("rt.jar", "jce.jar");
127 // Workaround: The following packages are not annotated as jdk.Exported
128 private static List<String> EXPORTED_PACKAGES = Arrays.asList(
129 "javax.jnlp",
130 "org.w3c.dom.css",
131 "org.w3c.dom.html",
132 "org.w3c.dom.stylesheets",
133 "org.w3c.dom.xpath"
134 );
135 public static boolean isProfileArchive(Archive archive) {
136 if (archive instanceof JDKArchive) {
137 return PROFILE_JARS.contains(archive.getName());
138 }
139 return false;
140 }
141
142 private final Map<String,Boolean> exportedPackages = new HashMap<>();
143 private final Map<String,Boolean> exportedTypes = new HashMap<>();
144 JDKArchive(Path p) throws IOException {
145 super(p, ClassFileReader.newInstance(p));
146 }
147
148 /**
149 * Tests if a given fully-qualified name is an exported type.
150 */
151 public boolean isExported(String cn) {
152 int i = cn.lastIndexOf('.');
153 String pn = i > 0 ? cn.substring(0, i) : "";
154
155 boolean isJdkExported = isExportedPackage(pn);
156 if (exportedTypes.containsKey(cn)) {
157 return exportedTypes.get(cn);
158 }
159 return isJdkExported;
160 }
161
162 /**
163 * Tests if a given package name is exported.
164 */
165 public boolean isExportedPackage(String pn) {
166 if (Profile.getProfile(pn) != null) {
167 return true;
168 }
169 // special case for JavaFX and APIs that are not annotated with @jdk.Exported)
170 if (EXPORTED_PACKAGES.contains(pn) || pn.startsWith("javafx.")) {
171 return true;
172 }
173 return exportedPackages.containsKey(pn) ? exportedPackages.get(pn) : false;
174 }
175
176 private static final String JDK_EXPORTED_ANNOTATION = "Ljdk/Exported;";
177 private Boolean isJdkExported(ClassFile cf) throws ConstantPoolException {
178 RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute)
179 cf.attributes.get(RuntimeVisibleAnnotations);
180 if (attr != null) {
181 for (int i = 0; i < attr.annotations.length; i++) {
182 Annotation ann = attr.annotations[i];
183 String annType = cf.constant_pool.getUTF8Value(ann.type_index);
184 if (JDK_EXPORTED_ANNOTATION.equals(annType)) {
185 boolean isJdkExported = true;
186 for (int j = 0; j < ann.num_element_value_pairs; j++) {
187 Annotation.element_value_pair pair = ann.element_value_pairs[j];
188 Annotation.Primitive_element_value ev = (Annotation.Primitive_element_value) pair.value;
189 ConstantPool.CONSTANT_Integer_info info = (ConstantPool.CONSTANT_Integer_info)
190 cf.constant_pool.get(ev.const_value_index);
|