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

Reviewed-by: dfuchs
This commit is contained in:
Mandy Chung 2014-07-17 10:17:58 -07:00
parent 541591d644
commit acacb0481e
5 changed files with 106 additions and 4 deletions

View File

@ -24,8 +24,6 @@
*/
package com.sun.tools.jdeps;
import com.sun.tools.classfile.Dependency.Location;
import com.sun.tools.jdeps.PlatformClassPath.JDKArchive;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
@ -33,6 +31,10 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import com.sun.tools.classfile.Dependency.Location;
import com.sun.tools.jdeps.PlatformClassPath.JDKArchive;
/**
* Dependency Analyzer.
@ -110,6 +112,13 @@ public class Analyzer {
return false;
}
public Set<String> dependences(Archive source) {
ArchiveDeps result = results.get(source);
return result.dependencies().stream()
.map(Dep::target)
.collect(Collectors.toSet());
}
public interface Visitor {
/**
* Visits a recorded dependency from origin to target which can be

View File

@ -236,6 +236,11 @@ class JdepsTask {
task.options.showLabel = true;
}
},
new HiddenOption(false, "-q", "-quiet") {
void process(JdepsTask task, String opt, String arg) {
task.options.nowarning = true;
}
},
new HiddenOption(true, "-depth") {
void process(JdepsTask task, String opt, String arg) throws BadArgs {
try {
@ -320,7 +325,9 @@ class JdepsTask {
Analyzer analyzer = new Analyzer(options.verbose, new Analyzer.Filter() {
@Override
public boolean accepts(Location origin, Archive originArchive, Location target, Archive targetArchive) {
public boolean accepts(Location origin, Archive originArchive,
Location target, Archive targetArchive)
{
if (options.findJDKInternals) {
// accepts target that is JDK class but not exported
return isJDKArchive(targetArchive) &&
@ -344,6 +351,10 @@ class JdepsTask {
} else {
printRawOutput(log, analyzer);
}
if (options.findJDKInternals && !options.nowarning) {
showReplacements(analyzer);
}
return true;
}
@ -693,6 +704,7 @@ class JdepsTask {
boolean apiOnly;
boolean showLabel;
boolean findJDKInternals;
boolean nowarning;
// default is to show package-level dependencies
// and filter references from same package
Analyzer.Type verbose = PACKAGE;
@ -709,6 +721,7 @@ class JdepsTask {
private static class ResourceBundleHelper {
static final ResourceBundle versionRB;
static final ResourceBundle bundle;
static final ResourceBundle jdkinternals;
static {
Locale locale = Locale.getDefault();
@ -722,6 +735,11 @@ class JdepsTask {
} catch (MissingResourceException e) {
throw new InternalError("version.resource.missing");
}
try {
jdkinternals = ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdkinternals");
} catch (MissingResourceException e) {
throw new InternalError("Cannot find jdkinternals resource bundle");
}
}
}
@ -928,4 +946,50 @@ class JdepsTask {
}
return Profile.getProfile(pn);
}
/**
* Returns the recommended replacement API for the given classname;
* or return null if replacement API is not known.
*/
private String replacementFor(String cn) {
String name = cn;
String value = null;
while (value == null && name != null) {
try {
value = ResourceBundleHelper.jdkinternals.getString(name);
} catch (MissingResourceException e) {
// go up one subpackage level
int i = name.lastIndexOf('.');
name = i > 0 ? name.substring(0, i) : null;
}
}
return value;
};
private void showReplacements(Analyzer analyzer) {
Map<String,String> jdkinternals = new TreeMap<>();
boolean useInternals = false;
for (Archive source : sourceLocations) {
useInternals = useInternals || analyzer.hasDependences(source);
for (String cn : analyzer.dependences(source)) {
String repl = replacementFor(cn);
if (repl != null) {
jdkinternals.putIfAbsent(cn, repl);
}
}
}
if (useInternals) {
log.println();
warning("warn.replace.useJDKInternals", getMessage("jdeps.wiki.url"));
}
if (!jdkinternals.isEmpty()) {
log.println();
log.format("%-40s %s%n", "JDK Internal API", "Suggested Replacement");
log.format("%-40s %s%n", "----------------", "---------------------");
for (Map.Entry<String,String> e : jdkinternals.entrySet()) {
log.format("%-40s %s%n", e.getKey(), e.getValue());
}
}
}
}

View File

@ -93,5 +93,12 @@ err.profiles.msg=No profile information
err.invalid.path=invalid path: {0}
warn.invalid.arg=Invalid classname or pathname not exist: {0}
warn.split.package=package {0} defined in {1} {2}
warn.replace.useJDKInternals=\
JDK internal APIs are unsupported and private to JDK implementation that are\n\
subject to be removed or changed incompatibly and could break your application.\n\
Please modify your code to eliminate dependency on any JDK internal APIs.\n\
For the most recent update on JDK internal API replacements, please check:\n\
{0}
artifact.not.found=not found
jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool

View File

@ -0,0 +1,22 @@
// No translation needed
com.sun.crypto.provider.SunJCE=Use java.security.Security.getProvider(provider-name) @since 1.3
com.sun.image.codec=Use javax.imageio @since 1.4
com.sun.org.apache.xml.internal.security=Use java.xml.crypto @since 1.6
com.sun.org.apache.xml.internal.security.utils.Base64=Use java.util.Base64 @since 1.8
com.sun.net.ssl=Use javax.net.ssl @since 1.4
com.sun.net.ssl.internal.ssl.Provider=Use java.security.Security.getProvider(provider-name) @since 1.3
com.sun.rowset=Use javax.sql.rowset.RowSetProvider @since 1.7
com.sun.tools.javac.tree=Use com.sun.source @since 1.6
com.sun.tools.javac=Use javax.tools and javax.lang.model @since 1.6
sun.awt.image.codec=Use javax.imageio @since 1.4
sun.misc.BASE64Encoder=Use java.util.Base64 @since 1.8
sun.misc.BASE64Decoder=Use java.util.Base64 @since 1.8
sun.misc.Cleaner=Use java.lang.ref.PhantomReference @since 1.2
sun.misc.Service=Use java.util.ServiceLoader @since 1.6
sun.security.action=Use java.security.PrivilegedAction @since 1.1
sun.security.krb5=Use com.sun.security.jgss
sun.security.provider.PolicyFile=Use java.security.Policy.getInstance("JavaPolicy", new URIParameter(uri)) @since 1.6
sun.security.provider.Sun=Use java.security.Security.getProvider(provider-name) @since 1.3
sun.security.util.SecurityConstants=Use appropriate java.security.Permission subclass @since 1.1
sun.security.x509.X500Name=Use javax.security.auth.x500.X500Principal @since 1.4
sun.tools.jar=Use java.util.jar or jar tool @since 1.2

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8015912 8029216 8048063
* @bug 8015912 8029216 8048063 8050804
* @summary Test -apionly and -jdkinternals options
* @build m.Bar m.Foo m.Gee b.B c.C c.I d.D e.E f.F g.G
* @run main APIDeps