src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java

Sat, 07 Nov 2020 10:30:02 +0800

author
aoqi
date
Sat, 07 Nov 2020 10:30:02 +0800
changeset 3938
93012e2a5d1d
parent 2893
ca5783d9a597
permissions
-rw-r--r--

Added tag mips-jdk8u275-b01 for changeset eb6ee6a5f2fe

aoqi@0 1 /*
mchung@2538 2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25 package com.sun.tools.jdeps;
aoqi@0 26
mchung@2538 27 import com.sun.tools.classfile.Annotation;
mchung@2538 28 import com.sun.tools.classfile.ClassFile;
mchung@2538 29 import com.sun.tools.classfile.ConstantPool;
mchung@2538 30 import com.sun.tools.classfile.ConstantPoolException;
mchung@2538 31 import com.sun.tools.classfile.RuntimeAnnotations_attribute;
mchung@2538 32 import com.sun.tools.classfile.Dependencies.ClassFileError;
aoqi@0 33 import java.io.IOException;
aoqi@0 34 import java.nio.file.FileVisitResult;
aoqi@0 35 import java.nio.file.Files;
aoqi@0 36 import java.nio.file.Path;
aoqi@0 37 import java.nio.file.Paths;
aoqi@0 38 import java.nio.file.SimpleFileVisitor;
aoqi@0 39 import java.nio.file.attribute.BasicFileAttributes;
aoqi@0 40 import java.util.*;
aoqi@0 41
mchung@2538 42 import static com.sun.tools.classfile.Attribute.*;
mchung@2538 43
aoqi@0 44 /**
aoqi@0 45 * ClassPath for Java SE and JDK
aoqi@0 46 */
aoqi@0 47 class PlatformClassPath {
mchung@2538 48 private static final List<String> NON_PLATFORM_JARFILES =
mchung@2803 49 Arrays.asList("alt-rt.jar", "ant-javafx.jar", "javafx-mx.jar");
mchung@2538 50 private static final List<Archive> javaHomeArchives = init();
aoqi@0 51
aoqi@0 52 static List<Archive> getArchives() {
aoqi@0 53 return javaHomeArchives;
aoqi@0 54 }
aoqi@0 55
aoqi@0 56 private static List<Archive> init() {
aoqi@0 57 List<Archive> result = new ArrayList<>();
aoqi@0 58 Path home = Paths.get(System.getProperty("java.home"));
aoqi@0 59 try {
aoqi@0 60 if (home.endsWith("jre")) {
aoqi@0 61 // jar files in <javahome>/jre/lib
aoqi@0 62 result.addAll(addJarFiles(home.resolve("lib")));
mchung@2538 63 if (home.getParent() != null) {
mchung@2538 64 // add tools.jar and other JDK jar files
mchung@2538 65 Path lib = home.getParent().resolve("lib");
mchung@2538 66 if (Files.exists(lib)) {
mchung@2538 67 result.addAll(addJarFiles(lib));
mchung@2538 68 }
mchung@2538 69 }
aoqi@0 70 } else if (Files.exists(home.resolve("lib"))) {
aoqi@0 71 // either a JRE or a jdk build image
aoqi@0 72 Path classes = home.resolve("classes");
aoqi@0 73 if (Files.isDirectory(classes)) {
aoqi@0 74 // jdk build outputdir
mchung@2538 75 result.add(new JDKArchive(classes));
aoqi@0 76 }
aoqi@0 77 // add other JAR files
aoqi@0 78 result.addAll(addJarFiles(home.resolve("lib")));
aoqi@0 79 } else {
aoqi@0 80 throw new RuntimeException("\"" + home + "\" not a JDK home");
aoqi@0 81 }
aoqi@0 82 return result;
aoqi@0 83 } catch (IOException e) {
aoqi@0 84 throw new Error(e);
aoqi@0 85 }
aoqi@0 86 }
aoqi@0 87
aoqi@0 88 private static List<Archive> addJarFiles(final Path root) throws IOException {
aoqi@0 89 final List<Archive> result = new ArrayList<>();
aoqi@0 90 final Path ext = root.resolve("ext");
aoqi@0 91 Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
aoqi@0 92 @Override
aoqi@0 93 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
aoqi@0 94 throws IOException
aoqi@0 95 {
aoqi@0 96 if (dir.equals(root) || dir.equals(ext)) {
aoqi@0 97 return FileVisitResult.CONTINUE;
aoqi@0 98 } else {
aoqi@0 99 // skip other cobundled JAR files
aoqi@0 100 return FileVisitResult.SKIP_SUBTREE;
aoqi@0 101 }
aoqi@0 102 }
aoqi@0 103 @Override
aoqi@0 104 public FileVisitResult visitFile(Path p, BasicFileAttributes attrs)
aoqi@0 105 throws IOException
aoqi@0 106 {
aoqi@0 107 String fn = p.getFileName().toString();
aoqi@0 108 if (fn.endsWith(".jar")) {
aoqi@0 109 // JDK may cobundle with JavaFX that doesn't belong to any profile
aoqi@0 110 // Treat jfxrt.jar as regular Archive
mchung@2538 111 result.add(NON_PLATFORM_JARFILES.contains(fn)
mchung@2538 112 ? Archive.getInstance(p)
mchung@2538 113 : new JDKArchive(p));
aoqi@0 114 }
aoqi@0 115 return FileVisitResult.CONTINUE;
aoqi@0 116 }
aoqi@0 117 });
aoqi@0 118 return result;
aoqi@0 119 }
aoqi@0 120
aoqi@0 121 /**
aoqi@0 122 * A JDK archive is part of the JDK containing the Java SE API
aoqi@0 123 * or implementation classes (i.e. JDK internal API)
aoqi@0 124 */
aoqi@0 125 static class JDKArchive extends Archive {
mchung@2538 126 private static List<String> PROFILE_JARS = Arrays.asList("rt.jar", "jce.jar");
mchung@2803 127 // Workaround: The following packages are not annotated as jdk.Exported
mchung@2803 128 private static List<String> EXPORTED_PACKAGES = Arrays.asList(
mchung@2803 129 "javax.jnlp",
mchung@2803 130 "org.w3c.dom.css",
mchung@2803 131 "org.w3c.dom.html",
mchung@2803 132 "org.w3c.dom.stylesheets",
mchung@2803 133 "org.w3c.dom.xpath"
mchung@2803 134 );
mchung@2538 135 public static boolean isProfileArchive(Archive archive) {
mchung@2538 136 if (archive instanceof JDKArchive) {
mchung@2538 137 return PROFILE_JARS.contains(archive.getName());
mchung@2538 138 }
mchung@2538 139 return false;
mchung@2538 140 }
mchung@2538 141
mchung@2538 142 private final Map<String,Boolean> exportedPackages = new HashMap<>();
mchung@2538 143 private final Map<String,Boolean> exportedTypes = new HashMap<>();
mchung@2538 144 JDKArchive(Path p) throws IOException {
mchung@2538 145 super(p, ClassFileReader.newInstance(p));
mchung@2538 146 }
mchung@2538 147
mchung@2538 148 /**
mchung@2538 149 * Tests if a given fully-qualified name is an exported type.
mchung@2538 150 */
mchung@2538 151 public boolean isExported(String cn) {
mchung@2538 152 int i = cn.lastIndexOf('.');
mchung@2538 153 String pn = i > 0 ? cn.substring(0, i) : "";
mchung@2538 154
mchung@2538 155 boolean isJdkExported = isExportedPackage(pn);
mchung@2538 156 if (exportedTypes.containsKey(cn)) {
mchung@2538 157 return exportedTypes.get(cn);
mchung@2538 158 }
mchung@2538 159 return isJdkExported;
mchung@2538 160 }
mchung@2538 161
mchung@2538 162 /**
mchung@2538 163 * Tests if a given package name is exported.
mchung@2538 164 */
mchung@2538 165 public boolean isExportedPackage(String pn) {
mchung@2803 166 if (Profile.getProfile(pn) != null) {
mchung@2803 167 return true;
mchung@2803 168 }
mchung@2803 169 // special case for JavaFX and APIs that are not annotated with @jdk.Exported)
mchung@2803 170 if (EXPORTED_PACKAGES.contains(pn) || pn.startsWith("javafx.")) {
mchung@2538 171 return true;
mchung@2538 172 }
mchung@2538 173 return exportedPackages.containsKey(pn) ? exportedPackages.get(pn) : false;
mchung@2538 174 }
mchung@2538 175
mchung@2538 176 private static final String JDK_EXPORTED_ANNOTATION = "Ljdk/Exported;";
mchung@2538 177 private Boolean isJdkExported(ClassFile cf) throws ConstantPoolException {
mchung@2538 178 RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute)
mchung@2538 179 cf.attributes.get(RuntimeVisibleAnnotations);
mchung@2538 180 if (attr != null) {
mchung@2538 181 for (int i = 0; i < attr.annotations.length; i++) {
mchung@2538 182 Annotation ann = attr.annotations[i];
mchung@2538 183 String annType = cf.constant_pool.getUTF8Value(ann.type_index);
mchung@2538 184 if (JDK_EXPORTED_ANNOTATION.equals(annType)) {
mchung@2538 185 boolean isJdkExported = true;
mchung@2538 186 for (int j = 0; j < ann.num_element_value_pairs; j++) {
mchung@2538 187 Annotation.element_value_pair pair = ann.element_value_pairs[j];
mchung@2538 188 Annotation.Primitive_element_value ev = (Annotation.Primitive_element_value) pair.value;
mchung@2538 189 ConstantPool.CONSTANT_Integer_info info = (ConstantPool.CONSTANT_Integer_info)
mchung@2538 190 cf.constant_pool.get(ev.const_value_index);
mchung@2538 191 isJdkExported = info.value != 0;
mchung@2538 192 }
mchung@2538 193 return Boolean.valueOf(isJdkExported);
mchung@2538 194 }
mchung@2538 195 }
mchung@2538 196 }
mchung@2538 197 return null;
mchung@2538 198 }
mchung@2538 199
mchung@2538 200 void processJdkExported(ClassFile cf) throws IOException {
mchung@2538 201 try {
mchung@2538 202 String cn = cf.getName();
mchung@2538 203 String pn = cn.substring(0, cn.lastIndexOf('/')).replace('/', '.');
mchung@2538 204
mchung@2538 205 Boolean b = isJdkExported(cf);
mchung@2538 206 if (b != null) {
mchung@2538 207 exportedTypes.put(cn.replace('/', '.'), b);
mchung@2538 208 }
mchung@2538 209 if (!exportedPackages.containsKey(pn)) {
mchung@2538 210 // check if package-info.class has @jdk.Exported
mchung@2538 211 Boolean isJdkExported = null;
mchung@2538 212 ClassFile pcf = reader().getClassFile(cn.substring(0, cn.lastIndexOf('/')+1) + "package-info");
mchung@2538 213 if (pcf != null) {
mchung@2538 214 isJdkExported = isJdkExported(pcf);
mchung@2538 215 }
mchung@2538 216 if (isJdkExported != null) {
mchung@2538 217 exportedPackages.put(pn, isJdkExported);
mchung@2538 218 }
mchung@2538 219 }
mchung@2538 220 } catch (ConstantPoolException e) {
mchung@2538 221 throw new ClassFileError(e);
mchung@2538 222 }
aoqi@0 223 }
aoqi@0 224 }
aoqi@0 225 }

mercurial