8015912: jdeps support to output in dot file format

Thu, 17 Oct 2013 13:19:48 -0700

author
mchung
date
Thu, 17 Oct 2013 13:19:48 -0700
changeset 2139
defadd528513
parent 2138
4d8af6fda907
child 2140
bca97b47f0a2

8015912: jdeps support to output in dot file format
8026255: Switch jdeps to follow traditional Java option style
Reviewed-by: alanb

src/share/classes/com/sun/tools/jdeps/Analyzer.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/jdeps/Archive.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/jdeps/ClassFileReader.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/jdeps/JdepsTask.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/jdeps/Profile.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/jdeps/Profiles.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties file | annotate | diff | comparison | revisions
test/tools/jdeps/APIDeps.java file | annotate | diff | comparison | revisions
test/tools/jdeps/Basic.java file | annotate | diff | comparison | revisions
test/tools/jdeps/Test.java file | annotate | diff | comparison | revisions
test/tools/jdeps/b/B.java file | annotate | diff | comparison | revisions
test/tools/jdeps/c/C.java file | annotate | diff | comparison | revisions
test/tools/jdeps/c/I.java file | annotate | diff | comparison | revisions
test/tools/jdeps/d/D.java file | annotate | diff | comparison | revisions
test/tools/jdeps/e/E.java file | annotate | diff | comparison | revisions
test/tools/jdeps/f/F.java file | annotate | diff | comparison | revisions
test/tools/jdeps/g/G.java file | annotate | diff | comparison | revisions
test/tools/jdeps/m/Bar.java file | annotate | diff | comparison | revisions
test/tools/jdeps/m/Foo.java file | annotate | diff | comparison | revisions
test/tools/jdeps/m/Gee.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/jdeps/Analyzer.java	Thu Oct 17 13:50:00 2013 +0200
     1.2 +++ b/src/share/classes/com/sun/tools/jdeps/Analyzer.java	Thu Oct 17 13:19:48 2013 -0700
     1.3 @@ -25,9 +25,8 @@
     1.4  package com.sun.tools.jdeps;
     1.5  
     1.6  import com.sun.tools.classfile.Dependency.Location;
     1.7 -import java.util.ArrayList;
     1.8 +import com.sun.tools.jdeps.PlatformClassPath.JDKArchive;
     1.9  import java.util.HashMap;
    1.10 -import java.util.HashSet;
    1.11  import java.util.List;
    1.12  import java.util.Map;
    1.13  import java.util.Set;
    1.14 @@ -52,8 +51,8 @@
    1.15      };
    1.16  
    1.17      private final Type type;
    1.18 -    private final List<ArchiveDeps> results = new ArrayList<ArchiveDeps>();
    1.19 -    private final Map<String, Archive> map = new HashMap<String, Archive>();
    1.20 +    private final Map<Archive, ArchiveDeps> results = new HashMap<>();
    1.21 +    private final Map<String, Archive> map = new HashMap<>();
    1.22      private final Archive NOT_FOUND
    1.23          = new Archive(JdepsTask.getMessage("artifact.not.found"));
    1.24  
    1.25 @@ -78,27 +77,27 @@
    1.26                  deps = new PackageVisitor(archive);
    1.27              }
    1.28              archive.visit(deps);
    1.29 -            results.add(deps);
    1.30 +            results.put(archive, deps);
    1.31          }
    1.32  
    1.33          // set the required dependencies
    1.34 -        for (ArchiveDeps result: results) {
    1.35 +        for (ArchiveDeps result: results.values()) {
    1.36              for (Set<String> set : result.deps.values()) {
    1.37                  for (String target : set) {
    1.38                      Archive source = getArchive(target);
    1.39                      if (result.archive != source) {
    1.40 -                        if (!result.requiredArchives.contains(source)) {
    1.41 -                            result.requiredArchives.add(source);
    1.42 +                        String profile = "";
    1.43 +                        if (source instanceof JDKArchive) {
    1.44 +                            profile = result.profile != null ? result.profile.toString() : "";
    1.45 +                            if (result.getTargetProfile(target) == null) {
    1.46 +                                profile += ", JDK internal API";
    1.47 +                                // override the value if it accesses any JDK internal
    1.48 +                                result.requireArchives.put(source, profile);
    1.49 +                                continue;
    1.50 +                            }
    1.51                          }
    1.52 -                        // either a profile name or the archive name
    1.53 -                        String tname = result.getTargetProfile(target);
    1.54 -                        if (tname.isEmpty()) {
    1.55 -                            tname = PlatformClassPath.contains(source)
    1.56 -                                        ? "JDK internal API (" + source.getFileName() + ")"
    1.57 -                                        : source.toString();
    1.58 -                        }
    1.59 -                        if (!result.targetNames.contains(tname)) {
    1.60 -                            result.targetNames.add(tname);
    1.61 +                        if (!result.requireArchives.containsKey(source)) {
    1.62 +                            result.requireArchives.put(source, profile);
    1.63                          }
    1.64                      }
    1.65                  }
    1.66 @@ -106,42 +105,46 @@
    1.67          }
    1.68      }
    1.69  
    1.70 +    public boolean hasDependences(Archive archive) {
    1.71 +        if (results.containsKey(archive)) {
    1.72 +            return results.get(archive).deps.size() > 0;
    1.73 +        }
    1.74 +        return false;
    1.75 +    }
    1.76 +
    1.77      public interface Visitor {
    1.78          /**
    1.79 +         * Visits the source archive to its destination archive of
    1.80 +         * a recorded dependency.
    1.81 +         */
    1.82 +        void visitArchiveDependence(Archive origin, Archive target, String profile);
    1.83 +        /**
    1.84           * Visits a recorded dependency from origin to target which can be
    1.85           * a fully-qualified classname, a package name, a profile or
    1.86           * archive name depending on the Analyzer's type.
    1.87           */
    1.88 -        void visit(String origin, String target, String profile);
    1.89 -        /**
    1.90 -         * Visits the source archive to its destination archive of
    1.91 -         * a recorded dependency.
    1.92 -         */
    1.93 -        void visit(Archive source, Archive dest);
    1.94 +        void visitDependence(String origin, Archive source, String target, Archive archive, String profile);
    1.95      }
    1.96  
    1.97 -    public void visitSummary(Visitor v) {
    1.98 -        for (ArchiveDeps r : results) {
    1.99 -            for (Archive a : r.requiredArchives) {
   1.100 -                v.visit(r.archive, a);
   1.101 -            }
   1.102 -            for (String name : r.targetNames) {
   1.103 -                v.visit(r.archive.getFileName(), name, name);
   1.104 -            }
   1.105 +    public void visitArchiveDependences(Archive source, Visitor v) {
   1.106 +        ArchiveDeps r = results.get(source);
   1.107 +        for (Map.Entry<Archive,String> e : r.requireArchives.entrySet()) {
   1.108 +            v.visitArchiveDependence(r.archive, e.getKey(), e.getValue());
   1.109          }
   1.110      }
   1.111  
   1.112 -    public void visit(Visitor v) {
   1.113 -        for (ArchiveDeps r: results) {
   1.114 -            for (Archive a : r.requiredArchives) {
   1.115 -                v.visit(r.archive, a);
   1.116 -            }
   1.117 -            for (String origin : r.deps.keySet()) {
   1.118 -                for (String target : r.deps.get(origin)) {
   1.119 -                    // filter intra-dependency unless in verbose mode
   1.120 -                    if (type == Type.VERBOSE || getArchive(origin) != getArchive(target)) {
   1.121 -                        v.visit(origin, target, r.getTargetProfile(target));
   1.122 -                    }
   1.123 +    public void visitDependences(Archive source, Visitor v) {
   1.124 +        ArchiveDeps r = results.get(source);
   1.125 +        for (String origin : r.deps.keySet()) {
   1.126 +            for (String target : r.deps.get(origin)) {
   1.127 +                Archive archive = getArchive(target);
   1.128 +                assert source == getArchive(origin);
   1.129 +                Profile profile = r.getTargetProfile(target);
   1.130 +
   1.131 +                // filter intra-dependency unless in verbose mode
   1.132 +                if (type == Type.VERBOSE || archive != source) {
   1.133 +                    v.visitDependence(origin, source, target, archive,
   1.134 +                                      profile != null ? profile.toString() : "");
   1.135                  }
   1.136              }
   1.137          }
   1.138 @@ -151,29 +154,15 @@
   1.139          return map.containsKey(name) ? map.get(name) : NOT_FOUND;
   1.140      }
   1.141  
   1.142 -    /**
   1.143 -     * Returns the file name of the archive for non-JRE class or
   1.144 -     * internal JRE classes.  It returns empty string for SE API.
   1.145 -     */
   1.146 -    public String getArchiveName(String target, String profile) {
   1.147 -        Archive source = getArchive(target);
   1.148 -        String name = source.getFileName();
   1.149 -        if (PlatformClassPath.contains(source))
   1.150 -            return profile.isEmpty() ? "JDK internal API (" + name + ")" : "";
   1.151 -        return name;
   1.152 -    }
   1.153 -
   1.154      private abstract class ArchiveDeps implements Archive.Visitor {
   1.155          final Archive archive;
   1.156 -        final Set<Archive> requiredArchives;
   1.157 -        final SortedSet<String> targetNames;
   1.158 +        final Map<Archive,String> requireArchives;
   1.159          final SortedMap<String, SortedSet<String>> deps;
   1.160 -
   1.161 +        Profile profile = null;
   1.162          ArchiveDeps(Archive archive) {
   1.163              this.archive = archive;
   1.164 -            this.requiredArchives = new HashSet<Archive>();
   1.165 -            this.targetNames = new TreeSet<String>();
   1.166 -            this.deps = new TreeMap<String, SortedSet<String>>();
   1.167 +            this.requireArchives = new HashMap<>();
   1.168 +            this.deps = new TreeMap<>();
   1.169          }
   1.170  
   1.171          void add(String loc) {
   1.172 @@ -188,17 +177,19 @@
   1.173          void add(String origin, String target) {
   1.174              SortedSet<String> set = deps.get(origin);
   1.175              if (set == null) {
   1.176 -                set = new TreeSet<String>();
   1.177 -                deps.put(origin, set);
   1.178 +                deps.put(origin, set = new TreeSet<>());
   1.179              }
   1.180              if (!set.contains(target)) {
   1.181                  set.add(target);
   1.182 +                // find the corresponding profile
   1.183 +                Profile p = getTargetProfile(target);
   1.184 +                if (profile == null || (p != null && profile.profile < p.profile)) {
   1.185 +                     profile = p;
   1.186 +                }
   1.187              }
   1.188          }
   1.189 -
   1.190          public abstract void visit(Location o, Location t);
   1.191 -        public abstract String getTargetProfile(String target);
   1.192 -
   1.193 +        public abstract Profile getTargetProfile(String target);
   1.194      }
   1.195  
   1.196      private class ClassVisitor extends ArchiveDeps {
   1.197 @@ -211,9 +202,9 @@
   1.198          public void visit(Location o, Location t) {
   1.199              add(o.getClassName(), t.getClassName());
   1.200          }
   1.201 -        public String getTargetProfile(String target) {
   1.202 +        public Profile getTargetProfile(String target) {
   1.203              int i = target.lastIndexOf('.');
   1.204 -            return (i > 0) ? Profiles.getProfileName(target.substring(0, i)) : "";
   1.205 +            return (i > 0) ? Profile.getProfile(target.substring(0, i)) : null;
   1.206          }
   1.207      }
   1.208  
   1.209 @@ -231,8 +222,8 @@
   1.210              String pkg = loc.getPackageName();
   1.211              return pkg.isEmpty() ? "<unnamed>" : pkg;
   1.212          }
   1.213 -        public String getTargetProfile(String target) {
   1.214 -            return Profiles.getProfileName(target);
   1.215 +        public Profile getTargetProfile(String target) {
   1.216 +            return Profile.getProfile(target);
   1.217          }
   1.218      }
   1.219  }
     2.1 --- a/src/share/classes/com/sun/tools/jdeps/Archive.java	Thu Oct 17 13:50:00 2013 +0200
     2.2 +++ b/src/share/classes/com/sun/tools/jdeps/Archive.java	Thu Oct 17 13:19:48 2013 -0700
     2.3 @@ -25,7 +25,7 @@
     2.4  package com.sun.tools.jdeps;
     2.5  
     2.6  import com.sun.tools.classfile.Dependency.Location;
     2.7 -import java.io.File;
     2.8 +import java.nio.file.Path;
     2.9  import java.util.HashMap;
    2.10  import java.util.HashSet;
    2.11  import java.util.Map;
    2.12 @@ -35,21 +35,20 @@
    2.13   * Represents the source of the class files.
    2.14   */
    2.15  public class Archive {
    2.16 -    private final File file;
    2.17 +    private final Path path;
    2.18      private final String filename;
    2.19      private final ClassFileReader reader;
    2.20 -    private final Map<Location, Set<Location>> deps
    2.21 -        = new HashMap<Location, Set<Location>>();
    2.22 +    private final Map<Location, Set<Location>> deps = new HashMap<>();
    2.23  
    2.24      public Archive(String name) {
    2.25 -        this.file = null;
    2.26 +        this.path = null;
    2.27          this.filename = name;
    2.28          this.reader = null;
    2.29      }
    2.30  
    2.31 -    public Archive(File f, ClassFileReader reader) {
    2.32 -        this.file = f;
    2.33 -        this.filename = f.getName();
    2.34 +    public Archive(Path p, ClassFileReader reader) {
    2.35 +        this.path = p;
    2.36 +        this.filename = path.getFileName().toString();
    2.37          this.reader = reader;
    2.38      }
    2.39  
    2.40 @@ -64,14 +63,14 @@
    2.41      public void addClass(Location origin) {
    2.42          Set<Location> set = deps.get(origin);
    2.43          if (set == null) {
    2.44 -            set = new HashSet<Location>();
    2.45 +            set = new HashSet<>();
    2.46              deps.put(origin, set);
    2.47          }
    2.48      }
    2.49      public void addClass(Location origin, Location target) {
    2.50          Set<Location> set = deps.get(origin);
    2.51          if (set == null) {
    2.52 -            set = new HashSet<Location>();
    2.53 +            set = new HashSet<>();
    2.54              deps.put(origin, set);
    2.55          }
    2.56          set.add(target);
    2.57 @@ -87,7 +86,7 @@
    2.58      }
    2.59  
    2.60      public String toString() {
    2.61 -        return file != null ? file.getPath() : filename;
    2.62 +        return path != null ? path.toString() : filename;
    2.63      }
    2.64  
    2.65      interface Visitor {
     3.1 --- a/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java	Thu Oct 17 13:50:00 2013 +0200
     3.2 +++ b/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java	Thu Oct 17 13:19:48 2013 -0700
     3.3 @@ -45,17 +45,17 @@
     3.4      /**
     3.5       * Returns a ClassFileReader instance of a given path.
     3.6       */
     3.7 -    public static ClassFileReader newInstance(File path) throws IOException {
     3.8 -        if (!path.exists()) {
     3.9 -            throw new FileNotFoundException(path.getAbsolutePath());
    3.10 +    public static ClassFileReader newInstance(Path path) throws IOException {
    3.11 +        if (!Files.exists(path)) {
    3.12 +            throw new FileNotFoundException(path.toString());
    3.13          }
    3.14  
    3.15 -        if (path.isDirectory()) {
    3.16 -            return new DirectoryReader(path.toPath());
    3.17 -        } else if (path.getName().endsWith(".jar")) {
    3.18 -            return new JarFileReader(path.toPath());
    3.19 +        if (Files.isDirectory(path)) {
    3.20 +            return new DirectoryReader(path);
    3.21 +        } else if (path.getFileName().toString().endsWith(".jar")) {
    3.22 +            return new JarFileReader(path);
    3.23          } else {
    3.24 -            return new ClassFileReader(path.toPath());
    3.25 +            return new ClassFileReader(path);
    3.26          }
    3.27      }
    3.28  
    3.29 @@ -163,16 +163,16 @@
    3.30                  int i = name.lastIndexOf('.');
    3.31                  String pathname = name.replace('.', File.separatorChar) + ".class";
    3.32                  Path p = path.resolve(pathname);
    3.33 -                if (!p.toFile().exists()) {
    3.34 +                if (!Files.exists(p)) {
    3.35                      p = path.resolve(pathname.substring(0, i) + "$" +
    3.36                                       pathname.substring(i+1, pathname.length()));
    3.37                  }
    3.38 -                if (p.toFile().exists()) {
    3.39 +                if (Files.exists(p)) {
    3.40                      return readClassFile(p);
    3.41                  }
    3.42              } else {
    3.43                  Path p = path.resolve(name + ".class");
    3.44 -                if (p.toFile().exists()) {
    3.45 +                if (Files.exists(p)) {
    3.46                      return readClassFile(p);
    3.47                  }
    3.48              }
    3.49 @@ -193,7 +193,7 @@
    3.50              Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
    3.51                  public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
    3.52                          throws IOException {
    3.53 -                    if (file.toFile().getName().endsWith(".class")) {
    3.54 +                    if (file.getFileName().toString().endsWith(".class")) {
    3.55                          files.add(file);
    3.56                      }
    3.57                      return FileVisitResult.CONTINUE;
     4.1 --- a/src/share/classes/com/sun/tools/jdeps/JdepsTask.java	Thu Oct 17 13:50:00 2013 +0200
     4.2 +++ b/src/share/classes/com/sun/tools/jdeps/JdepsTask.java	Thu Oct 17 13:19:48 2013 -0700
     4.3 @@ -24,12 +24,18 @@
     4.4   */
     4.5  package com.sun.tools.jdeps;
     4.6  
     4.7 +import com.sun.tools.classfile.AccessFlags;
     4.8  import com.sun.tools.classfile.ClassFile;
     4.9  import com.sun.tools.classfile.ConstantPoolException;
    4.10  import com.sun.tools.classfile.Dependencies;
    4.11  import com.sun.tools.classfile.Dependencies.ClassFileError;
    4.12  import com.sun.tools.classfile.Dependency;
    4.13 +import com.sun.tools.jdeps.PlatformClassPath.JDKArchive;
    4.14  import java.io.*;
    4.15 +import java.nio.file.DirectoryStream;
    4.16 +import java.nio.file.Files;
    4.17 +import java.nio.file.Path;
    4.18 +import java.nio.file.Paths;
    4.19  import java.text.MessageFormat;
    4.20  import java.util.*;
    4.21  import java.util.regex.Pattern;
    4.22 @@ -67,11 +73,10 @@
    4.23  
    4.24          boolean matches(String opt) {
    4.25              for (String a : aliases) {
    4.26 -                if (a.equals(opt)) {
    4.27 +                if (a.equals(opt))
    4.28                      return true;
    4.29 -                } else if (opt.startsWith("--") && hasArg && opt.startsWith(a + "=")) {
    4.30 +                if (hasArg && opt.startsWith(a + "="))
    4.31                      return true;
    4.32 -                }
    4.33              }
    4.34              return false;
    4.35          }
    4.36 @@ -96,62 +101,96 @@
    4.37      }
    4.38  
    4.39      static Option[] recognizedOptions = {
    4.40 -        new Option(false, "-h", "-?", "--help") {
    4.41 +        new Option(false, "-h", "-?", "-help") {
    4.42              void process(JdepsTask task, String opt, String arg) {
    4.43                  task.options.help = true;
    4.44              }
    4.45          },
    4.46 -        new Option(false, "-s", "--summary") {
    4.47 +        new Option(true, "-dotoutput") {
    4.48 +            void process(JdepsTask task, String opt, String arg) throws BadArgs {
    4.49 +                Path p = Paths.get(arg);
    4.50 +                if (Files.exists(p) && (!Files.isDirectory(p) || !Files.isWritable(p))) {
    4.51 +                    throw new BadArgs("err.dot.output.path", arg);
    4.52 +                }
    4.53 +                task.options.dotOutputDir = arg;
    4.54 +            }
    4.55 +        },
    4.56 +        new Option(false, "-s", "-summary") {
    4.57              void process(JdepsTask task, String opt, String arg) {
    4.58                  task.options.showSummary = true;
    4.59                  task.options.verbose = Analyzer.Type.SUMMARY;
    4.60              }
    4.61          },
    4.62 -        new Option(false, "-v", "--verbose") {
    4.63 -            void process(JdepsTask task, String opt, String arg) {
    4.64 -                task.options.verbose = Analyzer.Type.VERBOSE;
    4.65 -            }
    4.66 -        },
    4.67 -        new Option(true, "-V", "--verbose-level") {
    4.68 +        new Option(false, "-v", "-verbose",
    4.69 +                          "-verbose:package",
    4.70 +                          "-verbose:class")
    4.71 +        {
    4.72              void process(JdepsTask task, String opt, String arg) throws BadArgs {
    4.73 -                if ("package".equals(arg)) {
    4.74 -                    task.options.verbose = Analyzer.Type.PACKAGE;
    4.75 -                } else if ("class".equals(arg)) {
    4.76 -                    task.options.verbose = Analyzer.Type.CLASS;
    4.77 -                } else {
    4.78 -                    throw new BadArgs("err.invalid.arg.for.option", opt);
    4.79 +                switch (opt) {
    4.80 +                    case "-v":
    4.81 +                    case "-verbose":
    4.82 +                        task.options.verbose = Analyzer.Type.VERBOSE;
    4.83 +                        break;
    4.84 +                    case "-verbose:package":
    4.85 +                            task.options.verbose = Analyzer.Type.PACKAGE;
    4.86 +                            break;
    4.87 +                    case "-verbose:class":
    4.88 +                            task.options.verbose = Analyzer.Type.CLASS;
    4.89 +                            break;
    4.90 +                    default:
    4.91 +                        throw new BadArgs("err.invalid.arg.for.option", opt);
    4.92                  }
    4.93              }
    4.94          },
    4.95 -        new Option(true, "-c", "--classpath") {
    4.96 +        new Option(true, "-cp", "-classpath") {
    4.97              void process(JdepsTask task, String opt, String arg) {
    4.98                  task.options.classpath = arg;
    4.99              }
   4.100          },
   4.101 -        new Option(true, "-p", "--package") {
   4.102 +        new Option(true, "-p", "-package") {
   4.103              void process(JdepsTask task, String opt, String arg) {
   4.104                  task.options.packageNames.add(arg);
   4.105              }
   4.106          },
   4.107 -        new Option(true, "-e", "--regex") {
   4.108 +        new Option(true, "-e", "-regex") {
   4.109              void process(JdepsTask task, String opt, String arg) {
   4.110                  task.options.regex = arg;
   4.111              }
   4.112          },
   4.113 -        new Option(false, "-P", "--profile") {
   4.114 +        new Option(true, "-include") {
   4.115 +            void process(JdepsTask task, String opt, String arg) throws BadArgs {
   4.116 +                task.options.includePattern = Pattern.compile(arg);
   4.117 +            }
   4.118 +        },
   4.119 +        new Option(false, "-P", "-profile") {
   4.120              void process(JdepsTask task, String opt, String arg) throws BadArgs {
   4.121                  task.options.showProfile = true;
   4.122 -                if (Profiles.getProfileCount() == 0) {
   4.123 +                if (Profile.getProfileCount() == 0) {
   4.124                      throw new BadArgs("err.option.unsupported", opt, getMessage("err.profiles.msg"));
   4.125                  }
   4.126              }
   4.127          },
   4.128 -        new Option(false, "-R", "--recursive") {
   4.129 +        new Option(false, "-apionly") {
   4.130 +            void process(JdepsTask task, String opt, String arg) {
   4.131 +                task.options.apiOnly = true;
   4.132 +            }
   4.133 +        },
   4.134 +        new Option(false, "-R", "-recursive") {
   4.135              void process(JdepsTask task, String opt, String arg) {
   4.136                  task.options.depth = 0;
   4.137              }
   4.138          },
   4.139 -        new HiddenOption(true, "-d", "--depth") {
   4.140 +        new Option(false, "-version") {
   4.141 +            void process(JdepsTask task, String opt, String arg) {
   4.142 +                task.options.version = true;
   4.143 +            }
   4.144 +        },
   4.145 +        new HiddenOption(false, "-fullversion") {
   4.146 +            void process(JdepsTask task, String opt, String arg) {
   4.147 +                task.options.fullVersion = true;
   4.148 +            }
   4.149 +        },
   4.150 +        new HiddenOption(true, "-depth") {
   4.151              void process(JdepsTask task, String opt, String arg) throws BadArgs {
   4.152                  try {
   4.153                      task.options.depth = Integer.parseInt(arg);
   4.154 @@ -160,16 +199,6 @@
   4.155                  }
   4.156              }
   4.157          },
   4.158 -        new Option(false, "--version") {
   4.159 -            void process(JdepsTask task, String opt, String arg) {
   4.160 -                task.options.version = true;
   4.161 -            }
   4.162 -        },
   4.163 -        new HiddenOption(false, "--fullversion") {
   4.164 -            void process(JdepsTask task, String opt, String arg) {
   4.165 -                task.options.fullVersion = true;
   4.166 -            }
   4.167 -        },
   4.168      };
   4.169  
   4.170      private static final String PROGNAME = "jdeps";
   4.171 @@ -202,7 +231,7 @@
   4.172              if (options.version || options.fullVersion) {
   4.173                  showVersion(options.fullVersion);
   4.174              }
   4.175 -            if (classes.isEmpty() && !options.wildcard) {
   4.176 +            if (classes.isEmpty() && options.includePattern == null) {
   4.177                  if (options.help || options.version || options.fullVersion) {
   4.178                      return EXIT_OK;
   4.179                  } else {
   4.180 @@ -233,19 +262,51 @@
   4.181          }
   4.182      }
   4.183  
   4.184 -    private final List<Archive> sourceLocations = new ArrayList<Archive>();
   4.185 +    private final List<Archive> sourceLocations = new ArrayList<>();
   4.186      private boolean run() throws IOException {
   4.187          findDependencies();
   4.188          Analyzer analyzer = new Analyzer(options.verbose);
   4.189          analyzer.run(sourceLocations);
   4.190 -        if (options.verbose == Analyzer.Type.SUMMARY) {
   4.191 -            printSummary(log, analyzer);
   4.192 +        if (options.dotOutputDir != null) {
   4.193 +            Path dir = Paths.get(options.dotOutputDir);
   4.194 +            Files.createDirectories(dir);
   4.195 +            generateDotFiles(dir, analyzer);
   4.196          } else {
   4.197 -            printDependencies(log, analyzer);
   4.198 +            printRawOutput(log, analyzer);
   4.199          }
   4.200          return true;
   4.201      }
   4.202  
   4.203 +    private void generateDotFiles(Path dir, Analyzer analyzer) throws IOException {
   4.204 +        Path summary = dir.resolve("summary.dot");
   4.205 +        try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary));
   4.206 +             DotFileFormatter formatter = new DotFileFormatter(sw, "summary")) {
   4.207 +            for (Archive archive : sourceLocations) {
   4.208 +                 analyzer.visitArchiveDependences(archive, formatter);
   4.209 +            }
   4.210 +        }
   4.211 +        if (options.verbose != Analyzer.Type.SUMMARY) {
   4.212 +            for (Archive archive : sourceLocations) {
   4.213 +                if (analyzer.hasDependences(archive)) {
   4.214 +                    Path dotfile = dir.resolve(archive.getFileName() + ".dot");
   4.215 +                    try (PrintWriter pw = new PrintWriter(Files.newOutputStream(dotfile));
   4.216 +                         DotFileFormatter formatter = new DotFileFormatter(pw, archive)) {
   4.217 +                        analyzer.visitDependences(archive, formatter);
   4.218 +                    }
   4.219 +                }
   4.220 +            }
   4.221 +        }
   4.222 +    }
   4.223 +
   4.224 +    private void printRawOutput(PrintWriter writer, Analyzer analyzer) {
   4.225 +        for (Archive archive : sourceLocations) {
   4.226 +            RawOutputFormatter formatter = new RawOutputFormatter(writer);
   4.227 +            analyzer.visitArchiveDependences(archive, formatter);
   4.228 +            if (options.verbose != Analyzer.Type.SUMMARY) {
   4.229 +                analyzer.visitDependences(archive, formatter);
   4.230 +            }
   4.231 +        }
   4.232 +    }
   4.233      private boolean isValidClassName(String name) {
   4.234          if (!Character.isJavaIdentifierStart(name.charAt(0))) {
   4.235              return false;
   4.236 @@ -259,27 +320,43 @@
   4.237          return true;
   4.238      }
   4.239  
   4.240 -    private void findDependencies() throws IOException {
   4.241 -        Dependency.Finder finder = Dependencies.getClassDependencyFinder();
   4.242 -        Dependency.Filter filter;
   4.243 -        if (options.regex != null) {
   4.244 -            filter = Dependencies.getRegexFilter(Pattern.compile(options.regex));
   4.245 +    private Dependency.Filter getDependencyFilter() {
   4.246 +         if (options.regex != null) {
   4.247 +            return Dependencies.getRegexFilter(Pattern.compile(options.regex));
   4.248          } else if (options.packageNames.size() > 0) {
   4.249 -            filter = Dependencies.getPackageFilter(options.packageNames, false);
   4.250 +            return Dependencies.getPackageFilter(options.packageNames, false);
   4.251          } else {
   4.252 -            filter = new Dependency.Filter() {
   4.253 +            return new Dependency.Filter() {
   4.254 +                @Override
   4.255                  public boolean accepts(Dependency dependency) {
   4.256                      return !dependency.getOrigin().equals(dependency.getTarget());
   4.257                  }
   4.258              };
   4.259          }
   4.260 +    }
   4.261  
   4.262 -        List<Archive> archives = new ArrayList<Archive>();
   4.263 -        Deque<String> roots = new LinkedList<String>();
   4.264 +    private boolean matches(String classname, AccessFlags flags) {
   4.265 +        if (options.apiOnly && !flags.is(AccessFlags.ACC_PUBLIC)) {
   4.266 +            return false;
   4.267 +        } else if (options.includePattern != null) {
   4.268 +            return options.includePattern.matcher(classname.replace('/', '.')).matches();
   4.269 +        } else {
   4.270 +            return true;
   4.271 +        }
   4.272 +    }
   4.273 +
   4.274 +    private void findDependencies() throws IOException {
   4.275 +        Dependency.Finder finder =
   4.276 +            options.apiOnly ? Dependencies.getAPIFinder(AccessFlags.ACC_PROTECTED)
   4.277 +                            : Dependencies.getClassDependencyFinder();
   4.278 +        Dependency.Filter filter = getDependencyFilter();
   4.279 +
   4.280 +        List<Archive> archives = new ArrayList<>();
   4.281 +        Deque<String> roots = new LinkedList<>();
   4.282          for (String s : classes) {
   4.283 -            File f = new File(s);
   4.284 -            if (f.exists()) {
   4.285 -                archives.add(new Archive(f, ClassFileReader.newInstance(f)));
   4.286 +            Path p = Paths.get(s);
   4.287 +            if (Files.exists(p)) {
   4.288 +                archives.add(new Archive(p, ClassFileReader.newInstance(p)));
   4.289              } else {
   4.290                  if (isValidClassName(s)) {
   4.291                      roots.add(s);
   4.292 @@ -289,9 +366,8 @@
   4.293              }
   4.294          }
   4.295  
   4.296 -        List<Archive> classpaths = new ArrayList<Archive>(); // for class file lookup
   4.297 -        if (options.wildcard) {
   4.298 -            // include all archives from classpath to the initial list
   4.299 +        List<Archive> classpaths = new ArrayList<>(); // for class file lookup
   4.300 +        if (options.includePattern != null) {
   4.301              archives.addAll(getClassPathArchives(options.classpath));
   4.302          } else {
   4.303              classpaths.addAll(getClassPathArchives(options.classpath));
   4.304 @@ -305,8 +381,8 @@
   4.305          // Work queue of names of classfiles to be searched.
   4.306          // Entries will be unique, and for classes that do not yet have
   4.307          // dependencies in the results map.
   4.308 -        Deque<String> deque = new LinkedList<String>();
   4.309 -        Set<String> doneClasses = new HashSet<String>();
   4.310 +        Deque<String> deque = new LinkedList<>();
   4.311 +        Set<String> doneClasses = new HashSet<>();
   4.312  
   4.313          // get the immediate dependencies of the input files
   4.314          for (Archive a : archives) {
   4.315 @@ -318,16 +394,18 @@
   4.316                      throw new ClassFileError(e);
   4.317                  }
   4.318  
   4.319 -                if (!doneClasses.contains(classFileName)) {
   4.320 -                    doneClasses.add(classFileName);
   4.321 -                }
   4.322 -                for (Dependency d : finder.findDependencies(cf)) {
   4.323 -                    if (filter.accepts(d)) {
   4.324 -                        String cn = d.getTarget().getName();
   4.325 -                        if (!doneClasses.contains(cn) && !deque.contains(cn)) {
   4.326 -                            deque.add(cn);
   4.327 +                if (matches(classFileName, cf.access_flags)) {
   4.328 +                    if (!doneClasses.contains(classFileName)) {
   4.329 +                        doneClasses.add(classFileName);
   4.330 +                    }
   4.331 +                    for (Dependency d : finder.findDependencies(cf)) {
   4.332 +                        if (filter.accepts(d)) {
   4.333 +                            String cn = d.getTarget().getName();
   4.334 +                            if (!doneClasses.contains(cn) && !deque.contains(cn)) {
   4.335 +                                deque.add(cn);
   4.336 +                            }
   4.337 +                            a.addClass(d.getOrigin(), d.getTarget());
   4.338                          }
   4.339 -                        a.addClass(d.getOrigin(), d.getTarget());
   4.340                      }
   4.341                  }
   4.342              }
   4.343 @@ -379,46 +457,10 @@
   4.344                  }
   4.345              }
   4.346              unresolved = deque;
   4.347 -            deque = new LinkedList<String>();
   4.348 +            deque = new LinkedList<>();
   4.349          } while (!unresolved.isEmpty() && depth-- > 0);
   4.350      }
   4.351  
   4.352 -    private void printSummary(final PrintWriter out, final Analyzer analyzer) {
   4.353 -        Analyzer.Visitor visitor = new Analyzer.Visitor() {
   4.354 -            public void visit(String origin, String target, String profile) {
   4.355 -                if (options.showProfile) {
   4.356 -                    out.format("%-30s -> %s%n", origin, target);
   4.357 -                }
   4.358 -            }
   4.359 -            public void visit(Archive origin, Archive target) {
   4.360 -                if (!options.showProfile) {
   4.361 -                    out.format("%-30s -> %s%n", origin, target);
   4.362 -                }
   4.363 -            }
   4.364 -        };
   4.365 -        analyzer.visitSummary(visitor);
   4.366 -    }
   4.367 -
   4.368 -    private void printDependencies(final PrintWriter out, final Analyzer analyzer) {
   4.369 -        Analyzer.Visitor visitor = new Analyzer.Visitor() {
   4.370 -            private String pkg = "";
   4.371 -            public void visit(String origin, String target, String profile) {
   4.372 -                if (!origin.equals(pkg)) {
   4.373 -                    pkg = origin;
   4.374 -                    out.format("   %s (%s)%n", origin, analyzer.getArchive(origin).getFileName());
   4.375 -                }
   4.376 -                out.format("      -> %-50s %s%n", target,
   4.377 -                           (options.showProfile && !profile.isEmpty())
   4.378 -                               ? profile
   4.379 -                               : analyzer.getArchiveName(target, profile));
   4.380 -            }
   4.381 -            public void visit(Archive origin, Archive target) {
   4.382 -                out.format("%s -> %s%n", origin, target);
   4.383 -            }
   4.384 -        };
   4.385 -        analyzer.visit(visitor);
   4.386 -    }
   4.387 -
   4.388      public void handleOptions(String[] args) throws BadArgs {
   4.389          // process options
   4.390          for (int i=0; i < args.length; i++) {
   4.391 @@ -427,7 +469,7 @@
   4.392                  Option option = getOption(name);
   4.393                  String param = null;
   4.394                  if (option.hasArg) {
   4.395 -                    if (name.startsWith("--") && name.indexOf('=') > 0) {
   4.396 +                    if (name.startsWith("-") && name.indexOf('=') > 0) {
   4.397                          param = name.substring(name.indexOf('=') + 1, name.length());
   4.398                      } else if (i + 1 < args.length) {
   4.399                          param = args[++i];
   4.400 @@ -447,11 +489,7 @@
   4.401                      if (name.charAt(0) == '-') {
   4.402                          throw new BadArgs("err.option.after.class", name).showUsage(true);
   4.403                      }
   4.404 -                    if (name.equals("*") || name.equals("\"*\"")) {
   4.405 -                        options.wildcard = true;
   4.406 -                    } else {
   4.407 -                        classes.add(name);
   4.408 -                    }
   4.409 +                    classes.add(name);
   4.410                  }
   4.411              }
   4.412          }
   4.413 @@ -518,13 +556,15 @@
   4.414          boolean showProfile;
   4.415          boolean showSummary;
   4.416          boolean wildcard;
   4.417 -        String regex;
   4.418 +        boolean apiOnly;
   4.419 +        String dotOutputDir;
   4.420          String classpath = "";
   4.421          int depth = 1;
   4.422          Analyzer.Type verbose = Analyzer.Type.PACKAGE;
   4.423 -        Set<String> packageNames = new HashSet<String>();
   4.424 +        Set<String> packageNames = new HashSet<>();
   4.425 +        String regex;             // apply to the dependences
   4.426 +        Pattern includePattern;   // apply to classes
   4.427      }
   4.428 -
   4.429      private static class ResourceBundleHelper {
   4.430          static final ResourceBundle versionRB;
   4.431          static final ResourceBundle bundle;
   4.432 @@ -547,9 +587,9 @@
   4.433      private List<Archive> getArchives(List<String> filenames) throws IOException {
   4.434          List<Archive> result = new ArrayList<Archive>();
   4.435          for (String s : filenames) {
   4.436 -            File f = new File(s);
   4.437 -            if (f.exists()) {
   4.438 -                result.add(new Archive(f, ClassFileReader.newInstance(f)));
   4.439 +            Path p = Paths.get(s);
   4.440 +            if (Files.exists(p)) {
   4.441 +                result.add(new Archive(p, ClassFileReader.newInstance(p)));
   4.442              } else {
   4.443                  warning("warn.file.not.exist", s);
   4.444              }
   4.445 @@ -558,18 +598,131 @@
   4.446      }
   4.447  
   4.448      private List<Archive> getClassPathArchives(String paths) throws IOException {
   4.449 -        List<Archive> result = new ArrayList<Archive>();
   4.450 +        List<Archive> result = new ArrayList<>();
   4.451          if (paths.isEmpty()) {
   4.452              return result;
   4.453          }
   4.454          for (String p : paths.split(File.pathSeparator)) {
   4.455              if (p.length() > 0) {
   4.456 -                File f = new File(p);
   4.457 -                if (f.exists()) {
   4.458 -                    result.add(new Archive(f, ClassFileReader.newInstance(f)));
   4.459 +                List<Path> files = new ArrayList<>();
   4.460 +                // wildcard to parse all JAR files e.g. -classpath dir/*
   4.461 +                int i = p.lastIndexOf(".*");
   4.462 +                if (i > 0) {
   4.463 +                    Path dir = Paths.get(p.substring(0, i));
   4.464 +                    try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.jar")) {
   4.465 +                        for (Path entry : stream) {
   4.466 +                            files.add(entry);
   4.467 +                        }
   4.468 +                    }
   4.469 +                } else {
   4.470 +                    files.add(Paths.get(p));
   4.471 +                }
   4.472 +                for (Path f : files) {
   4.473 +                    if (Files.exists(f)) {
   4.474 +                        result.add(new Archive(f, ClassFileReader.newInstance(f)));
   4.475 +                    }
   4.476                  }
   4.477              }
   4.478          }
   4.479          return result;
   4.480      }
   4.481 +
   4.482 +
   4.483 +    /**
   4.484 +     * Returns the file name of the archive for non-JRE class or
   4.485 +     * internal JRE classes.  It returns empty string for SE API.
   4.486 +     */
   4.487 +    private static String getArchiveName(Archive source, String profile) {
   4.488 +        String name = source.getFileName();
   4.489 +        if (source instanceof JDKArchive)
   4.490 +            return profile.isEmpty() ? "JDK internal API (" + name + ")" : "";
   4.491 +        return name;
   4.492 +    }
   4.493 +
   4.494 +    class RawOutputFormatter implements Analyzer.Visitor {
   4.495 +        private final PrintWriter writer;
   4.496 +        RawOutputFormatter(PrintWriter writer) {
   4.497 +            this.writer = writer;
   4.498 +        }
   4.499 +
   4.500 +        private String pkg = "";
   4.501 +        @Override
   4.502 +        public void visitDependence(String origin, Archive source,
   4.503 +                                    String target, Archive archive, String profile) {
   4.504 +            if (!origin.equals(pkg)) {
   4.505 +                pkg = origin;
   4.506 +                writer.format("   %s (%s)%n", origin, source.getFileName());
   4.507 +            }
   4.508 +            String name = (options.showProfile && !profile.isEmpty())
   4.509 +                                ? profile
   4.510 +                                : getArchiveName(archive, profile);
   4.511 +            writer.format("      -> %-50s %s%n", target, name);
   4.512 +        }
   4.513 +
   4.514 +        @Override
   4.515 +        public void visitArchiveDependence(Archive origin, Archive target, String profile) {
   4.516 +            writer.format("%s -> %s", origin, target);
   4.517 +            if (options.showProfile && !profile.isEmpty()) {
   4.518 +                writer.format(" (%s)%n", profile);
   4.519 +            } else {
   4.520 +                writer.format("%n");
   4.521 +            }
   4.522 +        }
   4.523 +    }
   4.524 +
   4.525 +    class DotFileFormatter implements Analyzer.Visitor, AutoCloseable {
   4.526 +        private final PrintWriter writer;
   4.527 +        private final String name;
   4.528 +        DotFileFormatter(PrintWriter writer, String name) {
   4.529 +            this.writer = writer;
   4.530 +            this.name = name;
   4.531 +            writer.format("digraph \"%s\" {%n", name);
   4.532 +        }
   4.533 +        DotFileFormatter(PrintWriter writer, Archive archive) {
   4.534 +            this.writer = writer;
   4.535 +            this.name = archive.getFileName();
   4.536 +            writer.format("digraph \"%s\" {%n", name);
   4.537 +            writer.format("    // Path: %s%n", archive.toString());
   4.538 +        }
   4.539 +
   4.540 +        @Override
   4.541 +        public void close() {
   4.542 +            writer.println("}");
   4.543 +        }
   4.544 +
   4.545 +        private final Set<String> edges = new HashSet<>();
   4.546 +        private String node = "";
   4.547 +        @Override
   4.548 +        public void visitDependence(String origin, Archive source,
   4.549 +                                    String target, Archive archive, String profile) {
   4.550 +            if (!node.equals(origin)) {
   4.551 +                edges.clear();
   4.552 +                node = origin;
   4.553 +            }
   4.554 +            // if -P option is specified, package name -> profile will
   4.555 +            // be shown and filter out multiple same edges.
   4.556 +            if (!edges.contains(target)) {
   4.557 +                StringBuilder sb = new StringBuilder();
   4.558 +                String name = options.showProfile && !profile.isEmpty()
   4.559 +                                  ? profile
   4.560 +                                  : getArchiveName(archive, profile);
   4.561 +                writer.format("   %-50s -> %s;%n",
   4.562 +                                 String.format("\"%s\"", origin),
   4.563 +                                 name.isEmpty() ? String.format("\"%s\"", target)
   4.564 +                                                :  String.format("\"%s (%s)\"", target, name));
   4.565 +                edges.add(target);
   4.566 +            }
   4.567 +        }
   4.568 +
   4.569 +        @Override
   4.570 +        public void visitArchiveDependence(Archive origin, Archive target, String profile) {
   4.571 +             String name = options.showProfile && !profile.isEmpty()
   4.572 +                                ? profile : "";
   4.573 +             writer.format("   %-30s -> \"%s\";%n",
   4.574 +                           String.format("\"%s\"", origin.getFileName()),
   4.575 +                           name.isEmpty()
   4.576 +                               ? target.getFileName()
   4.577 +                               : String.format("%s (%s)", target.getFileName(), name));
   4.578 +        }
   4.579 +    }
   4.580  }
     5.1 --- a/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java	Thu Oct 17 13:50:00 2013 +0200
     5.2 +++ b/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java	Thu Oct 17 13:19:48 2013 -0700
     5.3 @@ -24,11 +24,11 @@
     5.4   */
     5.5  package com.sun.tools.jdeps;
     5.6  
     5.7 -import java.io.File;
     5.8  import java.io.IOException;
     5.9  import java.nio.file.FileVisitResult;
    5.10  import java.nio.file.Files;
    5.11  import java.nio.file.Path;
    5.12 +import java.nio.file.Paths;
    5.13  import java.nio.file.SimpleFileVisitor;
    5.14  import java.nio.file.attribute.BasicFileAttributes;
    5.15  import java.util.*;
    5.16 @@ -38,45 +38,38 @@
    5.17   */
    5.18  class PlatformClassPath {
    5.19      private final static List<Archive> javaHomeArchives = init();
    5.20 +
    5.21      static List<Archive> getArchives() {
    5.22          return javaHomeArchives;
    5.23      }
    5.24  
    5.25 -    static boolean contains(Archive archive) {
    5.26 -        return javaHomeArchives.contains(archive);
    5.27 +    private static List<Archive> init() {
    5.28 +        List<Archive> result = new ArrayList<>();
    5.29 +        Path home = Paths.get(System.getProperty("java.home"));
    5.30 +        try {
    5.31 +            if (home.endsWith("jre")) {
    5.32 +                // jar files in <javahome>/jre/lib
    5.33 +                result.addAll(addJarFiles(home.resolve("lib")));
    5.34 +            } else if (Files.exists(home.resolve("lib"))) {
    5.35 +                // either a JRE or a jdk build image
    5.36 +                Path classes = home.resolve("classes");
    5.37 +                if (Files.isDirectory(classes)) {
    5.38 +                    // jdk build outputdir
    5.39 +                    result.add(new JDKArchive(classes, ClassFileReader.newInstance(classes)));
    5.40 +                }
    5.41 +                // add other JAR files
    5.42 +                result.addAll(addJarFiles(home.resolve("lib")));
    5.43 +            } else {
    5.44 +                throw new RuntimeException("\"" + home + "\" not a JDK home");
    5.45 +            }
    5.46 +            return result;
    5.47 +        } catch (IOException e) {
    5.48 +            throw new Error(e);
    5.49 +        }
    5.50      }
    5.51  
    5.52 -    private static List<Archive> init() {
    5.53 -        List<Archive> result = new ArrayList<Archive>();
    5.54 -        String javaHome = System.getProperty("java.home");
    5.55 -        File jre = new File(javaHome, "jre");
    5.56 -        File lib = new File(javaHome, "lib");
    5.57 -
    5.58 -        try {
    5.59 -            if (jre.exists() && jre.isDirectory()) {
    5.60 -                result.addAll(addJarFiles(new File(jre, "lib")));
    5.61 -                result.addAll(addJarFiles(lib));
    5.62 -            } else if (lib.exists() && lib.isDirectory()) {
    5.63 -                // either a JRE or a jdk build image
    5.64 -                File classes = new File(javaHome, "classes");
    5.65 -                if (classes.exists() && classes.isDirectory()) {
    5.66 -                    // jdk build outputdir
    5.67 -                    result.add(new Archive(classes, ClassFileReader.newInstance(classes)));
    5.68 -                }
    5.69 -                // add other JAR files
    5.70 -                result.addAll(addJarFiles(lib));
    5.71 -            } else {
    5.72 -                throw new RuntimeException("\"" + javaHome + "\" not a JDK home");
    5.73 -            }
    5.74 -        } catch (IOException e) {
    5.75 -            throw new RuntimeException(e);
    5.76 -        }
    5.77 -        return result;
    5.78 -    }
    5.79 -
    5.80 -    private static List<Archive> addJarFiles(File f) throws IOException {
    5.81 -        final List<Archive> result = new ArrayList<Archive>();
    5.82 -        final Path root = f.toPath();
    5.83 +    private static List<Archive> addJarFiles(final Path root) throws IOException {
    5.84 +        final List<Archive> result = new ArrayList<>();
    5.85          final Path ext = root.resolve("ext");
    5.86          Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
    5.87              @Override
    5.88 @@ -91,17 +84,30 @@
    5.89                  }
    5.90              }
    5.91              @Override
    5.92 -            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
    5.93 +            public FileVisitResult visitFile(Path p, BasicFileAttributes attrs)
    5.94                  throws IOException
    5.95              {
    5.96 -                File f = file.toFile();
    5.97 -                String fn = f.getName();
    5.98 -                if (fn.endsWith(".jar") && !fn.equals("alt-rt.jar")) {
    5.99 -                    result.add(new Archive(f, ClassFileReader.newInstance(f)));
   5.100 +                String fn = p.getFileName().toString();
   5.101 +                if (fn.endsWith(".jar")) {
   5.102 +                    // JDK may cobundle with JavaFX that doesn't belong to any profile
   5.103 +                    // Treat jfxrt.jar as regular Archive
   5.104 +                    result.add(fn.equals("jfxrt.jar")
   5.105 +                        ? new Archive(p, ClassFileReader.newInstance(p))
   5.106 +                        : new JDKArchive(p, ClassFileReader.newInstance(p)));
   5.107                  }
   5.108                  return FileVisitResult.CONTINUE;
   5.109              }
   5.110          });
   5.111          return result;
   5.112      }
   5.113 +
   5.114 +    /**
   5.115 +     * A JDK archive is part of the JDK containing the Java SE API
   5.116 +     * or implementation classes (i.e. JDK internal API)
   5.117 +     */
   5.118 +    static class JDKArchive extends Archive {
   5.119 +        JDKArchive(Path p, ClassFileReader reader) {
   5.120 +            super(p, reader);
   5.121 +        }
   5.122 +    }
   5.123  }
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/share/classes/com/sun/tools/jdeps/Profile.java	Thu Oct 17 13:19:48 2013 -0700
     6.3 @@ -0,0 +1,227 @@
     6.4 +/*
     6.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.  Oracle designates this
    6.11 + * particular file as subject to the "Classpath" exception as provided
    6.12 + * by Oracle in the LICENSE file that accompanied this code.
    6.13 + *
    6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.17 + * version 2 for more details (a copy is included in the LICENSE file that
    6.18 + * accompanied this code).
    6.19 + *
    6.20 + * You should have received a copy of the GNU General Public License version
    6.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.23 + *
    6.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.25 + * or visit www.oracle.com if you need additional information or have any
    6.26 + * questions.
    6.27 + */
    6.28 +package com.sun.tools.jdeps;
    6.29 +
    6.30 +import com.sun.tools.classfile.Annotation;
    6.31 +import com.sun.tools.classfile.Annotation.*;
    6.32 +import com.sun.tools.classfile.Attribute;
    6.33 +import com.sun.tools.classfile.ClassFile;
    6.34 +import com.sun.tools.classfile.ConstantPool.*;
    6.35 +import com.sun.tools.classfile.ConstantPoolException;
    6.36 +import com.sun.tools.classfile.RuntimeAnnotations_attribute;
    6.37 +import java.io.FileReader;
    6.38 +import java.io.IOException;
    6.39 +import java.nio.file.Files;
    6.40 +import java.nio.file.Path;
    6.41 +import java.nio.file.Paths;
    6.42 +import java.util.*;
    6.43 +import java.util.jar.JarFile;
    6.44 +
    6.45 +/**
    6.46 + * Build the profile information from ct.sym if exists.
    6.47 + */
    6.48 +enum Profile {
    6.49 +
    6.50 +    COMPACT1("compact1", 1),
    6.51 +    COMPACT2("compact2", 2),
    6.52 +    COMPACT3("compact3", 3),
    6.53 +    FULL_JRE("Full JRE", 4);
    6.54 +
    6.55 +    final String name;
    6.56 +    final int profile;
    6.57 +    final Set<String> packages;
    6.58 +    final Set<String> proprietaryPkgs;
    6.59 +
    6.60 +    Profile(String name, int profile) {
    6.61 +        this.name = name;
    6.62 +        this.profile = profile;
    6.63 +        this.packages = new HashSet<>();
    6.64 +        this.proprietaryPkgs = new HashSet<>();
    6.65 +    }
    6.66 +
    6.67 +    @Override
    6.68 +    public String toString() {
    6.69 +        return name;
    6.70 +    }
    6.71 +
    6.72 +    public static int getProfileCount() {
    6.73 +        return PackageToProfile.map.values().size();
    6.74 +    }
    6.75 +
    6.76 +    /**
    6.77 +     * Returns the Profile for the given package name. It returns an empty
    6.78 +     * string if the given package is not in any profile.
    6.79 +     */
    6.80 +    public static Profile getProfile(String pn) {
    6.81 +        Profile profile = PackageToProfile.map.get(pn);
    6.82 +        return (profile != null && profile.packages.contains(pn))
    6.83 +                ? profile : null;
    6.84 +    }
    6.85 +
    6.86 +    static class PackageToProfile {
    6.87 +        static Map<String, Profile> map = initProfiles();
    6.88 +
    6.89 +        private static Map<String, Profile> initProfiles() {
    6.90 +            try {
    6.91 +                String profilesProps = System.getProperty("jdeps.profiles");
    6.92 +                if (profilesProps != null) {
    6.93 +                    // for testing for JDK development build where ct.sym doesn't exist
    6.94 +                    initProfilesFromProperties(profilesProps);
    6.95 +                } else {
    6.96 +                    Path home = Paths.get(System.getProperty("java.home"));
    6.97 +                    if (home.endsWith("jre")) {
    6.98 +                        home = home.getParent();
    6.99 +                    }
   6.100 +                    Path ctsym = home.resolve("lib").resolve("ct.sym");
   6.101 +                    if (Files.exists(ctsym)) {
   6.102 +                        // parse ct.sym and load information about profiles
   6.103 +                        try (JarFile jf = new JarFile(ctsym.toFile())) {
   6.104 +                            ClassFileReader reader = ClassFileReader.newInstance(ctsym, jf);
   6.105 +                            for (ClassFile cf : reader.getClassFiles()) {
   6.106 +                                findProfile(cf);
   6.107 +                            }
   6.108 +                        }
   6.109 +                    }
   6.110 +                }
   6.111 +            } catch (IOException | ConstantPoolException e) {
   6.112 +                throw new Error(e);
   6.113 +            }
   6.114 +            HashMap<String,Profile> map = new HashMap<>();
   6.115 +            for (Profile profile : Profile.values()) {
   6.116 +                for (String pn : profile.packages) {
   6.117 +                    if (!map.containsKey(pn)) {
   6.118 +                        // split packages in the JRE: use the smaller compact
   6.119 +                        map.put(pn, profile);
   6.120 +                    }
   6.121 +                }
   6.122 +                for (String pn : profile.proprietaryPkgs) {
   6.123 +                    if (!map.containsKey(pn)) {
   6.124 +                        map.put(pn, profile);
   6.125 +                    }
   6.126 +                }
   6.127 +            }
   6.128 +            return map;
   6.129 +        }
   6.130 +        private static final String PROFILE_ANNOTATION = "Ljdk/Profile+Annotation;";
   6.131 +        private static final String PROPRIETARY_ANNOTATION = "Lsun/Proprietary+Annotation;";
   6.132 +        private static Profile findProfile(ClassFile cf) throws ConstantPoolException {
   6.133 +            RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute)
   6.134 +                cf.attributes.get(Attribute.RuntimeInvisibleAnnotations);
   6.135 +            int index = 0;
   6.136 +            boolean proprietary = false;
   6.137 +            if (attr != null) {
   6.138 +                for (int i = 0; i < attr.annotations.length; i++) {
   6.139 +                    Annotation ann = attr.annotations[i];
   6.140 +                    String annType = cf.constant_pool.getUTF8Value(ann.type_index);
   6.141 +                    if (PROFILE_ANNOTATION.equals(annType)) {
   6.142 +                        for (int j = 0; j < ann.num_element_value_pairs; j++) {
   6.143 +                            Annotation.element_value_pair pair = ann.element_value_pairs[j];
   6.144 +                            Primitive_element_value ev = (Primitive_element_value) pair.value;
   6.145 +                            CONSTANT_Integer_info info = (CONSTANT_Integer_info)
   6.146 +                                cf.constant_pool.get(ev.const_value_index);
   6.147 +                            index = info.value;
   6.148 +                            break;
   6.149 +                        }
   6.150 +                    } else if (PROPRIETARY_ANNOTATION.equals(annType)) {
   6.151 +                        proprietary = true;
   6.152 +                    }
   6.153 +                }
   6.154 +            }
   6.155 +
   6.156 +            Profile p = null;  // default
   6.157 +            switch (index) {
   6.158 +                case 1:
   6.159 +                    p = Profile.COMPACT1; break;
   6.160 +                case 2:
   6.161 +                    p = Profile.COMPACT2; break;
   6.162 +                case 3:
   6.163 +                    p = Profile.COMPACT3; break;
   6.164 +                case 4:
   6.165 +                    p = Profile.FULL_JRE; break;
   6.166 +                default:
   6.167 +                    // skip classes with profile=0
   6.168 +                    // Inner classes are not annotated with the profile annotation
   6.169 +                    return null;
   6.170 +            }
   6.171 +
   6.172 +            String name = cf.getName();
   6.173 +            int i = name.lastIndexOf('/');
   6.174 +            name = (i > 0) ? name.substring(0, i).replace('/', '.') : "";
   6.175 +            if (proprietary) {
   6.176 +                p.proprietaryPkgs.add(name);
   6.177 +            } else {
   6.178 +                p.packages.add(name);
   6.179 +            }
   6.180 +            return p;
   6.181 +        }
   6.182 +
   6.183 +        private static void initProfilesFromProperties(String path) throws IOException {
   6.184 +            Properties props = new Properties();
   6.185 +            try (FileReader reader = new FileReader(path)) {
   6.186 +                props.load(reader);
   6.187 +            }
   6.188 +            for (Profile prof : Profile.values()) {
   6.189 +                int i = prof.profile;
   6.190 +                String key = props.getProperty("profile." + i + ".name");
   6.191 +                if (key == null) {
   6.192 +                    throw new RuntimeException(key + " missing in " + path);
   6.193 +                }
   6.194 +                String n = props.getProperty("profile." + i + ".packages");
   6.195 +                String[] pkgs = n.split("\\s+");
   6.196 +                for (String p : pkgs) {
   6.197 +                    if (p.isEmpty()) continue;
   6.198 +                    prof.packages.add(p);
   6.199 +                }
   6.200 +            }
   6.201 +        }
   6.202 +    }
   6.203 +
   6.204 +    // for debugging
   6.205 +    public static void main(String[] args) {
   6.206 +        if (args.length == 0) {
   6.207 +            if (Profile.getProfileCount() == 0) {
   6.208 +                System.err.println("No profile is present in this JDK");
   6.209 +            }
   6.210 +            for (Profile p : Profile.values()) {
   6.211 +                String profileName = p.name;
   6.212 +                SortedSet<String> set = new TreeSet<>(p.packages);
   6.213 +                for (String s : set) {
   6.214 +                    // filter out the inner classes that are not annotated with
   6.215 +                    // the profile annotation
   6.216 +                    if (PackageToProfile.map.get(s) == p) {
   6.217 +                        System.out.format("%2d: %-10s  %s%n", p.profile, profileName, s);
   6.218 +                        profileName = "";
   6.219 +                    } else {
   6.220 +                        System.err.format("Split package: %s in %s and %s %n",
   6.221 +                            s, PackageToProfile.map.get(s).name, p.name);
   6.222 +                    }
   6.223 +                }
   6.224 +            }
   6.225 +        }
   6.226 +        for (String pn : args) {
   6.227 +            System.out.format("%s in %s%n", pn, getProfile(pn));
   6.228 +        }
   6.229 +    }
   6.230 +}
     7.1 --- a/src/share/classes/com/sun/tools/jdeps/Profiles.java	Thu Oct 17 13:50:00 2013 +0200
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,241 +0,0 @@
     7.4 -/*
     7.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     7.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 - *
     7.8 - * This code is free software; you can redistribute it and/or modify it
     7.9 - * under the terms of the GNU General Public License version 2 only, as
    7.10 - * published by the Free Software Foundation.  Oracle designates this
    7.11 - * particular file as subject to the "Classpath" exception as provided
    7.12 - * by Oracle in the LICENSE file that accompanied this code.
    7.13 - *
    7.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
    7.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.17 - * version 2 for more details (a copy is included in the LICENSE file that
    7.18 - * accompanied this code).
    7.19 - *
    7.20 - * You should have received a copy of the GNU General Public License version
    7.21 - * 2 along with this work; if not, write to the Free Software Foundation,
    7.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.23 - *
    7.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.25 - * or visit www.oracle.com if you need additional information or have any
    7.26 - * questions.
    7.27 - */
    7.28 -package com.sun.tools.jdeps;
    7.29 -
    7.30 -import com.sun.tools.classfile.Annotation;
    7.31 -import com.sun.tools.classfile.Annotation.*;
    7.32 -import com.sun.tools.classfile.Attribute;
    7.33 -import com.sun.tools.classfile.ClassFile;
    7.34 -import com.sun.tools.classfile.ConstantPool;
    7.35 -import com.sun.tools.classfile.ConstantPool.*;
    7.36 -import com.sun.tools.classfile.ConstantPoolException;
    7.37 -import com.sun.tools.classfile.RuntimeAnnotations_attribute;
    7.38 -import java.io.File;
    7.39 -import java.io.FileReader;
    7.40 -import java.io.IOException;
    7.41 -import java.nio.file.Path;
    7.42 -import java.nio.file.Paths;
    7.43 -import java.util.*;
    7.44 -import java.util.jar.JarFile;
    7.45 -
    7.46 -/**
    7.47 - * Build the profile information from ct.sym if exists.
    7.48 - */
    7.49 -class Profiles {
    7.50 -    private static final Map<String,Profile> map = initProfiles();
    7.51 -    /**
    7.52 -     * Returns the name of the profile for the given package name.
    7.53 -     * It returns an empty string if the given package is not in any profile.
    7.54 -     */
    7.55 -    public static String getProfileName(String pn) {
    7.56 -        Profile profile = map.get(pn);
    7.57 -        return (profile != null && profile.packages.contains(pn))
    7.58 -                    ? profile.name : "";
    7.59 -    }
    7.60 -
    7.61 -    public static int getProfileCount() {
    7.62 -        return new HashSet<Profile>(map.values()).size();
    7.63 -    }
    7.64 -
    7.65 -    private static Map<String,Profile> initProfiles() {
    7.66 -        List<Profile> profiles = new ArrayList<Profile>();
    7.67 -        try {
    7.68 -            String profilesProps = System.getProperty("jdeps.profiles");
    7.69 -            if (profilesProps != null) {
    7.70 -                // for testing for JDK development build where ct.sym doesn't exist
    7.71 -                initProfilesFromProperties(profiles, profilesProps);
    7.72 -            } else {
    7.73 -                Path home = Paths.get(System.getProperty("java.home"));
    7.74 -                if (home.endsWith("jre")) {
    7.75 -                    home = home.getParent();
    7.76 -                }
    7.77 -                Path ctsym = home.resolve("lib").resolve("ct.sym");
    7.78 -                if (ctsym.toFile().exists()) {
    7.79 -                    // add a default Full JRE
    7.80 -                    profiles.add(0, new Profile("Full JRE", 0));
    7.81 -                    // parse ct.sym and load information about profiles
    7.82 -                    try (JarFile jf = new JarFile(ctsym.toFile())) {
    7.83 -                        ClassFileReader reader = ClassFileReader.newInstance(ctsym, jf);
    7.84 -                        for (ClassFile cf : reader.getClassFiles()) {
    7.85 -                            findProfile(profiles, cf);
    7.86 -                        }
    7.87 -                    }
    7.88 -
    7.89 -                    // merge the last Profile with the "Full JRE"
    7.90 -                    if (profiles.size() > 1) {
    7.91 -                        Profile fullJRE = profiles.get(0);
    7.92 -                        Profile p = profiles.remove(profiles.size() - 1);
    7.93 -                        for (String pn : fullJRE.packages) {
    7.94 -                            // The last profile contains the packages determined from ct.sym.
    7.95 -                            // Move classes annotated profile==0 or no attribute that are
    7.96 -                            // added in the fullJRE profile to either supported or proprietary
    7.97 -                            // packages appropriately
    7.98 -                            if (p.proprietaryPkgs.contains(pn)) {
    7.99 -                                p.proprietaryPkgs.add(pn);
   7.100 -                            } else {
   7.101 -                                p.packages.add(pn);
   7.102 -                            }
   7.103 -                        }
   7.104 -                        fullJRE.packages.clear();
   7.105 -                        fullJRE.proprietaryPkgs.clear();
   7.106 -                        fullJRE.packages.addAll(p.packages);
   7.107 -                        fullJRE.proprietaryPkgs.addAll(p.proprietaryPkgs);
   7.108 -                    }
   7.109 -                }
   7.110 -            }
   7.111 -        } catch (IOException | ConstantPoolException e) {
   7.112 -            throw new Error(e);
   7.113 -        }
   7.114 -        HashMap<String,Profile> map = new HashMap<String,Profile>();
   7.115 -        for (Profile profile : profiles) {
   7.116 -            // Inner classes are not annotated with the profile annotation
   7.117 -            // packages may be in one profile but also appear in the Full JRE
   7.118 -            // Full JRE is always the first element in profiles list and
   7.119 -            // so the map will contain the appropriate Profile
   7.120 -            for (String pn : profile.packages) {
   7.121 -                map.put(pn, profile);
   7.122 -            }
   7.123 -            for (String pn : profile.proprietaryPkgs) {
   7.124 -                map.put(pn, profile);
   7.125 -            }
   7.126 -        }
   7.127 -        return map;
   7.128 -    }
   7.129 -
   7.130 -    private static final String PROFILE_ANNOTATION = "Ljdk/Profile+Annotation;";
   7.131 -    private static final String PROPRIETARY_ANNOTATION = "Lsun/Proprietary+Annotation;";
   7.132 -    private static Profile findProfile(List<Profile> profiles, ClassFile cf)
   7.133 -            throws ConstantPoolException
   7.134 -    {
   7.135 -        RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute)
   7.136 -            cf.attributes.get(Attribute.RuntimeInvisibleAnnotations);
   7.137 -        int index = 0;
   7.138 -        boolean proprietary = false;
   7.139 -        if (attr != null) {
   7.140 -            for (int i = 0; i < attr.annotations.length; i++) {
   7.141 -                Annotation ann = attr.annotations[i];
   7.142 -                String annType = cf.constant_pool.getUTF8Value(ann.type_index);
   7.143 -                if (PROFILE_ANNOTATION.equals(annType)) {
   7.144 -                    for (int j = 0; j < ann.num_element_value_pairs; j++) {
   7.145 -                        Annotation.element_value_pair pair = ann.element_value_pairs[j];
   7.146 -                        Primitive_element_value ev = (Primitive_element_value)pair.value;
   7.147 -                        CONSTANT_Integer_info info = (CONSTANT_Integer_info)
   7.148 -                             cf.constant_pool.get(ev.const_value_index);
   7.149 -                        index = info.value;
   7.150 -                        break;
   7.151 -                    }
   7.152 -                } else if (PROPRIETARY_ANNOTATION.equals(annType)) {
   7.153 -                    proprietary = true;
   7.154 -                }
   7.155 -            }
   7.156 -            if (index >= profiles.size()) {
   7.157 -                Profile p = null;
   7.158 -                for (int i = profiles.size(); i <= index; i++) {
   7.159 -                    p = new Profile(i);
   7.160 -                    profiles.add(p);
   7.161 -                }
   7.162 -            }
   7.163 -        }
   7.164 -
   7.165 -        Profile p = profiles.get(index);
   7.166 -        String name = cf.getName();
   7.167 -        int i = name.lastIndexOf('/');
   7.168 -        name = (i > 0) ? name.substring(0, i).replace('/','.') : "";
   7.169 -        if (proprietary) {
   7.170 -            p.proprietaryPkgs.add(name);
   7.171 -        } else {
   7.172 -            p.packages.add(name);
   7.173 -        }
   7.174 -        return p;
   7.175 -    }
   7.176 -
   7.177 -    private static void initProfilesFromProperties(List<Profile> profiles, String path)
   7.178 -            throws IOException
   7.179 -    {
   7.180 -        Properties props = new Properties();
   7.181 -        try (FileReader reader = new FileReader(path)) {
   7.182 -            props.load(reader);
   7.183 -        }
   7.184 -        int i=1;
   7.185 -        String key;
   7.186 -        while (props.containsKey((key = "profile." + i + ".name"))) {
   7.187 -            Profile profile = new Profile(props.getProperty(key), i);
   7.188 -            profiles.add(profile);
   7.189 -            String n = props.getProperty("profile." + i + ".packages");
   7.190 -            String[] pkgs = n.split("\\s+");
   7.191 -            for (String p : pkgs) {
   7.192 -                if (p.isEmpty()) continue;
   7.193 -                profile.packages.add(p);
   7.194 -            }
   7.195 -            i++;
   7.196 -        }
   7.197 -    }
   7.198 -
   7.199 -    private static class Profile {
   7.200 -        final String name;
   7.201 -        final int profile;
   7.202 -        final Set<String> packages;
   7.203 -        final Set<String> proprietaryPkgs;
   7.204 -        Profile(int profile) {
   7.205 -            this("compact" + profile, profile);
   7.206 -        }
   7.207 -        Profile(String name, int profile) {
   7.208 -            this.name = name;
   7.209 -            this.profile = profile;
   7.210 -            this.packages = new HashSet<String>();
   7.211 -            this.proprietaryPkgs = new HashSet<String>();
   7.212 -        }
   7.213 -        public String toString() {
   7.214 -            return name;
   7.215 -        }
   7.216 -    }
   7.217 -
   7.218 -    // for debugging
   7.219 -    public static void main(String[] args) {
   7.220 -        if (args.length == 0) {
   7.221 -            Profile[] profiles = new Profile[getProfileCount()];
   7.222 -            for (Profile p : map.values()) {
   7.223 -                // move the zeroth profile to the last
   7.224 -                int index = p.profile == 0 ? profiles.length-1 : p.profile-1;
   7.225 -                profiles[index] = p;
   7.226 -            }
   7.227 -            for (Profile p : profiles) {
   7.228 -                String profileName = p.name;
   7.229 -                SortedSet<String> set = new TreeSet<String>(p.packages);
   7.230 -                for (String s : set) {
   7.231 -                    // filter out the inner classes that are not annotated with
   7.232 -                    // the profile annotation
   7.233 -                    if (map.get(s) == p) {
   7.234 -                        System.out.format("%-10s  %s%n", profileName, s);
   7.235 -                        profileName = "";
   7.236 -                    }
   7.237 -                }
   7.238 -            }
   7.239 -        }
   7.240 -        for (String pn : args) {
   7.241 -            System.out.format("%s in %s%n", pn, getProfileName(pn));
   7.242 -        }
   7.243 -    }
   7.244 -}
     8.1 --- a/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties	Thu Oct 17 13:50:00 2013 +0200
     8.2 +++ b/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties	Thu Oct 17 13:19:48 2013 -0700
     8.3 @@ -5,46 +5,63 @@
     8.4  main.usage=\
     8.5  Usage: {0} <options> <classes...>\n\
     8.6  where <classes> can be a pathname to a .class file, a directory, a JAR file,\n\
     8.7 -or a fully-qualified classname or wildcard "*".  Possible options include:
     8.8 +or a fully-qualified class name.  Possible options include:
     8.9  
    8.10  error.prefix=Error:
    8.11  warn.prefix=Warning:
    8.12  
    8.13  main.opt.h=\
    8.14 -\  -h -?      --help                    Print this usage message
    8.15 +\  -h -?        -help                 Print this usage message
    8.16  
    8.17  main.opt.version=\
    8.18 -\             --version                 Version information
    8.19 -
    8.20 -main.opt.V=\
    8.21 -\  -V <level> --verbose-level=<level>   Print package-level or class-level dependencies\n\
    8.22 -\                                       Valid levels are: "package" and "class"
    8.23 +\  -version                           Version information
    8.24  
    8.25  main.opt.v=\
    8.26 -\  -v         --verbose                 Print additional information
    8.27 +\  -v           -verbose              Print all class level dependencies\n\
    8.28 +\  -verbose:package                   Print package-level dependencies excluding\n\
    8.29 +\                                     dependencies within the same archive\n\
    8.30 +\  -verbose:class                     Print class-level dependencies excluding\n\
    8.31 +\                                     dependencies within the same archive
    8.32  
    8.33  main.opt.s=\
    8.34 -\  -s         --summary                 Print dependency summary only
    8.35 +\  -s           -summary              Print dependency summary only
    8.36  
    8.37  main.opt.p=\
    8.38 -\  -p <pkg name> --package=<pkg name>   Restrict analysis to classes in this package\n\
    8.39 -\                                       (may be given multiple times)
    8.40 +\  -p <pkgname> -package <pkgname>    Finds dependences in the given package\n\
    8.41 +\                                     (may be given multiple times)
    8.42  
    8.43  main.opt.e=\
    8.44 -\  -e <regex> --regex=<regex>           Restrict analysis to packages matching pattern\n\
    8.45 -\                                       (-p and -e are exclusive)
    8.46 +\  -e <regex>   -regex <regex>        Finds dependences in packages matching pattern\n\
    8.47 +\                                     (-p and -e are exclusive)
    8.48 +
    8.49 +main.opt.include=\
    8.50 +\  -include <regex>                   Restrict analysis to classes matching pattern\n\
    8.51 +\                                     This option filters the list of classes to\n\
    8.52 +\                                     be analyzed.  It can be used together with\n\
    8.53 +\                                     -p and -e which apply pattern to the dependences
    8.54  
    8.55  main.opt.P=\
    8.56 -\  -P         --profile                 Show profile or the file containing a package
    8.57 +\  -P           -profile              Show profile or the file containing a package
    8.58  
    8.59 -main.opt.c=\
    8.60 -\  -c <path>  --classpath=<path>        Specify where to find class files
    8.61 +main.opt.cp=\
    8.62 +\  -cp <path>   -classpath <path>     Specify where to find class files
    8.63  
    8.64  main.opt.R=\
    8.65 -\  -R         --recursive               Recursively traverse all dependencies
    8.66 +\  -R           -recursive            Recursively traverse all dependencies
    8.67  
    8.68 -main.opt.d=\
    8.69 -\  -d <depth> --depth=<depth>           Specify the depth of the transitive dependency analysis
    8.70 +main.opt.apionly=\
    8.71 +\  -apionly                           Restrict analysis to APIs i.e. dependences\n\
    8.72 +\                                     from the signature of public and protected\n\
    8.73 +\                                     members of public classes including field\n\
    8.74 +\                                     type, method parameter types, returned type,\n\
    8.75 +\                                     checked exception types etc
    8.76 +
    8.77 +main.opt.dotoutput=\
    8.78 +\  -dotoutput <dir>                   Destination directory for DOT file output
    8.79 +
    8.80 +main.opt.depth=\
    8.81 +\  -depth=<depth>                     Specify the depth of the transitive\n\
    8.82 +\                                     dependency analysis
    8.83  
    8.84  err.unknown.option=unknown option: {0}
    8.85  err.missing.arg=no value given for {0}
    8.86 @@ -53,6 +70,7 @@
    8.87  err.option.after.class=option must be specified before classes: {0}
    8.88  err.option.unsupported={0} not supported: {1}
    8.89  err.profiles.msg=No profile information
    8.90 +err.dot.output.path=invalid path: {0}
    8.91  warn.invalid.arg=Invalid classname or pathname not exist: {0}
    8.92  warn.split.package=package {0} defined in {1} {2}
    8.93  
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/test/tools/jdeps/APIDeps.java	Thu Oct 17 13:19:48 2013 -0700
     9.3 @@ -0,0 +1,191 @@
     9.4 +/*
     9.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.
    9.11 + *
    9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.15 + * version 2 for more details (a copy is included in the LICENSE file that
    9.16 + * accompanied this code).
    9.17 + *
    9.18 + * You should have received a copy of the GNU General Public License version
    9.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.21 + *
    9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.23 + * or visit www.oracle.com if you need additional information or have any
    9.24 + * questions.
    9.25 + */
    9.26 +
    9.27 +/*
    9.28 + * @test
    9.29 + * @bug 8015912
    9.30 + * @summary find API dependencies
    9.31 + * @build m.Bar m.Foo m.Gee b.B c.C c.I d.D e.E f.F g.G
    9.32 + * @run main APIDeps
    9.33 + */
    9.34 +
    9.35 +import java.io.File;
    9.36 +import java.io.IOException;
    9.37 +import java.io.PrintWriter;
    9.38 +import java.io.StringWriter;
    9.39 +import java.nio.file.Path;
    9.40 +import java.nio.file.Paths;
    9.41 +import java.util.*;
    9.42 +import java.util.regex.*;
    9.43 +
    9.44 +public class APIDeps {
    9.45 +    private static boolean symbolFileExist = initProfiles();
    9.46 +    private static boolean initProfiles() {
    9.47 +        // check if ct.sym exists; if not use the profiles.properties file
    9.48 +        Path home = Paths.get(System.getProperty("java.home"));
    9.49 +        if (home.endsWith("jre")) {
    9.50 +            home = home.getParent();
    9.51 +        }
    9.52 +        Path ctsym = home.resolve("lib").resolve("ct.sym");
    9.53 +        boolean symbolExists = ctsym.toFile().exists();
    9.54 +        if (!symbolExists) {
    9.55 +            Path testSrcProfiles =
    9.56 +                Paths.get(System.getProperty("test.src", "."), "profiles.properties");
    9.57 +            if (!testSrcProfiles.toFile().exists())
    9.58 +                throw new Error(testSrcProfiles + " does not exist");
    9.59 +            System.out.format("%s doesn't exist.%nUse %s to initialize profiles info%n",
    9.60 +                ctsym, testSrcProfiles);
    9.61 +            System.setProperty("jdeps.profiles", testSrcProfiles.toString());
    9.62 +        }
    9.63 +        return symbolExists;
    9.64 +    }
    9.65 +
    9.66 +    public static void main(String... args) throws Exception {
    9.67 +        int errors = 0;
    9.68 +        errors += new APIDeps().run();
    9.69 +        if (errors > 0)
    9.70 +            throw new Exception(errors + " errors found");
    9.71 +    }
    9.72 +
    9.73 +    int run() throws IOException {
    9.74 +        File testDir = new File(System.getProperty("test.classes", "."));
    9.75 +        String testDirBasename = testDir.toPath().getFileName().toString();
    9.76 +        File mDir = new File(testDir, "m");
    9.77 +        // all dependencies
    9.78 +        test(new File(mDir, "Bar.class"),
    9.79 +             new String[] {"java.lang.Object", "java.lang.String",
    9.80 +                           "java.util.Set", "java.util.HashSet",
    9.81 +                           "java.lang.management.ManagementFactory",
    9.82 +                           "java.lang.management.RuntimeMXBean",
    9.83 +                           "b.B", "c.C", "d.D", "f.F", "g.G"},
    9.84 +             new String[] {"compact1", "compact3", testDirBasename},
    9.85 +             new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"});
    9.86 +        test(new File(mDir, "Foo.class"),
    9.87 +             new String[] {"c.I", "e.E", "f.F", "m.Bar"},
    9.88 +             new String[] {testDirBasename},
    9.89 +             new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"});
    9.90 +        test(new File(mDir, "Gee.class"),
    9.91 +             new String[] {"g.G", "sun.misc.Lock"},
    9.92 +             new String[] {testDirBasename, "JDK internal API"},
    9.93 +             new String[] {"-classpath", testDir.getPath(), "-verbose"});
    9.94 +        // parse only APIs
    9.95 +        test(mDir,
    9.96 +             new String[] {"java.lang.Object", "java.lang.String",
    9.97 +                           "java.util.Set",
    9.98 +                           "c.C", "d.D", "c.I", "e.E", "m.Bar"},
    9.99 +             new String[] {"compact1", testDirBasename, mDir.getName()},
   9.100 +             new String[] {"-classpath", testDir.getPath(), "-verbose", "-P", "-apionly"});
   9.101 +        return errors;
   9.102 +    }
   9.103 +
   9.104 +    void test(File file, String[] expect, String[] profiles) {
   9.105 +        test(file, expect, profiles, new String[0]);
   9.106 +    }
   9.107 +
   9.108 +    void test(File file, String[] expect, String[] profiles, String[] options) {
   9.109 +        List<String> args = new ArrayList<>(Arrays.asList(options));
   9.110 +        if (file != null) {
   9.111 +            args.add(file.getPath());
   9.112 +        }
   9.113 +        checkResult("api-dependencies", expect, profiles,
   9.114 +                    jdeps(args.toArray(new String[0])));
   9.115 +    }
   9.116 +
   9.117 +    Map<String,String> jdeps(String... args) {
   9.118 +        StringWriter sw = new StringWriter();
   9.119 +        PrintWriter pw = new PrintWriter(sw);
   9.120 +        System.err.println("jdeps " + Arrays.toString(args));
   9.121 +        int rc = com.sun.tools.jdeps.Main.run(args, pw);
   9.122 +        pw.close();
   9.123 +        String out = sw.toString();
   9.124 +        if (!out.isEmpty())
   9.125 +            System.err.println(out);
   9.126 +        if (rc != 0)
   9.127 +            throw new Error("jdeps failed: rc=" + rc);
   9.128 +        return findDeps(out);
   9.129 +    }
   9.130 +
   9.131 +    // Pattern used to parse lines
   9.132 +    private static Pattern linePattern = Pattern.compile(".*\r?\n");
   9.133 +    private static Pattern pattern = Pattern.compile("\\s+ -> (\\S+) +(.*)");
   9.134 +
   9.135 +    // Use the linePattern to break the given String into lines, applying
   9.136 +    // the pattern to each line to see if we have a match
   9.137 +    private static Map<String,String> findDeps(String out) {
   9.138 +        Map<String,String> result = new HashMap<>();
   9.139 +        Matcher lm = linePattern.matcher(out);  // Line matcher
   9.140 +        Matcher pm = null;                      // Pattern matcher
   9.141 +        int lines = 0;
   9.142 +        while (lm.find()) {
   9.143 +            lines++;
   9.144 +            CharSequence cs = lm.group();       // The current line
   9.145 +            if (pm == null)
   9.146 +                pm = pattern.matcher(cs);
   9.147 +            else
   9.148 +                pm.reset(cs);
   9.149 +            if (pm.find())
   9.150 +                result.put(pm.group(1), pm.group(2).trim());
   9.151 +            if (lm.end() == out.length())
   9.152 +                break;
   9.153 +        }
   9.154 +        return result;
   9.155 +    }
   9.156 +
   9.157 +    void checkResult(String label, String[] expect, Collection<String> found) {
   9.158 +        List<String> list = Arrays.asList(expect);
   9.159 +        if (!isEqual(list, found))
   9.160 +            error("Unexpected " + label + " found: '" + found + "', expected: '" + list + "'");
   9.161 +    }
   9.162 +
   9.163 +    void checkResult(String label, String[] expect, String[] profiles, Map<String,String> result) {
   9.164 +        // check the dependencies
   9.165 +        checkResult(label, expect, result.keySet());
   9.166 +        // check profile information
   9.167 +        Set<String> values = new TreeSet<>();
   9.168 +        String internal = "JDK internal API";
   9.169 +        for (String s: result.values()) {
   9.170 +            if (s.startsWith(internal)){
   9.171 +                values.add(internal);
   9.172 +            } else {
   9.173 +                values.add(s);
   9.174 +            }
   9.175 +        }
   9.176 +        checkResult(label, profiles, values);
   9.177 +    }
   9.178 +
   9.179 +    boolean isEqual(List<String> expected, Collection<String> found) {
   9.180 +        if (expected.size() != found.size())
   9.181 +            return false;
   9.182 +
   9.183 +        List<String> list = new ArrayList<>(found);
   9.184 +        list.removeAll(expected);
   9.185 +        return list.isEmpty();
   9.186 +    }
   9.187 +
   9.188 +    void error(String msg) {
   9.189 +        System.err.println("Error: " + msg);
   9.190 +        errors++;
   9.191 +    }
   9.192 +
   9.193 +    int errors;
   9.194 +}
    10.1 --- a/test/tools/jdeps/Basic.java	Thu Oct 17 13:50:00 2013 +0200
    10.2 +++ b/test/tools/jdeps/Basic.java	Thu Oct 17 13:19:48 2013 -0700
    10.3 @@ -23,7 +23,7 @@
    10.4  
    10.5  /*
    10.6   * @test
    10.7 - * @bug 8003562 8005428
    10.8 + * @bug 8003562 8005428 8015912
    10.9   * @summary Basic tests for jdeps tool
   10.10   * @build Test p.Foo
   10.11   * @run main Basic
   10.12 @@ -79,40 +79,33 @@
   10.13               new String[] {"compact1", "compact1", "compact3"});
   10.14          // test class-level dependency output
   10.15          test(new File(testDir, "Test.class"),
   10.16 -             new String[] {"java.lang.Object", "p.Foo"},
   10.17 -             new String[] {"compact1", "not found"},
   10.18 -             new String[] {"-V", "class"});
   10.19 +             new String[] {"java.lang.Object", "java.lang.String", "p.Foo"},
   10.20 +             new String[] {"compact1", "compact1", "not found"},
   10.21 +             new String[] {"-verbose:class"});
   10.22          // test -p option
   10.23          test(new File(testDir, "Test.class"),
   10.24               new String[] {"p.Foo"},
   10.25               new String[] {"not found"},
   10.26 -             new String[] {"--verbose-level=class", "-p", "p"});
   10.27 +             new String[] {"-verbose:class", "-p", "p"});
   10.28          // test -e option
   10.29          test(new File(testDir, "Test.class"),
   10.30               new String[] {"p.Foo"},
   10.31               new String[] {"not found"},
   10.32 -             new String[] {"-V", "class", "-e", "p\\..*"});
   10.33 +             new String[] {"-verbose:class", "-e", "p\\..*"});
   10.34          test(new File(testDir, "Test.class"),
   10.35               new String[] {"java.lang"},
   10.36               new String[] {"compact1"},
   10.37 -             new String[] {"-V", "package", "-e", "java\\.lang\\..*"});
   10.38 -        // test -classpath and wildcard options
   10.39 +             new String[] {"-verbose:package", "-e", "java\\.lang\\..*"});
   10.40 +        // test -classpath and -include options
   10.41          test(null,
   10.42 -             new String[] {"com.sun.tools.jdeps", "java.lang", "java.util",
   10.43 -                           "java.util.regex", "java.io", "java.nio.file",
   10.44 +             new String[] {"java.lang", "java.util",
   10.45                             "java.lang.management"},
   10.46 -             new String[] {(symbolFileExist? "not found" : "JDK internal API (classes)"),
   10.47 -                           "compact1", "compact1", "compact1",
   10.48 -                           "compact1", "compact1", "compact3"},
   10.49 -             new String[] {"--classpath", testDir.getPath(), "*"});
   10.50 -        /* Temporary disable this test case.  Test.class has a dependency
   10.51 -         * on java.lang.String on certain windows machine (8008479).
   10.52 -         // -v shows intra-dependency
   10.53 -         test(new File(testDir, "Test.class"),
   10.54 -              new String[] {"java.lang.Object", "p.Foo"},
   10.55 -              new String[] {"compact1", testDir.getName()},
   10.56 -              new String[] {"-v", "--classpath", testDir.getPath(), "Test.class"});
   10.57 -        */
   10.58 +             new String[] {"compact1", "compact1", "compact3"},
   10.59 +             new String[] {"-classpath", testDir.getPath(), "-include", "p.+|Test.class"});
   10.60 +        test(new File(testDir, "Test.class"),
   10.61 +             new String[] {"java.lang.Object", "java.lang.String", "p.Foo"},
   10.62 +             new String[] {"compact1", "compact1", testDir.getName()},
   10.63 +             new String[] {"-v", "-classpath", testDir.getPath(), "Test.class"});
   10.64          return errors;
   10.65      }
   10.66  
    11.1 --- a/test/tools/jdeps/Test.java	Thu Oct 17 13:50:00 2013 +0200
    11.2 +++ b/test/tools/jdeps/Test.java	Thu Oct 17 13:19:48 2013 -0700
    11.3 @@ -25,4 +25,7 @@
    11.4      public void test() {
    11.5          p.Foo f = new p.Foo();
    11.6      }
    11.7 +    private String name() {
    11.8 +        return "this test";
    11.9 +    }
   11.10  }
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/test/tools/jdeps/b/B.java	Thu Oct 17 13:19:48 2013 -0700
    12.3 @@ -0,0 +1,32 @@
    12.4 +/*
    12.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.7 + *
    12.8 + * This code is free software; you can redistribute it and/or modify it
    12.9 + * under the terms of the GNU General Public License version 2 only, as
   12.10 + * published by the Free Software Foundation.
   12.11 + *
   12.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   12.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12.15 + * version 2 for more details (a copy is included in the LICENSE file that
   12.16 + * accompanied this code).
   12.17 + *
   12.18 + * You should have received a copy of the GNU General Public License version
   12.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   12.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   12.21 + *
   12.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   12.23 + * or visit www.oracle.com if you need additional information or have any
   12.24 + * questions.
   12.25 + */
   12.26 +
   12.27 +package b;
   12.28 +
   12.29 +import java.lang.annotation.*;
   12.30 +import static java.lang.annotation.ElementType.*;
   12.31 +
   12.32 +@Retention(RetentionPolicy.RUNTIME)
   12.33 +@Target({TYPE, METHOD, FIELD})
   12.34 +public @interface B {
   12.35 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/test/tools/jdeps/c/C.java	Thu Oct 17 13:19:48 2013 -0700
    13.3 @@ -0,0 +1,27 @@
    13.4 +/*
    13.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 + *
    13.8 + * This code is free software; you can redistribute it and/or modify it
    13.9 + * under the terms of the GNU General Public License version 2 only, as
   13.10 + * published by the Free Software Foundation.
   13.11 + *
   13.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   13.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.15 + * version 2 for more details (a copy is included in the LICENSE file that
   13.16 + * accompanied this code).
   13.17 + *
   13.18 + * You should have received a copy of the GNU General Public License version
   13.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   13.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.21 + *
   13.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.23 + * or visit www.oracle.com if you need additional information or have any
   13.24 + * questions.
   13.25 + */
   13.26 +
   13.27 +package c;
   13.28 +
   13.29 +public class C {
   13.30 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/tools/jdeps/c/I.java	Thu Oct 17 13:19:48 2013 -0700
    14.3 @@ -0,0 +1,28 @@
    14.4 +/*
    14.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.7 + *
    14.8 + * This code is free software; you can redistribute it and/or modify it
    14.9 + * under the terms of the GNU General Public License version 2 only, as
   14.10 + * published by the Free Software Foundation.
   14.11 + *
   14.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   14.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14.15 + * version 2 for more details (a copy is included in the LICENSE file that
   14.16 + * accompanied this code).
   14.17 + *
   14.18 + * You should have received a copy of the GNU General Public License version
   14.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   14.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   14.21 + *
   14.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   14.23 + * or visit www.oracle.com if you need additional information or have any
   14.24 + * questions.
   14.25 + */
   14.26 +
   14.27 +package c;
   14.28 +
   14.29 +public interface I {
   14.30 +    void run();
   14.31 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/test/tools/jdeps/d/D.java	Thu Oct 17 13:19:48 2013 -0700
    15.3 @@ -0,0 +1,27 @@
    15.4 +/*
    15.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    15.7 + *
    15.8 + * This code is free software; you can redistribute it and/or modify it
    15.9 + * under the terms of the GNU General Public License version 2 only, as
   15.10 + * published by the Free Software Foundation.
   15.11 + *
   15.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   15.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   15.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   15.15 + * version 2 for more details (a copy is included in the LICENSE file that
   15.16 + * accompanied this code).
   15.17 + *
   15.18 + * You should have received a copy of the GNU General Public License version
   15.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   15.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   15.21 + *
   15.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   15.23 + * or visit www.oracle.com if you need additional information or have any
   15.24 + * questions.
   15.25 + */
   15.26 +
   15.27 +package d;
   15.28 +
   15.29 +public class D {
   15.30 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/test/tools/jdeps/e/E.java	Thu Oct 17 13:19:48 2013 -0700
    16.3 @@ -0,0 +1,28 @@
    16.4 +/*
    16.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.7 + *
    16.8 + * This code is free software; you can redistribute it and/or modify it
    16.9 + * under the terms of the GNU General Public License version 2 only, as
   16.10 + * published by the Free Software Foundation.
   16.11 + *
   16.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   16.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16.15 + * version 2 for more details (a copy is included in the LICENSE file that
   16.16 + * accompanied this code).
   16.17 + *
   16.18 + * You should have received a copy of the GNU General Public License version
   16.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   16.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   16.21 + *
   16.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   16.23 + * or visit www.oracle.com if you need additional information or have any
   16.24 + * questions.
   16.25 + */
   16.26 +
   16.27 +package e;
   16.28 +
   16.29 +// use compact2
   16.30 +public class E extends java.rmi.RemoteException {
   16.31 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/test/tools/jdeps/f/F.java	Thu Oct 17 13:19:48 2013 -0700
    17.3 @@ -0,0 +1,31 @@
    17.4 +/*
    17.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    17.7 + *
    17.8 + * This code is free software; you can redistribute it and/or modify it
    17.9 + * under the terms of the GNU General Public License version 2 only, as
   17.10 + * published by the Free Software Foundation.
   17.11 + *
   17.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   17.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   17.15 + * version 2 for more details (a copy is included in the LICENSE file that
   17.16 + * accompanied this code).
   17.17 + *
   17.18 + * You should have received a copy of the GNU General Public License version
   17.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   17.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   17.21 + *
   17.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   17.23 + * or visit www.oracle.com if you need additional information or have any
   17.24 + * questions.
   17.25 + */
   17.26 +
   17.27 +package f;
   17.28 +
   17.29 +public class F {
   17.30 +    public F() {
   17.31 +        // jdk internal API
   17.32 +        sun.misc.Unsafe.getUnsafe();
   17.33 +    }
   17.34 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/test/tools/jdeps/g/G.java	Thu Oct 17 13:19:48 2013 -0700
    18.3 @@ -0,0 +1,29 @@
    18.4 +/*
    18.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    18.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    18.7 + *
    18.8 + * This code is free software; you can redistribute it and/or modify it
    18.9 + * under the terms of the GNU General Public License version 2 only, as
   18.10 + * published by the Free Software Foundation.
   18.11 + *
   18.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   18.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   18.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   18.15 + * version 2 for more details (a copy is included in the LICENSE file that
   18.16 + * accompanied this code).
   18.17 + *
   18.18 + * You should have received a copy of the GNU General Public License version
   18.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   18.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   18.21 + *
   18.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   18.23 + * or visit www.oracle.com if you need additional information or have any
   18.24 + * questions.
   18.25 + */
   18.26 +
   18.27 +package g;
   18.28 +
   18.29 +public class G {
   18.30 +    // Full JRE
   18.31 +    private static final boolean gui = java.beans.Beans.isGuiAvailable();
   18.32 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/test/tools/jdeps/m/Bar.java	Thu Oct 17 13:19:48 2013 -0700
    19.3 @@ -0,0 +1,50 @@
    19.4 +/*
    19.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    19.7 + *
    19.8 + * This code is free software; you can redistribute it and/or modify it
    19.9 + * under the terms of the GNU General Public License version 2 only, as
   19.10 + * published by the Free Software Foundation.
   19.11 + *
   19.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   19.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   19.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   19.15 + * version 2 for more details (a copy is included in the LICENSE file that
   19.16 + * accompanied this code).
   19.17 + *
   19.18 + * You should have received a copy of the GNU General Public License version
   19.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   19.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   19.21 + *
   19.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   19.23 + * or visit www.oracle.com if you need additional information or have any
   19.24 + * questions.
   19.25 + */
   19.26 +
   19.27 +package m;
   19.28 +
   19.29 +import java.util.*;
   19.30 +
   19.31 +@b.B
   19.32 +public class Bar {
   19.33 +    public final Set<String> set = new HashSet<>();
   19.34 +    protected d.D d;
   19.35 +    private f.F f;
   19.36 +
   19.37 +    public Bar() {
   19.38 +        // compact3
   19.39 +        java.lang.management.ManagementFactory.getRuntimeMXBean();
   19.40 +    }
   19.41 +
   19.42 +    protected c.C c() {
   19.43 +        return new c.C();
   19.44 +    }
   19.45 +
   19.46 +    /* package private */ void setF(f.F o) {
   19.47 +        f = o;
   19.48 +    }
   19.49 +
   19.50 +    private g.G g() {
   19.51 +        return new g.G();
   19.52 +    }
   19.53 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/test/tools/jdeps/m/Foo.java	Thu Oct 17 13:19:48 2013 -0700
    20.3 @@ -0,0 +1,33 @@
    20.4 +/*
    20.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    20.7 + *
    20.8 + * This code is free software; you can redistribute it and/or modify it
    20.9 + * under the terms of the GNU General Public License version 2 only, as
   20.10 + * published by the Free Software Foundation.
   20.11 + *
   20.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   20.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   20.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   20.15 + * version 2 for more details (a copy is included in the LICENSE file that
   20.16 + * accompanied this code).
   20.17 + *
   20.18 + * You should have received a copy of the GNU General Public License version
   20.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   20.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20.21 + *
   20.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   20.23 + * or visit www.oracle.com if you need additional information or have any
   20.24 + * questions.
   20.25 + */
   20.26 +
   20.27 +package m;
   20.28 +
   20.29 +public class Foo extends Bar implements c.I {
   20.30 +   public void foo() throws e.E {
   20.31 +   }
   20.32 +   public void run() {
   20.33 +      setF(new f.F());
   20.34 +   }
   20.35 +}
   20.36 +
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/test/tools/jdeps/m/Gee.java	Thu Oct 17 13:19:48 2013 -0700
    21.3 @@ -0,0 +1,30 @@
    21.4 +/*
    21.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    21.7 + *
    21.8 + * This code is free software; you can redistribute it and/or modify it
    21.9 + * under the terms of the GNU General Public License version 2 only, as
   21.10 + * published by the Free Software Foundation.
   21.11 + *
   21.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   21.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   21.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   21.15 + * version 2 for more details (a copy is included in the LICENSE file that
   21.16 + * accompanied this code).
   21.17 + *
   21.18 + * You should have received a copy of the GNU General Public License version
   21.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   21.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   21.21 + *
   21.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   21.23 + * or visit www.oracle.com if you need additional information or have any
   21.24 + * questions.
   21.25 + */
   21.26 +
   21.27 +package m;
   21.28 +
   21.29 +
   21.30 +class Gee extends g.G {
   21.31 +    public sun.misc.Lock lock;
   21.32 +}
   21.33 +

mercurial