8050804: (jdeps) Recommend supported API to replace use of JDK internal API
Reviewed-by: dfuchs
This commit is contained in:
parent
541591d644
commit
acacb0481e
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user