Fri, 18 Jul 2014 10:43:41 -0700
8050804: (jdeps) Recommend supported API to replace use of JDK internal API
Reviewed-by: dfuchs
1.1 --- a/src/share/classes/com/sun/tools/jdeps/Analyzer.java Thu Jul 17 15:23:08 2014 -0700 1.2 +++ b/src/share/classes/com/sun/tools/jdeps/Analyzer.java Fri Jul 18 10:43:41 2014 -0700 1.3 @@ -114,6 +114,11 @@ 1.4 return false; 1.5 } 1.6 1.7 + public Set<String> dependences(Archive source) { 1.8 + ArchiveDeps result = results.get(source); 1.9 + return result.targetDependences(); 1.10 + } 1.11 + 1.12 public interface Visitor { 1.13 /** 1.14 * Visits a recorded dependency from origin to target which can be 1.15 @@ -179,6 +184,14 @@ 1.16 return deps; 1.17 } 1.18 1.19 + Set<String> targetDependences() { 1.20 + Set<String> targets = new HashSet<>(); 1.21 + for (Dep d : deps) { 1.22 + targets.add(d.target()); 1.23 + } 1.24 + return targets; 1.25 + } 1.26 + 1.27 Set<Archive> requires() { 1.28 return requires; 1.29 }
2.1 --- a/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Thu Jul 17 15:23:08 2014 -0700 2.2 +++ b/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Fri Jul 18 10:43:41 2014 -0700 2.3 @@ -236,6 +236,11 @@ 2.4 task.options.showLabel = true; 2.5 } 2.6 }, 2.7 + new HiddenOption(false, "-q", "-quiet") { 2.8 + void process(JdepsTask task, String opt, String arg) { 2.9 + task.options.nowarning = true; 2.10 + } 2.11 + }, 2.12 new HiddenOption(true, "-depth") { 2.13 void process(JdepsTask task, String opt, String arg) throws BadArgs { 2.14 try { 2.15 @@ -249,7 +254,7 @@ 2.16 2.17 private static final String PROGNAME = "jdeps"; 2.18 private final Options options = new Options(); 2.19 - private final List<String> classes = new ArrayList<String>(); 2.20 + private final List<String> classes = new ArrayList<>(); 2.21 2.22 private PrintWriter log; 2.23 void setLog(PrintWriter out) { 2.24 @@ -320,7 +325,9 @@ 2.25 2.26 Analyzer analyzer = new Analyzer(options.verbose, new Analyzer.Filter() { 2.27 @Override 2.28 - public boolean accepts(Location origin, Archive originArchive, Location target, Archive targetArchive) { 2.29 + public boolean accepts(Location origin, Archive originArchive, 2.30 + Location target, Archive targetArchive) 2.31 + { 2.32 if (options.findJDKInternals) { 2.33 // accepts target that is JDK class but not exported 2.34 return isJDKArchive(targetArchive) && 2.35 @@ -344,6 +351,10 @@ 2.36 } else { 2.37 printRawOutput(log, analyzer); 2.38 } 2.39 + 2.40 + if (options.findJDKInternals && !options.nowarning) { 2.41 + showReplacements(analyzer); 2.42 + } 2.43 return true; 2.44 } 2.45 2.46 @@ -693,6 +704,7 @@ 2.47 boolean apiOnly; 2.48 boolean showLabel; 2.49 boolean findJDKInternals; 2.50 + boolean nowarning; 2.51 // default is to show package-level dependencies 2.52 // and filter references from same package 2.53 Analyzer.Type verbose = PACKAGE; 2.54 @@ -709,6 +721,7 @@ 2.55 private static class ResourceBundleHelper { 2.56 static final ResourceBundle versionRB; 2.57 static final ResourceBundle bundle; 2.58 + static final ResourceBundle jdkinternals; 2.59 2.60 static { 2.61 Locale locale = Locale.getDefault(); 2.62 @@ -722,6 +735,11 @@ 2.63 } catch (MissingResourceException e) { 2.64 throw new InternalError("version.resource.missing"); 2.65 } 2.66 + try { 2.67 + jdkinternals = ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdkinternals"); 2.68 + } catch (MissingResourceException e) { 2.69 + throw new InternalError("Cannot find jdkinternals resource bundle"); 2.70 + } 2.71 } 2.72 } 2.73 2.74 @@ -935,4 +953,50 @@ 2.75 } 2.76 return Profile.getProfile(pn); 2.77 } 2.78 + 2.79 + /** 2.80 + * Returns the recommended replacement API for the given classname; 2.81 + * or return null if replacement API is not known. 2.82 + */ 2.83 + private String replacementFor(String cn) { 2.84 + String name = cn; 2.85 + String value = null; 2.86 + while (value == null && name != null) { 2.87 + try { 2.88 + value = ResourceBundleHelper.jdkinternals.getString(name); 2.89 + } catch (MissingResourceException e) { 2.90 + // go up one subpackage level 2.91 + int i = name.lastIndexOf('.'); 2.92 + name = i > 0 ? name.substring(0, i) : null; 2.93 + } 2.94 + } 2.95 + return value; 2.96 + }; 2.97 + 2.98 + private void showReplacements(Analyzer analyzer) { 2.99 + Map<String,String> jdkinternals = new TreeMap<>(); 2.100 + boolean useInternals = false; 2.101 + for (Archive source : sourceLocations) { 2.102 + useInternals = useInternals || analyzer.hasDependences(source); 2.103 + for (String cn : analyzer.dependences(source)) { 2.104 + String repl = replacementFor(cn); 2.105 + if (repl != null && !jdkinternals.containsKey(cn)) { 2.106 + jdkinternals.put(cn, repl); 2.107 + } 2.108 + } 2.109 + } 2.110 + if (useInternals) { 2.111 + log.println(); 2.112 + warning("warn.replace.useJDKInternals", getMessage("jdeps.wiki.url")); 2.113 + } 2.114 + if (!jdkinternals.isEmpty()) { 2.115 + log.println(); 2.116 + log.format("%-40s %s%n", "JDK Internal API", "Suggested Replacement"); 2.117 + log.format("%-40s %s%n", "----------------", "---------------------"); 2.118 + for (Map.Entry<String,String> e : jdkinternals.entrySet()) { 2.119 + log.format("%-40s %s%n", e.getKey(), e.getValue()); 2.120 + } 2.121 + } 2.122 + 2.123 + } 2.124 }
3.1 --- a/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Thu Jul 17 15:23:08 2014 -0700 3.2 +++ b/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Fri Jul 18 10:43:41 2014 -0700 3.3 @@ -93,5 +93,12 @@ 3.4 err.invalid.path=invalid path: {0} 3.5 warn.invalid.arg=Invalid classname or pathname not exist: {0} 3.6 warn.split.package=package {0} defined in {1} {2} 3.7 +warn.replace.useJDKInternals=\ 3.8 +JDK internal APIs are unsupported and private to JDK implementation that are\n\ 3.9 +subject to be removed or changed incompatibly and could break your application.\n\ 3.10 +Please modify your code to eliminate dependency on any JDK internal APIs.\n\ 3.11 +For the most recent update on JDK internal API replacements, please check:\n\ 3.12 +{0} 3.13 3.14 artifact.not.found=not found 3.15 +jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/share/classes/com/sun/tools/jdeps/resources/jdkinternals.properties Fri Jul 18 10:43:41 2014 -0700 4.3 @@ -0,0 +1,22 @@ 4.4 +// No translation needed 4.5 +com.sun.crypto.provider.SunJCE=Use java.security.Security.getProvider(provider-name) @since 1.3 4.6 +com.sun.image.codec=Use javax.imageio @since 1.4 4.7 +com.sun.org.apache.xml.internal.security=Use java.xml.crypto @since 1.6 4.8 +com.sun.org.apache.xml.internal.security.utils.Base64=Use java.util.Base64 @since 1.8 4.9 +com.sun.net.ssl=Use javax.net.ssl @since 1.4 4.10 +com.sun.net.ssl.internal.ssl.Provider=Use java.security.Security.getProvider(provider-name) @since 1.3 4.11 +com.sun.rowset=Use javax.sql.rowset.RowSetProvider @since 1.7 4.12 +com.sun.tools.javac.tree=Use com.sun.source @since 1.6 4.13 +com.sun.tools.javac=Use javax.tools and javax.lang.model @since 1.6 4.14 +sun.awt.image.codec=Use javax.imageio @since 1.4 4.15 +sun.misc.BASE64Encoder=Use java.util.Base64 @since 1.8 4.16 +sun.misc.BASE64Decoder=Use java.util.Base64 @since 1.8 4.17 +sun.misc.Cleaner=Use java.lang.ref.PhantomReference @since 1.2 4.18 +sun.misc.Service=Use java.util.ServiceLoader @since 1.6 4.19 +sun.security.action=Use java.security.PrivilegedAction @since 1.1 4.20 +sun.security.krb5=Use com.sun.security.jgss 4.21 +sun.security.provider.PolicyFile=Use java.security.Policy.getInstance("JavaPolicy", new URIParameter(uri)) @since 1.6 4.22 +sun.security.provider.Sun=Use java.security.Security.getProvider(provider-name) @since 1.3 4.23 +sun.security.util.SecurityConstants=Use appropriate java.security.Permission subclass @since 1.1 4.24 +sun.security.x509.X500Name=Use javax.security.auth.x500.X500Principal @since 1.4 4.25 +sun.tools.jar=Use java.util.jar or jar tool @since 1.2
5.1 --- a/test/tools/jdeps/APIDeps.java Thu Jul 17 15:23:08 2014 -0700 5.2 +++ b/test/tools/jdeps/APIDeps.java Fri Jul 18 10:43:41 2014 -0700 5.3 @@ -23,7 +23,7 @@ 5.4 5.5 /* 5.6 * @test 5.7 - * @bug 8015912 8029216 8048063 5.8 + * @bug 8015912 8029216 8048063 8050804 5.9 * @summary Test -apionly and -jdkinternals options 5.10 * @build m.Bar m.Foo m.Gee b.B c.C c.I d.D e.E f.F g.G 5.11 * @run main APIDeps