234 new HiddenOption(false, "-showlabel") { |
234 new HiddenOption(false, "-showlabel") { |
235 void process(JdepsTask task, String opt, String arg) { |
235 void process(JdepsTask task, String opt, String arg) { |
236 task.options.showLabel = true; |
236 task.options.showLabel = true; |
237 } |
237 } |
238 }, |
238 }, |
|
239 new HiddenOption(false, "-q", "-quiet") { |
|
240 void process(JdepsTask task, String opt, String arg) { |
|
241 task.options.nowarning = true; |
|
242 } |
|
243 }, |
239 new HiddenOption(true, "-depth") { |
244 new HiddenOption(true, "-depth") { |
240 void process(JdepsTask task, String opt, String arg) throws BadArgs { |
245 void process(JdepsTask task, String opt, String arg) throws BadArgs { |
241 try { |
246 try { |
242 task.options.depth = Integer.parseInt(arg); |
247 task.options.depth = Integer.parseInt(arg); |
243 } catch (NumberFormatException e) { |
248 } catch (NumberFormatException e) { |
247 }, |
252 }, |
248 }; |
253 }; |
249 |
254 |
250 private static final String PROGNAME = "jdeps"; |
255 private static final String PROGNAME = "jdeps"; |
251 private final Options options = new Options(); |
256 private final Options options = new Options(); |
252 private final List<String> classes = new ArrayList<String>(); |
257 private final List<String> classes = new ArrayList<>(); |
253 |
258 |
254 private PrintWriter log; |
259 private PrintWriter log; |
255 void setLog(PrintWriter out) { |
260 void setLog(PrintWriter out) { |
256 log = out; |
261 log = out; |
257 } |
262 } |
318 // parse classfiles and find all dependencies |
323 // parse classfiles and find all dependencies |
319 findDependencies(); |
324 findDependencies(); |
320 |
325 |
321 Analyzer analyzer = new Analyzer(options.verbose, new Analyzer.Filter() { |
326 Analyzer analyzer = new Analyzer(options.verbose, new Analyzer.Filter() { |
322 @Override |
327 @Override |
323 public boolean accepts(Location origin, Archive originArchive, Location target, Archive targetArchive) { |
328 public boolean accepts(Location origin, Archive originArchive, |
|
329 Location target, Archive targetArchive) |
|
330 { |
324 if (options.findJDKInternals) { |
331 if (options.findJDKInternals) { |
325 // accepts target that is JDK class but not exported |
332 // accepts target that is JDK class but not exported |
326 return isJDKArchive(targetArchive) && |
333 return isJDKArchive(targetArchive) && |
327 !((JDKArchive) targetArchive).isExported(target.getClassName()); |
334 !((JDKArchive) targetArchive).isExported(target.getClassName()); |
328 } else if (options.filterSameArchive) { |
335 } else if (options.filterSameArchive) { |
341 Path dir = Paths.get(options.dotOutputDir); |
348 Path dir = Paths.get(options.dotOutputDir); |
342 Files.createDirectories(dir); |
349 Files.createDirectories(dir); |
343 generateDotFiles(dir, analyzer); |
350 generateDotFiles(dir, analyzer); |
344 } else { |
351 } else { |
345 printRawOutput(log, analyzer); |
352 printRawOutput(log, analyzer); |
|
353 } |
|
354 |
|
355 if (options.findJDKInternals && !options.nowarning) { |
|
356 showReplacements(analyzer); |
346 } |
357 } |
347 return true; |
358 return true; |
348 } |
359 } |
349 |
360 |
350 private void generateSummaryDotFile(Path dir, Analyzer analyzer) throws IOException { |
361 private void generateSummaryDotFile(Path dir, Analyzer analyzer) throws IOException { |
691 boolean showProfile; |
702 boolean showProfile; |
692 boolean showSummary; |
703 boolean showSummary; |
693 boolean apiOnly; |
704 boolean apiOnly; |
694 boolean showLabel; |
705 boolean showLabel; |
695 boolean findJDKInternals; |
706 boolean findJDKInternals; |
|
707 boolean nowarning; |
696 // default is to show package-level dependencies |
708 // default is to show package-level dependencies |
697 // and filter references from same package |
709 // and filter references from same package |
698 Analyzer.Type verbose = PACKAGE; |
710 Analyzer.Type verbose = PACKAGE; |
699 boolean filterSamePackage = true; |
711 boolean filterSamePackage = true; |
700 boolean filterSameArchive = false; |
712 boolean filterSameArchive = false; |
707 Pattern includePattern; // apply to classes |
719 Pattern includePattern; // apply to classes |
708 } |
720 } |
709 private static class ResourceBundleHelper { |
721 private static class ResourceBundleHelper { |
710 static final ResourceBundle versionRB; |
722 static final ResourceBundle versionRB; |
711 static final ResourceBundle bundle; |
723 static final ResourceBundle bundle; |
|
724 static final ResourceBundle jdkinternals; |
712 |
725 |
713 static { |
726 static { |
714 Locale locale = Locale.getDefault(); |
727 Locale locale = Locale.getDefault(); |
715 try { |
728 try { |
716 bundle = ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdeps", locale); |
729 bundle = ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdeps", locale); |
719 } |
732 } |
720 try { |
733 try { |
721 versionRB = ResourceBundle.getBundle("com.sun.tools.jdeps.resources.version"); |
734 versionRB = ResourceBundle.getBundle("com.sun.tools.jdeps.resources.version"); |
722 } catch (MissingResourceException e) { |
735 } catch (MissingResourceException e) { |
723 throw new InternalError("version.resource.missing"); |
736 throw new InternalError("version.resource.missing"); |
|
737 } |
|
738 try { |
|
739 jdkinternals = ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdkinternals"); |
|
740 } catch (MissingResourceException e) { |
|
741 throw new InternalError("Cannot find jdkinternals resource bundle"); |
724 } |
742 } |
725 } |
743 } |
726 } |
744 } |
727 |
745 |
728 private List<Archive> getClassPathArchives(String paths) throws IOException { |
746 private List<Archive> getClassPathArchives(String paths) throws IOException { |
933 int i = name.lastIndexOf('.'); |
951 int i = name.lastIndexOf('.'); |
934 pn = i > 0 ? name.substring(0, i) : ""; |
952 pn = i > 0 ? name.substring(0, i) : ""; |
935 } |
953 } |
936 return Profile.getProfile(pn); |
954 return Profile.getProfile(pn); |
937 } |
955 } |
|
956 |
|
957 /** |
|
958 * Returns the recommended replacement API for the given classname; |
|
959 * or return null if replacement API is not known. |
|
960 */ |
|
961 private String replacementFor(String cn) { |
|
962 String name = cn; |
|
963 String value = null; |
|
964 while (value == null && name != null) { |
|
965 try { |
|
966 value = ResourceBundleHelper.jdkinternals.getString(name); |
|
967 } catch (MissingResourceException e) { |
|
968 // go up one subpackage level |
|
969 int i = name.lastIndexOf('.'); |
|
970 name = i > 0 ? name.substring(0, i) : null; |
|
971 } |
|
972 } |
|
973 return value; |
|
974 }; |
|
975 |
|
976 private void showReplacements(Analyzer analyzer) { |
|
977 Map<String,String> jdkinternals = new TreeMap<>(); |
|
978 boolean useInternals = false; |
|
979 for (Archive source : sourceLocations) { |
|
980 useInternals = useInternals || analyzer.hasDependences(source); |
|
981 for (String cn : analyzer.dependences(source)) { |
|
982 String repl = replacementFor(cn); |
|
983 if (repl != null && !jdkinternals.containsKey(cn)) { |
|
984 jdkinternals.put(cn, repl); |
|
985 } |
|
986 } |
|
987 } |
|
988 if (useInternals) { |
|
989 log.println(); |
|
990 warning("warn.replace.useJDKInternals", getMessage("jdeps.wiki.url")); |
|
991 } |
|
992 if (!jdkinternals.isEmpty()) { |
|
993 log.println(); |
|
994 log.format("%-40s %s%n", "JDK Internal API", "Suggested Replacement"); |
|
995 log.format("%-40s %s%n", "----------------", "---------------------"); |
|
996 for (Map.Entry<String,String> e : jdkinternals.entrySet()) { |
|
997 log.format("%-40s %s%n", e.getKey(), e.getValue()); |
|
998 } |
|
999 } |
|
1000 |
|
1001 } |
938 } |
1002 } |