Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/test/tools/jdeps/APIDeps.java
32285 views
/*1* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 8015912 8029216 8048063 805080426* @summary Test -apionly and -jdkinternals options27* @build m.Bar m.Foo m.Gee b.B c.C c.I d.D e.E f.F g.G28* @run main APIDeps29*/3031import java.io.File;32import java.io.IOException;33import java.io.PrintWriter;34import java.io.StringWriter;35import java.nio.file.Path;36import java.nio.file.Paths;37import java.util.*;38import java.util.regex.*;3940public class APIDeps {41private static boolean symbolFileExist = initProfiles();42private static boolean initProfiles() {43// check if ct.sym exists; if not use the profiles.properties file44Path home = Paths.get(System.getProperty("java.home"));45if (home.endsWith("jre")) {46home = home.getParent();47}48Path ctsym = home.resolve("lib").resolve("ct.sym");49boolean symbolExists = ctsym.toFile().exists();50if (!symbolExists) {51Path testSrcProfiles =52Paths.get(System.getProperty("test.src", "."), "profiles.properties");53if (!testSrcProfiles.toFile().exists())54throw new Error(testSrcProfiles + " does not exist");55System.out.format("%s doesn't exist.%nUse %s to initialize profiles info%n",56ctsym, testSrcProfiles);57System.setProperty("jdeps.profiles", testSrcProfiles.toString());58}59return symbolExists;60}6162public static void main(String... args) throws Exception {63int errors = 0;64errors += new APIDeps().run();65if (errors > 0)66throw new Exception(errors + " errors found");67}6869int run() throws IOException {70File testDir = new File(System.getProperty("test.classes", "."));71String testDirBasename = testDir.toPath().getFileName().toString();72File mDir = new File(testDir, "m");73// all dependencies74test(new File(mDir, "Bar.class"),75new String[] {"java.lang.Object", "java.lang.String",76"java.util.Set", "java.util.HashSet",77"java.lang.management.ManagementFactory",78"java.lang.management.RuntimeMXBean",79"b.B", "c.C", "d.D", "f.F", "g.G"},80new String[] {"compact1", "compact3", testDirBasename},81new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"});82test(new File(mDir, "Foo.class"),83new String[] {"c.I", "e.E", "f.F"},84new String[] {testDirBasename},85new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-P"});86test(new File(mDir, "Foo.class"),87new String[] {"c.I", "e.E", "f.F", "m.Bar"},88new String[] {testDirBasename},89new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-filter:none", "-P"});90test(new File(mDir, "Gee.class"),91new String[] {"g.G", "sun.misc.Lock", "com.sun.tools.classfile.ClassFile",92"com.sun.management.ThreadMXBean", "com.sun.source.tree.BinaryTree",93"org.w3c.dom.css.CSSValue"},94new String[] {testDirBasename, "JDK internal API", "compact2", "compact3", ""},95new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"});9697// -jdkinternals98test(new File(mDir, "Gee.class"),99new String[] {"sun.misc.Lock", "com.sun.tools.classfile.ClassFile"},100new String[] {"JDK internal API"},101new String[] {"-jdkinternals"});102// -jdkinternals parses all classes on -classpath and the input arguments103test(new File(mDir, "Gee.class"),104new String[] {"com.sun.tools.jdeps.Main", "com.sun.tools.classfile.ClassFile",105"sun.misc.Lock", "sun.misc.Unsafe"},106new String[] {"JDK internal API"},107new String[] {"-classpath", testDir.getPath(), "-jdkinternals"});108109// parse only APIs110test(mDir,111new String[] {"java.lang.Object", "java.lang.String",112"java.util.Set",113"c.C", "d.D", "c.I", "e.E"},114new String[] {"compact1", testDirBasename},115new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-P", "-apionly"});116117test(mDir,118new String[] {"java.lang.Object", "java.lang.String",119"java.util.Set",120"c.C", "d.D", "c.I", "e.E", "m.Bar"},121new String[] {"compact1", testDirBasename, mDir.getName()},122new String[] {"-classpath", testDir.getPath(), "-verbose", "-P", "-apionly"});123return errors;124}125126void test(File file, String[] expect, String[] profiles) {127test(file, expect, profiles, new String[0]);128}129130void test(File file, String[] expect, String[] profiles, String[] options) {131List<String> args = new ArrayList<>(Arrays.asList(options));132if (file != null) {133args.add(file.getPath());134}135checkResult("api-dependencies", expect, profiles,136jdeps(args.toArray(new String[0])));137}138139Map<String,String> jdeps(String... args) {140StringWriter sw = new StringWriter();141PrintWriter pw = new PrintWriter(sw);142System.err.println("jdeps " + Arrays.toString(args));143int rc = com.sun.tools.jdeps.Main.run(args, pw);144pw.close();145String out = sw.toString();146if (!out.isEmpty())147System.err.println(out);148if (rc != 0)149throw new Error("jdeps failed: rc=" + rc);150return findDeps(out);151}152153// Pattern used to parse lines154private static Pattern linePattern = Pattern.compile(".*\r?\n");155private static Pattern pattern = Pattern.compile("\\s+ -> (\\S+) +(.*)");156157// Use the linePattern to break the given String into lines, applying158// the pattern to each line to see if we have a match159private static Map<String,String> findDeps(String out) {160Map<String,String> result = new HashMap<>();161Matcher lm = linePattern.matcher(out); // Line matcher162Matcher pm = null; // Pattern matcher163int lines = 0;164while (lm.find()) {165lines++;166CharSequence cs = lm.group(); // The current line167if (pm == null)168pm = pattern.matcher(cs);169else170pm.reset(cs);171if (pm.find())172result.put(pm.group(1), pm.group(2).trim());173if (lm.end() == out.length())174break;175}176return result;177}178179void checkResult(String label, String[] expect, Collection<String> found) {180List<String> list = Arrays.asList(expect);181if (!isEqual(list, found))182error("Unexpected " + label + " found: '" + found + "', expected: '" + list + "'");183}184185void checkResult(String label, String[] expect, String[] profiles, Map<String,String> result) {186// check the dependencies187checkResult(label, expect, result.keySet());188// check profile information189Set<String> values = new TreeSet<>();190String internal = "JDK internal API";191for (String s: result.values()) {192if (s.startsWith(internal)){193values.add(internal);194} else {195values.add(s);196}197}198checkResult(label, profiles, values);199}200201boolean isEqual(List<String> expected, Collection<String> found) {202if (expected.size() != found.size())203return false;204205List<String> list = new ArrayList<>(found);206list.removeAll(expected);207return list.isEmpty();208}209210void error(String msg) {211System.err.println("Error: " + msg);212errors++;213}214215int errors;216}217218219