--- old/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java 2018-11-14 16:47:51.000000000 -0800 +++ new/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java 2018-11-14 16:47:50.000000000 -0800 @@ -357,6 +357,11 @@ task.command = task.listModuleDeps(CommandOption.PRINT_MODULE_DEPS); } }, + new Option(false, "--ignore-missing-deps") { + void process(JdepsTask task, String opt, String arg) { + task.options.ignoreMissingDeps = true; + } + }, // ---- Target filtering options ---- new Option(true, "-p", "-package", "--package") { @@ -401,6 +406,11 @@ } } }, + new Option(false, "--missing-deps") { + void process(JdepsTask task, String opt, String arg) { + task.options.findMissingDeps = true; + } + }, // ---- Source filtering options ---- new Option(true, "-include") { @@ -611,6 +621,11 @@ } private ListModuleDeps listModuleDeps(CommandOption option) throws BadArgs { + // no need to record the dependences on the same archive or same package + options.filterSameArchive = true; + options.filterSamePackage = true; + // do transitive dependence analysis + options.depth = 0; switch (option) { case LIST_DEPS: return new ListModuleDeps(option, true, false); @@ -677,16 +692,16 @@ @Override boolean checkOptions() { - if (options.findJDKInternals) { + if (options.findJDKInternals || options.findMissingDeps) { // cannot set any filter, -verbose and -summary option if (options.showSummary || options.verbose != null) { reportError("err.invalid.options", "-summary or -verbose", - "-jdkinternals"); + options.findJDKInternals ? "-jdkinternals" : "--missing-deps"); return false; } if (options.hasFilter()) { reportError("err.invalid.options", "--package, --regex, --require", - "-jdkinternals"); + options.findJDKInternals ? "-jdkinternals" : "--missing-deps"); return false; } } @@ -715,7 +730,7 @@ if (options.showSummary) return Type.SUMMARY; - if (options.findJDKInternals) + if (options.findJDKInternals || options.findMissingDeps) return Type.CLASS; // default to package-level verbose @@ -925,12 +940,7 @@ if (!ok && !options.nowarning) { reportError("err.missing.dependences"); - builder.visitMissingDeps( - (origin, originArchive, target, targetArchive) -> { - if (builder.notFound(targetArchive)) - log.format(" %-50s -> %-50s %s%n", - origin, target, targetArchive.getName()); - }); + builder.visitMissingDeps(new SimpleDepVisitor()); } return ok; } @@ -993,13 +1003,15 @@ @Override boolean checkOptions() { if (options.showSummary || options.verbose != null) { - reportError("err.invalid.options", "-summary or -verbose", - option); + reportError("err.invalid.options", "-summary or -verbose", option); return false; } if (options.findJDKInternals) { - reportError("err.invalid.options", "-jdkinternals", - option); + reportError("err.invalid.options", "-jdkinternals", option); + return false; + } + if (options.findMissingDeps) { + reportError("err.invalid.options", "--missing-deps", option); return false; } @@ -1015,16 +1027,22 @@ @Override boolean run(JdepsConfiguration config) throws IOException { - return new ModuleExportsAnalyzer(config, - dependencyFilter(config), - jdkinternals, - reduced, - log, - separator).run(); + ModuleExportsAnalyzer analyzer = new ModuleExportsAnalyzer(config, + dependencyFilter(config), + jdkinternals, + reduced, + log, + separator); + boolean ok = analyzer.run(options.depth, options.ignoreMissingDeps); + if (!ok) { + reportError("err.cant.list.module.deps"); + log.println(); + analyzer.visitMissingDeps(new SimpleDepVisitor()); + } + return ok; } } - class GenDotFile extends AnalyzeDeps { final Path dotOutputDir; GenDotFile(Path dotOutputDir) { @@ -1053,6 +1071,18 @@ } } + class SimpleDepVisitor implements Analyzer.Visitor { + private Archive source; + @Override + public void visitDependence(String origin, Archive originArchive, String target, Archive targetArchive) { + if (source != originArchive) { + source = originArchive; + log.format("%s%n", originArchive); + } + log.format(" %-50s -> %-50s %s%n", origin, target, targetArchive.getName()); + } + } + /** * Returns a filter used during dependency analysis */ @@ -1066,6 +1096,7 @@ // target filters builder.filter(options.filterSamePackage, options.filterSameArchive); builder.findJDKInternals(options.findJDKInternals); + builder.findMissingDeps(options.findMissingDeps); // --require if (!options.requires.isEmpty()) { @@ -1158,11 +1189,8 @@ private String version(String key) { // key=version: mm.nn.oo[-milestone] // key=full: mm.mm.oo[-milestone]-build - if (ResourceBundleHelper.versionRB == null) { - return System.getProperty("java.version"); - } try { - return ResourceBundleHelper.versionRB.getString(key); + return ResourceBundleHelper.getVersion(key); } catch (MissingResourceException e) { return getMessage("version.unknown", System.getProperty("java.version")); } @@ -1170,7 +1198,7 @@ static String getMessage(String key, Object... args) { try { - return MessageFormat.format(ResourceBundleHelper.bundle.getString(key), args); + return MessageFormat.format(ResourceBundleHelper.getMessage(key), args); } catch (MissingResourceException e) { throw new InternalError("Missing message: " + key); } @@ -1186,6 +1214,8 @@ boolean apiOnly; boolean showLabel; boolean findJDKInternals; + boolean findMissingDeps; + boolean ignoreMissingDeps; boolean nowarning = false; Analyzer.Type verbose; // default filter references from same package @@ -1225,6 +1255,7 @@ } private static class ResourceBundleHelper { + static final String LS = System.lineSeparator(); static final ResourceBundle versionRB; static final ResourceBundle bundle; static final ResourceBundle jdkinternals; @@ -1247,6 +1278,21 @@ throw new InternalError("Cannot find jdkinternals resource bundle"); } } + + static String getMessage(String key) { + return bundle.getString(key).replace("\n", LS); + } + + static String getVersion(String key) { + if (ResourceBundleHelper.versionRB == null) { + return System.getProperty("java.version"); + } + return versionRB.getString(key).replace("\n", LS); + } + + static String getSuggestedReplacement(String key) { + return ResourceBundleHelper.jdkinternals.getString(key).replace("\n", LS); + } } /** @@ -1258,7 +1304,7 @@ String value = null; while (value == null && name != null) { try { - value = ResourceBundleHelper.jdkinternals.getString(name); + value = ResourceBundleHelper.getSuggestedReplacement(name); } catch (MissingResourceException e) { // go up one subpackage level int i = name.lastIndexOf('.');