8005428: Update jdeps to read the same profile information as by javac
Reviewed-by: alanb
--- a/langtools/make/netbeans/langtools/nbproject/project.xml Thu Mar 14 08:30:16 2013 +0000
+++ b/langtools/make/netbeans/langtools/nbproject/project.xml Thu Mar 14 10:33:31 2013 -0700
@@ -29,15 +29,13 @@
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
-
-<!DOCTYPE project [
- <!ENTITY standard-ide-actions SYSTEM "standard-ide-actions.ent">
- <!ENTITY standard-context-menu-items SYSTEM "standard-context-menu-items.ent">
-]>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.ant.freeform</type>
<configuration>
<general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
+ <name>langtools</name>
+ </general-data>
+ <general-data xmlns="http://www.netbeans.org/ns/freeform-project/2">
<!-- Do not use Project Properties customizer when editing this file manually. -->
<name>langtools</name>
<properties>
@@ -49,11 +47,6 @@
<location>${root}</location>
</source-folder>
<source-folder>
- <label>Source files</label>
- <type>java</type>
- <location>${root}/src/share/classes</location>
- </source-folder>
- <source-folder>
<label>Test files</label>
<type>tests</type>
<location>${root}/test</location>
@@ -63,9 +56,169 @@
<type>build</type>
<location>${root}/make</location>
</source-folder>
+ <source-folder>
+ <label>Source files</label>
+ <type>java</type>
+ <location>${root}/src/share/classes</location>
+ </source-folder>
+ <build-file>
+ <location>${root}/build/classes</location>
+ </build-file>
</folders>
<ide-actions>
- &standard-ide-actions;
+ <!--
+ Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of Oracle nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+ <!--
+ This file defines the standard actions accepted by langtools projects.
+ It is normally included as an entity into a project's project.xml file.
+
+ For information on these actions, see
+ - NetBeans: Setting Up Projects
+ at http://www.netbeans.org/kb/55/using-netbeans/project_setup.html
+ - NetBeans: Advanced Freeform Project Configuration
+ at http://www.netbeans.org/kb/41/freeform-config.html
+-->
+ <action name="build">
+ <target>build</target>
+ </action>
+ <action name="clean">
+ <target>clean</target>
+ </action>
+ <action name="rebuild">
+ <target>clean</target>
+ <target>build</target>
+ </action>
+ <action name="compile.single">
+ <target>compile-single</target>
+ <property name="srcdir">${root}/src/share/classes</property>
+ <context>
+ <property>includes</property>
+ <folder>${root}/src/share/classes</folder>
+ <pattern>\.java$</pattern>
+ <format>relative-path</format>
+ <arity>
+ <separated-files>,</separated-files>
+ </arity>
+ </context>
+ </action>
+ <action name="run">
+ <target>run</target>
+ </action>
+ <action name="run.single">
+ <target>run-single</target>
+ <context>
+ <property>run.classname</property>
+ <folder>${root}/src/share/classes</folder>
+ <pattern>\.java$</pattern>
+ <format>java-name</format>
+ <arity>
+ <one-file-only/>
+ </arity>
+ </context>
+ </action>
+ <!--
+ Note: NetBeans does not appear to support context menu items
+ on shell scripts :-(
+-->
+ <action name="run.single">
+ <target>jtreg</target>
+ <context>
+ <property>jtreg.tests</property>
+ <folder>${root}/test</folder>
+ <pattern>\.(java|sh)$</pattern>
+ <format>relative-path</format>
+ <arity>
+ <separated-files>,</separated-files>
+ </arity>
+ </context>
+ </action>
+ <action name="test">
+ <target>jtreg</target>
+ </action>
+ <action name="debug">
+ <target>debug</target>
+ </action>
+ <action name="debug.single">
+ <target>debug-single</target>
+ <context>
+ <property>debug.classname</property>
+ <folder>${root}/src/share/classes</folder>
+ <pattern>\.java$</pattern>
+ <format>java-name</format>
+ <arity>
+ <one-file-only/>
+ </arity>
+ </context>
+ </action>
+ <!--
+ Note: NetBeans does not appear to support context menu items
+ on shell scripts :-(
+-->
+ <action name="debug.single">
+ <target>debug-jtreg</target>
+ <context>
+ <property>jtreg.tests</property>
+ <folder>${root}/test</folder>
+ <pattern>\.(java|sh)$</pattern>
+ <format>relative-path</format>
+ <arity>
+ <one-file-only/>
+ </arity>
+ </context>
+ </action>
+ <action name="debug.fix">
+ <target>debug-fix</target>
+ <property name="srcdir">${root}/src/share/classes</property>
+ <context>
+ <property>class</property>
+ <folder>${root}/src/share/classes</folder>
+ <pattern>\.java$</pattern>
+ <format>relative-path-noext</format>
+ <arity>
+ <one-file-only/>
+ </arity>
+ </context>
+ </action>
+ <action name="javadoc">
+ <target>javadoc</target>
+ </action>
+ <action name="select-tool">
+ <target>select-tool</target>
+ </action>
+ <action name="test-select-tool-1">
+ <target>test-select-tool-1</target>
+ </action>
+ <action name="test-select-tool-2">
+ <target>test-select-tool-2</target>
+ </action>
</ide-actions>
<export>
<type>folder</type>
@@ -86,13 +239,68 @@
<label>Build files</label>
<location>${root}/make</location>
</source-folder>
+ <source-folder style="packages">
+ <label>Source files</label>
+ <location>${root}/src/share/classes</location>
+ </source-folder>
<source-file>
<label>README</label>
<location>README</location>
</source-file>
</items>
<context-menu>
- &standard-context-menu-items;
+ <!--
+ Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of Oracle nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+ <!--
+ This file defines the actions that will appear on the project's context
+ menu, in the Projects viewer.
+ It is normally included as an entity into a project's project.xml file.
+
+ For information on these actions, see
+ - NetBeans: Setting Up Projects
+ at http://www.netbeans.org/kb/55/using-netbeans/project_setup.html
+ - NetBeans: Advanced Freeform Project Configuration
+ at http://www.netbeans.org/kb/41/freeform-config.html
+-->
+ <ide-action name="select-tool"/>
+ <separator/>
+ <ide-action name="build"/>
+ <ide-action name="rebuild"/>
+ <ide-action name="clean"/>
+ <ide-action name="javadoc"/>
+ <separator/>
+ <ide-action name="run"/>
+ <ide-action name="debug"/>
+ <separator/>
+ <ide-action name="test"/>
</context-menu>
</view>
<subprojects/>
@@ -101,7 +309,7 @@
<compilation-unit>
<package-root>${root}/src/share/classes</package-root>
<built-to>${root}/build/classes</built-to>
- <source-level>1.5</source-level> <!-- FIXME -->
+ <source-level>1.5</source-level>
</compilation-unit>
</java-data>
</configuration>
--- a/langtools/src/share/classes/com/sun/tools/jdeps/Analyzer.java Thu Mar 14 08:30:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/Analyzer.java Thu Mar 14 10:33:31 2013 -0700
@@ -91,9 +91,11 @@
result.requiredArchives.add(source);
}
// either a profile name or the archive name
- String tname = getProfile(target);
- if (tname.isEmpty()){
- tname = source.toString();
+ String tname = result.getTargetProfile(target);
+ if (tname.isEmpty()) {
+ tname = PlatformClassPath.contains(source)
+ ? "JDK internal API (" + source.getFileName() + ")"
+ : source.toString();
}
if (!result.targetNames.contains(tname)) {
result.targetNames.add(tname);
@@ -110,7 +112,7 @@
* a fully-qualified classname, a package name, a profile or
* archive name depending on the Analyzer's type.
*/
- void visit(String origin, String target);
+ void visit(String origin, String target, String profile);
/**
* Visits the source archive to its destination archive of
* a recorded dependency.
@@ -124,7 +126,7 @@
v.visit(r.archive, a);
}
for (String name : r.targetNames) {
- v.visit(r.archive.getFileName(), name);
+ v.visit(r.archive.getFileName(), name, name);
}
}
}
@@ -138,7 +140,7 @@
for (String target : r.deps.get(origin)) {
// filter intra-dependency unless in verbose mode
if (type == Type.VERBOSE || getArchive(origin) != getArchive(target)) {
- v.visit(origin, target);
+ v.visit(origin, target, r.getTargetProfile(target));
}
}
}
@@ -149,21 +151,16 @@
return map.containsKey(name) ? map.get(name) : NOT_FOUND;
}
- public String getArchiveName(String name) {
- return getArchive(name).getFileName();
- }
-
- public String getProfile(String name) {
- String pn = type == Type.CLASS ? packageOf(name) : name;
- Archive source = map.get(name);
- if (source != null && PlatformClassPath.contains(source)) {
- String profile = PlatformClassPath.getProfileName(pn);
- if (profile.isEmpty()) {
- return "JDK internal API (" + source.getFileName() + ")";
- }
- return profile;
- }
- return "";
+ /**
+ * Returns the file name of the archive for non-JRE class or
+ * internal JRE classes. It returns empty string for SE API.
+ */
+ public String getArchiveName(String target, String profile) {
+ Archive source = getArchive(target);
+ String name = source.getFileName();
+ if (PlatformClassPath.contains(source))
+ return profile.isEmpty() ? "JDK internal API (" + name + ")" : "";
+ return name;
}
private abstract class ArchiveDeps implements Archive.Visitor {
@@ -200,6 +197,8 @@
}
public abstract void visit(Location o, Location t);
+ public abstract String getTargetProfile(String target);
+
}
private class ClassVisitor extends ArchiveDeps {
@@ -212,6 +211,10 @@
public void visit(Location o, Location t) {
add(o.getClassName(), t.getClassName());
}
+ public String getTargetProfile(String target) {
+ int i = target.lastIndexOf('.');
+ return (i > 0) ? Profiles.getProfileName(target.substring(0, i)) : "";
+ }
}
private class PackageVisitor extends ArchiveDeps {
@@ -221,19 +224,15 @@
public void visit(Location o, Location t) {
add(packageOf(o), packageOf(t));
}
-
public void visit(Location l) {
add(packageOf(l));
}
-
private String packageOf(Location loc) {
String pkg = loc.getPackageName();
return pkg.isEmpty() ? "<unnamed>" : pkg;
}
- }
-
- private static String packageOf(String cn) {
- int i = cn.lastIndexOf('.');
- return (i > 0) ? cn.substring(0, i) : "<unnamed>";
+ public String getTargetProfile(String target) {
+ return Profiles.getProfileName(target);
+ }
}
}
--- a/langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java Thu Mar 14 08:30:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java Thu Mar 14 10:33:31 2013 -0700
@@ -59,6 +59,13 @@
}
}
+ /**
+ * Returns a ClassFileReader instance of a given JarFile.
+ */
+ public static ClassFileReader newInstance(Path path, JarFile jf) throws IOException {
+ return new JarFileReader(path, jf);
+ }
+
protected final Path path;
protected final String baseFileName;
private ClassFileReader(Path path) {
@@ -228,8 +235,11 @@
private static class JarFileReader extends ClassFileReader {
final JarFile jarfile;
JarFileReader(Path path) throws IOException {
+ this(path, new JarFile(path.toFile()));
+ }
+ JarFileReader(Path path, JarFile jf) throws IOException {
super(path);
- this.jarfile = new JarFile(path.toFile());
+ this.jarfile = jf;
}
public ClassFile getClassFile(String name) throws IOException {
--- a/langtools/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Thu Mar 14 08:30:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Thu Mar 14 10:33:31 2013 -0700
@@ -139,8 +139,11 @@
}
},
new Option(false, "-P", "--profile") {
- void process(JdepsTask task, String opt, String arg) {
+ void process(JdepsTask task, String opt, String arg) throws BadArgs {
task.options.showProfile = true;
+ if (Profiles.getProfileCount() == 0) {
+ throw task.new BadArgs("err.option.unsupported", opt, getMessage("err.profiles.msg"));
+ }
}
},
new Option(false, "-R", "--recursive") {
@@ -382,9 +385,9 @@
private void printSummary(final PrintWriter out, final Analyzer analyzer) {
Analyzer.Visitor visitor = new Analyzer.Visitor() {
- public void visit(String origin, String profile) {
+ public void visit(String origin, String target, String profile) {
if (options.showProfile) {
- out.format("%-30s -> %s%n", origin, profile);
+ out.format("%-30s -> %s%n", origin, target);
}
}
public void visit(Archive origin, Archive target) {
@@ -399,17 +402,15 @@
private void printDependencies(final PrintWriter out, final Analyzer analyzer) {
Analyzer.Visitor visitor = new Analyzer.Visitor() {
private String pkg = "";
- public void visit(String origin, String target) {
+ public void visit(String origin, String target, String profile) {
if (!origin.equals(pkg)) {
pkg = origin;
- out.format(" %s (%s)%n", origin, analyzer.getArchiveName(origin));
+ out.format(" %s (%s)%n", origin, analyzer.getArchive(origin).getFileName());
}
- Archive source = analyzer.getArchive(target);
- String profile = options.showProfile ? analyzer.getProfile(target) : "";
out.format(" -> %-50s %s%n", target,
- PlatformClassPath.contains(source)
+ (options.showProfile && !profile.isEmpty())
? profile
- : analyzer.getArchiveName(target));
+ : analyzer.getArchiveName(target, profile));
}
public void visit(Archive origin, Archive target) {
out.format("%s -> %s%n", origin, target);
--- a/langtools/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java Thu Mar 14 08:30:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java Thu Mar 14 10:33:31 2013 -0700
@@ -37,34 +37,6 @@
* ClassPath for Java SE and JDK
*/
class PlatformClassPath {
- /*
- * Profiles for Java SE
- *
- * This is a temporary workaround until a common API is defined for langtools
- * to determine which profile a given classname belongs to. The list of
- * packages and profile names are hardcoded in jdk.properties and
- * split packages are not supported.
- */
- static class Profile {
- final String name;
- final Set<String> packages;
-
- Profile(String name) {
- this.name = name;
- this.packages = new HashSet<String>();
- }
- }
-
- private final static String JAVAFX = "javafx";
- private final static Map<String,Profile> map = getProfilePackages();
- static String getProfileName(String packageName) {
- Profile profile = map.get(packageName);
- if (packageName.startsWith(JAVAFX + ".")) {
- profile = map.get(JAVAFX);
- }
- return profile != null ? profile.name : "";
- }
-
private final static List<Archive> javaHomeArchives = init();
static List<Archive> getArchives() {
return javaHomeArchives;
@@ -100,13 +72,6 @@
} catch (IOException e) {
throw new RuntimeException(e);
}
-
- // add a JavaFX profile if there is jfxrt.jar
- for (Archive archive : result) {
- if (archive.getFileName().equals("jfxrt.jar")) {
- map.put(JAVAFX, new Profile("jfxrt.jar"));
- }
- }
return result;
}
@@ -140,30 +105,4 @@
});
return result;
}
-
- private static Map<String,Profile> getProfilePackages() {
- Map<String,Profile> map = new HashMap<String,Profile>();
-
- // read the properties as a ResourceBundle as the build compiles
- // the properties file into Java class. Another alternative is
- // to load it as Properties and fix the build to exclude this file.
- ResourceBundle profileBundle =
- ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdk");
-
- int i=1;
- String key;
- while (profileBundle.containsKey((key = "profile." + i + ".name"))) {
- Profile profile = new Profile(profileBundle.getString(key));
- String n = profileBundle.getString("profile." + i + ".packages");
- String[] pkgs = n.split("\\s+");
- for (String p : pkgs) {
- if (p.isEmpty()) continue;
- assert(map.containsKey(p) == false);
- profile.packages.add(p);
- map.put(p, profile);
- }
- i++;
- }
- return map;
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/Profiles.java Thu Mar 14 10:33:31 2013 -0700
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.jdeps;
+
+import com.sun.tools.classfile.Annotation;
+import com.sun.tools.classfile.Annotation.*;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPool.*;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.RuntimeAnnotations_attribute;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.jar.JarFile;
+
+/**
+ * Build the profile information from ct.sym if exists.
+ */
+class Profiles {
+ private static final Map<String,Profile> map = initProfiles();
+ /**
+ * Returns the name of the profile for the given package name.
+ * It returns an empty string if the given package is not in any profile.
+ */
+ public static String getProfileName(String pn) {
+ Profile profile = map.get(pn);
+ return (profile != null && profile.packages.contains(pn))
+ ? profile.name : "";
+ }
+
+ public static int getProfileCount() {
+ return new HashSet<Profile>(map.values()).size();
+ }
+
+ private static Map<String,Profile> initProfiles() {
+ List<Profile> profiles = new ArrayList<Profile>();
+ try {
+ String profilesProps = System.getProperty("jdeps.profiles");
+ if (profilesProps != null) {
+ // for testing for JDK development build where ct.sym doesn't exist
+ initProfilesFromProperties(profiles, profilesProps);
+ } else {
+ Path home = Paths.get(System.getProperty("java.home"));
+ if (home.endsWith("jre")) {
+ home = home.getParent();
+ }
+ Path ctsym = home.resolve("lib").resolve("ct.sym");
+ if (ctsym.toFile().exists()) {
+ // add a default Full JRE
+ profiles.add(0, new Profile("Full JRE", 0));
+ // parse ct.sym and load information about profiles
+ try (JarFile jf = new JarFile(ctsym.toFile())) {
+ ClassFileReader reader = ClassFileReader.newInstance(ctsym, jf);
+ for (ClassFile cf : reader.getClassFiles()) {
+ findProfile(profiles, cf);
+ }
+ }
+
+ // merge the last Profile with the "Full JRE"
+ if (profiles.size() > 1) {
+ Profile fullJRE = profiles.get(0);
+ Profile p = profiles.remove(profiles.size() - 1);
+ for (String pn : fullJRE.packages) {
+ // The last profile contains the packages determined from ct.sym.
+ // Move classes annotated profile==0 or no attribute that are
+ // added in the fullJRE profile to either supported or proprietary
+ // packages appropriately
+ if (p.proprietaryPkgs.contains(pn)) {
+ p.proprietaryPkgs.add(pn);
+ } else {
+ p.packages.add(pn);
+ }
+ }
+ fullJRE.packages.clear();
+ fullJRE.proprietaryPkgs.clear();
+ fullJRE.packages.addAll(p.packages);
+ fullJRE.proprietaryPkgs.addAll(p.proprietaryPkgs);
+ }
+ }
+ }
+ } catch (IOException | ConstantPoolException e) {
+ throw new Error(e);
+ }
+ HashMap<String,Profile> map = new HashMap<String,Profile>();
+ for (Profile profile : profiles) {
+ // Inner classes are not annotated with the profile annotation
+ // packages may be in one profile but also appear in the Full JRE
+ // Full JRE is always the first element in profiles list and
+ // so the map will contain the appropriate Profile
+ for (String pn : profile.packages) {
+ map.put(pn, profile);
+ }
+ for (String pn : profile.proprietaryPkgs) {
+ map.put(pn, profile);
+ }
+ }
+ return map;
+ }
+
+ private static final String PROFILE_ANNOTATION = "Ljdk/Profile+Annotation;";
+ private static final String PROPRIETARY_ANNOTATION = "Lsun/Proprietary+Annotation;";
+ private static Profile findProfile(List<Profile> profiles, ClassFile cf)
+ throws ConstantPoolException
+ {
+ RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute)
+ cf.attributes.get(Attribute.RuntimeInvisibleAnnotations);
+ int index = 0;
+ boolean proprietary = false;
+ if (attr != null) {
+ for (int i = 0; i < attr.annotations.length; i++) {
+ Annotation ann = attr.annotations[i];
+ String annType = cf.constant_pool.getUTF8Value(ann.type_index);
+ if (PROFILE_ANNOTATION.equals(annType)) {
+ for (int j = 0; j < ann.num_element_value_pairs; j++) {
+ Annotation.element_value_pair pair = ann.element_value_pairs[j];
+ Primitive_element_value ev = (Primitive_element_value)pair.value;
+ CONSTANT_Integer_info info = (CONSTANT_Integer_info)
+ cf.constant_pool.get(ev.const_value_index);
+ index = info.value;
+ break;
+ }
+ } else if (PROPRIETARY_ANNOTATION.equals(annType)) {
+ proprietary = true;
+ }
+ }
+ if (index >= profiles.size()) {
+ Profile p = null;
+ for (int i = profiles.size(); i <= index; i++) {
+ p = new Profile(i);
+ profiles.add(p);
+ }
+ }
+ }
+
+ Profile p = profiles.get(index);
+ String name = cf.getName();
+ int i = name.lastIndexOf('/');
+ name = (i > 0) ? name.substring(0, i).replace('/','.') : "";
+ if (proprietary) {
+ p.proprietaryPkgs.add(name);
+ } else {
+ p.packages.add(name);
+ }
+ return p;
+ }
+
+ private static void initProfilesFromProperties(List<Profile> profiles, String path)
+ throws IOException
+ {
+ Properties props = new Properties();
+ try (FileReader reader = new FileReader(path)) {
+ props.load(reader);
+ }
+ int i=1;
+ String key;
+ while (props.containsKey((key = "profile." + i + ".name"))) {
+ Profile profile = new Profile(props.getProperty(key), i);
+ profiles.add(profile);
+ String n = props.getProperty("profile." + i + ".packages");
+ String[] pkgs = n.split("\\s+");
+ for (String p : pkgs) {
+ if (p.isEmpty()) continue;
+ profile.packages.add(p);
+ }
+ i++;
+ }
+ }
+
+ private static class Profile {
+ final String name;
+ final int profile;
+ final Set<String> packages;
+ final Set<String> proprietaryPkgs;
+ Profile(int profile) {
+ this("compact" + profile, profile);
+ }
+ Profile(String name, int profile) {
+ this.name = name;
+ this.profile = profile;
+ this.packages = new HashSet<String>();
+ this.proprietaryPkgs = new HashSet<String>();
+ }
+ public String toString() {
+ return name;
+ }
+ }
+
+ // for debugging
+ public static void main(String[] args) {
+ if (args.length == 0) {
+ Profile[] profiles = new Profile[getProfileCount()];
+ for (Profile p : map.values()) {
+ // move the zeroth profile to the last
+ int index = p.profile == 0 ? profiles.length-1 : p.profile-1;
+ profiles[index] = p;
+ }
+ for (Profile p : profiles) {
+ String profileName = p.name;
+ SortedSet<String> set = new TreeSet<String>(p.packages);
+ for (String s : set) {
+ // filter out the inner classes that are not annotated with
+ // the profile annotation
+ if (map.get(s) == p) {
+ System.out.format("%-10s %s%n", profileName, s);
+ profileName = "";
+ }
+ }
+ }
+ }
+ for (String pn : args) {
+ System.out.format("%s in %s%n", pn, getProfileName(pn));
+ }
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Thu Mar 14 08:30:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Thu Mar 14 10:33:31 2013 -0700
@@ -51,6 +51,8 @@
err.internal.error=internal error: {0} {1} {2}
err.invalid.arg.for.option=invalid argument for option: {0}
err.option.after.class=option must be specified before classes: {0}
+err.option.unsupported={0} not supported: {1}
+err.profiles.msg=No profile information
warn.invalid.arg=Invalid classname or pathname not exist: {0}
warn.split.package=package {0} defined in {1} {2}
--- a/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdk.properties Thu Mar 14 08:30:16 2013 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,262 +0,0 @@
-# This properties file does not need localization.
-
-profile.1.name = compact1
-profile.1.packages = \
- java.io \
- java.lang \
- java.lang.annotation \
- java.lang.invoke \
- java.lang.ref \
- java.lang.reflect \
- java.math \
- java.net \
- java.nio \
- java.nio.channels \
- java.nio.channels.spi \
- java.nio.charset \
- java.nio.charset.spi \
- java.nio.file \
- java.nio.file.attribute \
- java.nio.file.spi \
- java.security \
- java.security.cert \
- java.security.interfaces \
- java.security.spec \
- java.text \
- java.text.spi \
- java.util \
- java.util.concurrent \
- java.util.concurrent.atomic \
- java.util.concurrent.locks \
- java.util.jar \
- java.util.logging \
- java.util.regex \
- java.util.spi \
- java.util.zip \
- javax.crypto \
- javax.crypto.interfaces \
- javax.crypto.spec \
- javax.security.auth \
- javax.security.auth.callback \
- javax.security.auth.login \
- javax.security.auth.spi \
- javax.security.auth.x500 \
- javax.net \
- javax.net.ssl \
- javax.security.cert \
- \
- com.sun.net.ssl \
- com.sun.nio.file \
- com.sun.nio.sctp \
- com.sun.security.auth \
- com.sun.security.auth.login
-
-profile.2.name = compact2
-profile.2.packages = \
- java.sql \
- javax.sql \
- javax.xml \
- javax.xml.datatype \
- javax.xml.namespace \
- javax.xml.parsers \
- javax.xml.stream \
- javax.xml.stream.events \
- javax.xml.stream.util \
- javax.xml.transform \
- javax.xml.transform.dom \
- javax.xml.transform.sax \
- javax.xml.transform.stax \
- javax.xml.transform.stream \
- javax.xml.validation \
- javax.xml.xpath \
- org.w3c.dom \
- org.w3c.dom.bootstrap \
- org.w3c.dom.events \
- org.w3c.dom.ls \
- org.xml.sax \
- org.xml.sax.ext \
- org.xml.sax.helpers \
- java.rmi \
- java.rmi.activation \
- java.rmi.dgc \
- java.rmi.registry \
- java.rmi.server \
- javax.rmi.ssl \
- javax.transaction \
- javax.transaction.xa \
- \
- com.sun.net.httpserver \
- com.sun.net.httpserver.spi
-
-profile.3.name = compact3
-profile.3.packages = \
- java.lang.instrument \
- java.lang.management \
- java.security.acl \
- java.util.prefs \
- javax.management \
- javax.management.loading \
- javax.management.modelmbean \
- javax.management.monitor \
- javax.management.openmbean \
- javax.management.relation \
- javax.management.remote \
- javax.management.remote.rmi \
- javax.management.timer \
- javax.naming \
- javax.naming.directory \
- javax.naming.event \
- javax.naming.ldap \
- javax.naming.spi \
- javax.sql.rowset \
- javax.sql.rowset.serial \
- javax.sql.rowset.spi \
- javax.security.auth.kerberos \
- javax.security.sasl \
- javax.script \
- javax.smartcardio \
- javax.xml.crypto \
- javax.xml.crypto.dom \
- javax.xml.crypto.dsig \
- javax.xml.crypto.dsig.dom \
- javax.xml.crypto.dsig.keyinfo \
- javax.xml.crypto.dsig.spec \
- javax.annotation.processing \
- javax.lang.model \
- javax.lang.model.element \
- javax.lang.model.type \
- javax.lang.model.util \
- javax.tools \
- javax.tools.annotation \
- org.ietf.jgss \
- \
- com.sun.management \
- com.sun.security.auth.callback \
- com.sun.security.auth.module \
- com.sun.security.jgss
-
-profile.4.name = Full JRE
-profile.4.packages = \
- java.applet \
- java.awt \
- java.awt.color \
- java.awt.datatransfer \
- java.awt.dnd \
- java.awt.dnd.peer \
- java.awt.event \
- java.awt.font \
- java.awt.geom \
- java.awt.im \
- java.awt.im.spi \
- java.awt.image \
- java.awt.image.renderable \
- java.awt.peer \
- java.awt.print \
- java.beans \
- java.beans.beancontext \
- javax.accessibility \
- javax.imageio \
- javax.imageio.event \
- javax.imageio.metadata \
- javax.imageio.plugins.bmp \
- javax.imageio.plugins.jpeg \
- javax.imageio.spi \
- javax.imageio.stream \
- javax.print \
- javax.print.attribute \
- javax.print.attribute.standard \
- javax.print.event \
- javax.sound.midi \
- javax.sound.midi.spi \
- javax.sound.sampled \
- javax.sound.sampled.spi \
- javax.swing \
- javax.swing.border \
- javax.swing.colorchooser \
- javax.swing.event \
- javax.swing.filechooser \
- javax.swing.plaf \
- javax.swing.plaf.basic \
- javax.swing.plaf.metal \
- javax.swing.plaf.multi \
- javax.swing.plaf.nimbus \
- javax.swing.plaf.synth \
- javax.swing.table \
- javax.swing.text \
- javax.swing.text.html \
- javax.swing.text.html.parser \
- javax.swing.text.rtf \
- javax.swing.tree \
- javax.swing.undo \
- javax.activation \
- javax.jws \
- javax.jws.soap \
- javax.rmi \
- javax.rmi.CORBA \
- javax.xml.bind \
- javax.xml.bind.annotation \
- javax.xml.bind.annotation.adapters \
- javax.xml.bind.attachment \
- javax.xml.bind.helpers \
- javax.xml.bind.util \
- javax.xml.soap \
- javax.xml.ws \
- javax.xml.ws.handler \
- javax.xml.ws.handler.soap \
- javax.xml.ws.http \
- javax.xml.ws.soap \
- javax.xml.ws.spi \
- javax.xml.ws.spi.http \
- javax.xml.ws.wsaddressing \
- javax.annotation \
- org.omg.CORBA \
- org.omg.CORBA.DynAnyPackage \
- org.omg.CORBA.ORBPackage \
- org.omg.CORBA.TypeCodePackage \
- org.omg.CORBA.portable \
- org.omg.CORBA_2_3 \
- org.omg.CORBA_2_3.portable \
- org.omg.CosNaming \
- org.omg.CosNaming.NamingContextExtPackage \
- org.omg.CosNaming.NamingContextPackage \
- org.omg.Dynamic \
- org.omg.DynamicAny \
- org.omg.DynamicAny.DynAnyFactoryPackage \
- org.omg.DynamicAny.DynAnyPackage \
- org.omg.IOP \
- org.omg.IOP.CodecFactoryPackage \
- org.omg.IOP.CodecPackage \
- org.omg.Messaging \
- org.omg.PortableInterceptor \
- org.omg.PortableInterceptor.ORBInitInfoPackage \
- org.omg.PortableServer \
- org.omg.PortableServer.CurrentPackage \
- org.omg.PortableServer.POAManagerPackage \
- org.omg.PortableServer.POAPackage \
- org.omg.PortableServer.ServantLocatorPackage \
- org.omg.PortableServer.portable \
- org.omg.SendingContext \
- org.omg.stub.java.rmi \
- org.omg.stub.javax.management.remote.rmi
-
-# Remaining JDK supported API
-profile.5.name = JDK tools
-profile.5.packages = \
- com.sun.jdi \
- com.sun.jdi.connect \
- com.sun.jdi.connect.spi \
- com.sun.jdi.event \
- com.sun.jdi.request \
- com.sun.javadoc \
- com.sun.tools.doclets \
- com.sun.tools.doctree \
- com.sun.source.tree \
- com.sun.source.util \
- com.sun.tools.attach \
- com.sun.tools.attach.spi \
- com.sun.tools.jconsole \
- com.sun.tools.javac \
- com.sun.tools.javah \
- com.sun.tools.javap \
- com.sun.tools.javadoc \
- com.sun.servicetag
--- a/langtools/test/tools/jdeps/Basic.java Thu Mar 14 08:30:16 2013 +0000
+++ b/langtools/test/tools/jdeps/Basic.java Thu Mar 14 10:33:31 2013 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8003562
+ * @bug 8003562 8005428
* @summary Basic tests for jdeps tool
* @build Test p.Foo
* @run main Basic
@@ -33,13 +33,35 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.*;
import java.util.regex.*;
public class Basic {
+ private static boolean symbolFileExist = initProfiles();
+ private static boolean initProfiles() {
+ // check if ct.sym exists; if not use the profiles.properties file
+ Path home = Paths.get(System.getProperty("java.home"));
+ if (home.endsWith("jre")) {
+ home = home.getParent();
+ }
+ Path ctsym = home.resolve("lib").resolve("ct.sym");
+ boolean symbolExists = ctsym.toFile().exists();
+ if (!symbolExists) {
+ Path testSrcProfiles =
+ Paths.get(System.getProperty("test.src", "."), "profiles.properties");
+ if (!testSrcProfiles.toFile().exists())
+ throw new Error(testSrcProfiles + " does not exist");
+ System.out.format("%s doesn't exist.%nUse %s to initialize profiles info%n",
+ ctsym, testSrcProfiles);
+ System.setProperty("jdeps.profiles", testSrcProfiles.toString());
+ }
+ return symbolExists;
+ }
+
public static void main(String... args) throws Exception {
int errors = 0;
-
errors += new Basic().run();
if (errors > 0)
throw new Exception(errors + " errors found");
@@ -49,54 +71,70 @@
File testDir = new File(System.getProperty("test.classes", "."));
// test a .class file
test(new File(testDir, "Test.class"),
- new String[] {"java.lang", "p"});
+ new String[] {"java.lang", "p"},
+ new String[] {"compact1", "not found"});
// test a directory
test(new File(testDir, "p"),
- new String[] {"java.lang", "java.util"});
+ new String[] {"java.lang", "java.util", "java.lang.management"},
+ new String[] {"compact1", "compact1", "compact3"});
// test class-level dependency output
test(new File(testDir, "Test.class"),
new String[] {"java.lang.Object", "p.Foo"},
+ new String[] {"compact1", "not found"},
new String[] {"-V", "class"});
// test -p option
test(new File(testDir, "Test.class"),
new String[] {"p.Foo"},
+ new String[] {"not found"},
new String[] {"--verbose-level=class", "-p", "p"});
// test -e option
test(new File(testDir, "Test.class"),
new String[] {"p.Foo"},
+ new String[] {"not found"},
new String[] {"-V", "class", "-e", "p\\..*"});
test(new File(testDir, "Test.class"),
new String[] {"java.lang"},
+ new String[] {"compact1"},
new String[] {"-V", "package", "-e", "java\\.lang\\..*"});
// test -classpath and wildcard options
test(null,
new String[] {"com.sun.tools.jdeps", "java.lang", "java.util",
- "java.util.regex", "java.io"},
+ "java.util.regex", "java.io", "java.nio.file",
+ "java.lang.management"},
+ new String[] {(symbolFileExist? "not found" : "JDK internal API (classes)"),
+ "compact1", "compact1", "compact1",
+ "compact1", "compact1", "compact3"},
new String[] {"--classpath", testDir.getPath(), "*"});
- // -v shows intra-dependency
- test(new File(testDir, "Test.class"),
- new String[] {"java.lang.Object", "p.Foo"},
- new String[] {"-v", "--classpath", testDir.getPath(), "Test.class"});
+ /* Temporary disable this test case. Test.class has a dependency
+ * on java.lang.String on certain windows machine (8008479).
+ // -v shows intra-dependency
+ test(new File(testDir, "Test.class"),
+ new String[] {"java.lang.Object", "p.Foo"},
+ new String[] {"compact1", testDir.getName()},
+ new String[] {"-v", "--classpath", testDir.getPath(), "Test.class"});
+ */
return errors;
}
- void test(File file, String[] expect) {
- test(file, expect, new String[0]);
+ void test(File file, String[] expect, String[] profiles) {
+ test(file, expect, profiles, new String[0]);
}
- void test(File file, String[] expect, String[] options) {
- String[] args;
+ void test(File file, String[] expect, String[] profiles, String[] options) {
+ List<String> args = new ArrayList<>(Arrays.asList(options));
if (file != null) {
- args = Arrays.copyOf(options, options.length+1);
- args[options.length] = file.getPath();
- } else {
- args = options;
+ args.add(file.getPath());
}
- String[] deps = jdeps(args);
- checkEqual("dependencies", expect, deps);
+ List<String> argsWithDashP = new ArrayList<>();
+ argsWithDashP.add("-P");
+ argsWithDashP.addAll(args);
+ // test without -P
+ checkResult("dependencies", expect, jdeps(args.toArray(new String[0])).keySet());
+ // test with -P
+ checkResult("profiles", expect, profiles, jdeps(argsWithDashP.toArray(new String[0])));
}
- String[] jdeps(String... args) {
+ Map<String,String> jdeps(String... args) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
System.err.println("jdeps " + Arrays.toString(args));
@@ -112,12 +150,12 @@
// Pattern used to parse lines
private static Pattern linePattern = Pattern.compile(".*\r?\n");
- private static Pattern pattern = Pattern.compile("\\s+ -> (\\S+) +.*");
+ private static Pattern pattern = Pattern.compile("\\s+ -> (\\S+) +(.*)");
// Use the linePattern to break the given String into lines, applying
// the pattern to each line to see if we have a match
- private static String[] findDeps(String out) {
- List<String> result = new ArrayList<>();
+ private static Map<String,String> findDeps(String out) {
+ Map<String,String> result = new HashMap<>();
Matcher lm = linePattern.matcher(out); // Line matcher
Matcher pm = null; // Pattern matcher
int lines = 0;
@@ -129,19 +167,41 @@
else
pm.reset(cs);
if (pm.find())
- result.add(pm.group(1));
+ result.put(pm.group(1), pm.group(2).trim());
if (lm.end() == out.length())
break;
}
- return result.toArray(new String[0]);
+ return result;
+ }
+
+ void checkResult(String label, String[] expect, Collection<String> found) {
+ List<String> list = Arrays.asList(expect);
+ if (!isEqual(list, found))
+ error("Unexpected " + label + " found: '" + found + "', expected: '" + list + "'");
}
- void checkEqual(String label, String[] expect, String[] found) {
- Set<String> s1 = new HashSet<>(Arrays.asList(expect));
- Set<String> s2 = new HashSet<>(Arrays.asList(found));
+ void checkResult(String label, String[] expect, String[] profiles, Map<String,String> result) {
+ if (expect.length != profiles.length)
+ error("Invalid expected names and profiles");
- if (!s1.equals(s2))
- error("Unexpected " + label + " found: '" + s2 + "', expected: '" + s1 + "'");
+ // check the dependencies
+ checkResult(label, expect, result.keySet());
+ // check profile information
+ checkResult(label, profiles, result.values());
+ for (int i=0; i < expect.length; i++) {
+ String profile = result.get(expect[i]);
+ if (!profile.equals(profiles[i]))
+ error("Unexpected profile: '" + profile + "', expected: '" + profiles[i] + "'");
+ }
+ }
+
+ boolean isEqual(List<String> expected, Collection<String> found) {
+ if (expected.size() != found.size())
+ return false;
+
+ List<String> list = new ArrayList<>(found);
+ list.removeAll(expected);
+ return list.isEmpty();
}
void error(String msg) {
--- a/langtools/test/tools/jdeps/p/Foo.java Thu Mar 14 08:30:16 2013 +0000
+++ b/langtools/test/tools/jdeps/p/Foo.java Thu Mar 14 10:33:31 2013 -0700
@@ -31,5 +31,7 @@
}
public Foo() {
+ // compact3
+ java.lang.management.ManagementFactory.getRuntimeMXBean();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/jdeps/profiles.properties Thu Mar 14 10:33:31 2013 -0700
@@ -0,0 +1,263 @@
+# This properties file is used for testing a JDK development build.
+# No need to keep this properties file up to date as long as it covers
+# the APIs used by the jdeps regression test.
+profile.1.name = compact1
+profile.1.packages = \
+ java.io \
+ java.lang \
+ java.lang.annotation \
+ java.lang.invoke \
+ java.lang.ref \
+ java.lang.reflect \
+ java.math \
+ java.net \
+ java.nio \
+ java.nio.channels \
+ java.nio.channels.spi \
+ java.nio.charset \
+ java.nio.charset.spi \
+ java.nio.file \
+ java.nio.file.attribute \
+ java.nio.file.spi \
+ java.security \
+ java.security.cert \
+ java.security.interfaces \
+ java.security.spec \
+ java.text \
+ java.text.spi \
+ java.util \
+ java.util.concurrent \
+ java.util.concurrent.atomic \
+ java.util.concurrent.locks \
+ java.util.jar \
+ java.util.logging \
+ java.util.regex \
+ java.util.spi \
+ java.util.zip \
+ javax.crypto \
+ javax.crypto.interfaces \
+ javax.crypto.spec \
+ javax.security.auth \
+ javax.security.auth.callback \
+ javax.security.auth.login \
+ javax.security.auth.spi \
+ javax.security.auth.x500 \
+ javax.net \
+ javax.net.ssl \
+ javax.security.cert \
+ \
+ com.sun.net.ssl \
+ com.sun.nio.file \
+ com.sun.nio.sctp \
+ com.sun.security.auth \
+ com.sun.security.auth.login
+
+profile.2.name = compact2
+profile.2.packages = \
+ java.sql \
+ javax.sql \
+ javax.xml \
+ javax.xml.datatype \
+ javax.xml.namespace \
+ javax.xml.parsers \
+ javax.xml.stream \
+ javax.xml.stream.events \
+ javax.xml.stream.util \
+ javax.xml.transform \
+ javax.xml.transform.dom \
+ javax.xml.transform.sax \
+ javax.xml.transform.stax \
+ javax.xml.transform.stream \
+ javax.xml.validation \
+ javax.xml.xpath \
+ org.w3c.dom \
+ org.w3c.dom.bootstrap \
+ org.w3c.dom.events \
+ org.w3c.dom.ls \
+ org.xml.sax \
+ org.xml.sax.ext \
+ org.xml.sax.helpers \
+ java.rmi \
+ java.rmi.activation \
+ java.rmi.dgc \
+ java.rmi.registry \
+ java.rmi.server \
+ javax.rmi.ssl \
+ javax.transaction \
+ javax.transaction.xa \
+ \
+ com.sun.net.httpserver \
+ com.sun.net.httpserver.spi
+
+profile.3.name = compact3
+profile.3.packages = \
+ java.lang.instrument \
+ java.lang.management \
+ java.security.acl \
+ java.util.prefs \
+ javax.management \
+ javax.management.loading \
+ javax.management.modelmbean \
+ javax.management.monitor \
+ javax.management.openmbean \
+ javax.management.relation \
+ javax.management.remote \
+ javax.management.remote.rmi \
+ javax.management.timer \
+ javax.naming \
+ javax.naming.directory \
+ javax.naming.event \
+ javax.naming.ldap \
+ javax.naming.spi \
+ javax.sql.rowset \
+ javax.sql.rowset.serial \
+ javax.sql.rowset.spi \
+ javax.security.auth.kerberos \
+ javax.security.sasl \
+ javax.script \
+ javax.smartcardio \
+ javax.xml.crypto \
+ javax.xml.crypto.dom \
+ javax.xml.crypto.dsig \
+ javax.xml.crypto.dsig.dom \
+ javax.xml.crypto.dsig.keyinfo \
+ javax.xml.crypto.dsig.spec \
+ javax.annotation.processing \
+ javax.lang.model \
+ javax.lang.model.element \
+ javax.lang.model.type \
+ javax.lang.model.util \
+ javax.tools \
+ javax.tools.annotation \
+ org.ietf.jgss \
+ \
+ com.sun.management \
+ com.sun.security.auth.callback \
+ com.sun.security.auth.module \
+ com.sun.security.jgss
+
+profile.4.name = Full JRE
+profile.4.packages = \
+ java.applet \
+ java.awt \
+ java.awt.color \
+ java.awt.datatransfer \
+ java.awt.dnd \
+ java.awt.dnd.peer \
+ java.awt.event \
+ java.awt.font \
+ java.awt.geom \
+ java.awt.im \
+ java.awt.im.spi \
+ java.awt.image \
+ java.awt.image.renderable \
+ java.awt.peer \
+ java.awt.print \
+ java.beans \
+ java.beans.beancontext \
+ javax.accessibility \
+ javax.imageio \
+ javax.imageio.event \
+ javax.imageio.metadata \
+ javax.imageio.plugins.bmp \
+ javax.imageio.plugins.jpeg \
+ javax.imageio.spi \
+ javax.imageio.stream \
+ javax.print \
+ javax.print.attribute \
+ javax.print.attribute.standard \
+ javax.print.event \
+ javax.sound.midi \
+ javax.sound.midi.spi \
+ javax.sound.sampled \
+ javax.sound.sampled.spi \
+ javax.swing \
+ javax.swing.border \
+ javax.swing.colorchooser \
+ javax.swing.event \
+ javax.swing.filechooser \
+ javax.swing.plaf \
+ javax.swing.plaf.basic \
+ javax.swing.plaf.metal \
+ javax.swing.plaf.multi \
+ javax.swing.plaf.nimbus \
+ javax.swing.plaf.synth \
+ javax.swing.table \
+ javax.swing.text \
+ javax.swing.text.html \
+ javax.swing.text.html.parser \
+ javax.swing.text.rtf \
+ javax.swing.tree \
+ javax.swing.undo \
+ javax.activation \
+ javax.jws \
+ javax.jws.soap \
+ javax.rmi \
+ javax.rmi.CORBA \
+ javax.xml.bind \
+ javax.xml.bind.annotation \
+ javax.xml.bind.annotation.adapters \
+ javax.xml.bind.attachment \
+ javax.xml.bind.helpers \
+ javax.xml.bind.util \
+ javax.xml.soap \
+ javax.xml.ws \
+ javax.xml.ws.handler \
+ javax.xml.ws.handler.soap \
+ javax.xml.ws.http \
+ javax.xml.ws.soap \
+ javax.xml.ws.spi \
+ javax.xml.ws.spi.http \
+ javax.xml.ws.wsaddressing \
+ javax.annotation \
+ org.omg.CORBA \
+ org.omg.CORBA.DynAnyPackage \
+ org.omg.CORBA.ORBPackage \
+ org.omg.CORBA.TypeCodePackage \
+ org.omg.CORBA.portable \
+ org.omg.CORBA_2_3 \
+ org.omg.CORBA_2_3.portable \
+ org.omg.CosNaming \
+ org.omg.CosNaming.NamingContextExtPackage \
+ org.omg.CosNaming.NamingContextPackage \
+ org.omg.Dynamic \
+ org.omg.DynamicAny \
+ org.omg.DynamicAny.DynAnyFactoryPackage \
+ org.omg.DynamicAny.DynAnyPackage \
+ org.omg.IOP \
+ org.omg.IOP.CodecFactoryPackage \
+ org.omg.IOP.CodecPackage \
+ org.omg.Messaging \
+ org.omg.PortableInterceptor \
+ org.omg.PortableInterceptor.ORBInitInfoPackage \
+ org.omg.PortableServer \
+ org.omg.PortableServer.CurrentPackage \
+ org.omg.PortableServer.POAManagerPackage \
+ org.omg.PortableServer.POAPackage \
+ org.omg.PortableServer.ServantLocatorPackage \
+ org.omg.PortableServer.portable \
+ org.omg.SendingContext \
+ org.omg.stub.java.rmi \
+ org.omg.stub.javax.management.remote.rmi
+
+# Remaining JDK supported API
+profile.5.name = JDK tools
+profile.5.packages = \
+ com.sun.jdi \
+ com.sun.jdi.connect \
+ com.sun.jdi.connect.spi \
+ com.sun.jdi.event \
+ com.sun.jdi.request \
+ com.sun.javadoc \
+ com.sun.tools.doclets \
+ com.sun.tools.doctree \
+ com.sun.source.tree \
+ com.sun.source.util \
+ com.sun.tools.attach \
+ com.sun.tools.attach.spi \
+ com.sun.tools.jconsole \
+ com.sun.tools.javac \
+ com.sun.tools.javah \
+ com.sun.tools.javap \
+ com.sun.tools.javadoc \
+ com.sun.servicetag