8050804: (jdeps) Recommend supported API to replace use of JDK internal API

Fri, 18 Jul 2014 10:43:41 -0700

author
mchung
date
Fri, 18 Jul 2014 10:43:41 -0700
changeset 2539
a51b7fd0543b
parent 2538
1e39ae45d8ac
child 2540
c7947fd930eb

8050804: (jdeps) Recommend supported API to replace use of JDK internal API
Reviewed-by: dfuchs

src/share/classes/com/sun/tools/jdeps/Analyzer.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/resources/jdeps.properties file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/jdeps/resources/jdkinternals.properties file | annotate | diff | comparison | revisions
test/tools/jdeps/APIDeps.java file | annotate | diff | comparison | revisions
     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

mercurial