This commit is contained in:
Phil Race 2017-06-29 13:07:19 -07:00
commit 296990a1e8
431 changed files with 13618 additions and 8189 deletions

View File

@ -430,3 +430,5 @@ df64bd4757d0d130d62a22b8143ba31d3a16ac18 jdk-10+10
a5506b425f1bf91530d8417b57360e5d89328c0c jdk-9+173
42f18c931bd4fae5c206ccf6d8e591e4c4e69d31 jdk-9+174
5f504872a75b71f2fb19299f0d1e3395cf32eaa0 jdk-10+12
e6c4f6ef717d104dba880e2dae538690c993b46f jdk-9+175
4540d6376f3ef22305cca546f85f9b2ce9a210c4 jdk-10+13

View File

@ -1 +1,2 @@
project=jdk10
bugids=dup

View File

@ -49,7 +49,4 @@ TOOL_ADD_PACKAGES_ATTRIBUTE := $(BUILD_JAVA) $(JAVA_FLAGS_SMALL) \
--add-exports java.base/jdk.internal.module=ALL-UNNAMED \
build.tools.jigsaw.AddPackagesAttribute
TOOL_GEN_DOCS_BUNDLE_PAGE := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
build.tools.docs.GenDocsBundlePage
endif # _MODULE_TOOLS_GMK

View File

@ -278,7 +278,6 @@ SUNWprivate_1.1 {
Java_java_lang_Module_addExports0;
Java_java_lang_Module_addExportsToAll0;
Java_java_lang_Module_addExportsToAllUnnamed0;
Java_java_lang_Module_addPackage0;
Java_jdk_internal_loader_BootLoader_getSystemPackageLocation;
Java_jdk_internal_loader_BootLoader_getSystemPackageNames;

View File

@ -1,247 +0,0 @@
/*
* Copyright (c) 2017, 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 build.tools.docs;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream;
import static java.util.stream.Collectors.*;
/**
* Build tool to generate the docs bundle index page.
*/
public class GenDocsBundlePage {
private static String DOCS_BUNDLE_PAGE = "docs-bundle-page.html";
private static String MODULE_GROUPS_PROPS = "docs-module-groups.properties";
private static String USAGE =
"GenDocsBundlePage --output <file path> --title <title>" +
" [--template <template>]";
public static void main(String... args) throws IOException {
String title = null;
Path outputfile = null;
Path template = null;
for (int i=0; i < args.length; i++) {
String option = args[i];
if (option.equals("--output")) {
outputfile = Paths.get(getArgument(args, option, ++i));
} else if (option.equals("--title")) {
title = getArgument(args, option, ++i);
} else if (option.equals("--template")) {
template = Paths.get(getArgument(args, option, ++i));
} else if (option.startsWith("-")) {
throw new IllegalArgumentException("Invalid option: " + option);
}
}
if (outputfile == null) {
System.err.println("ERROR: must specify --output option");
System.exit(1);
}
if (title == null) {
System.err.println("ERROR: must specify --title option");
System.exit(1);
}
try (InputStream is = readTemplate(template);
BufferedReader reader = new BufferedReader(new InputStreamReader(is)))
{
new GenDocsBundlePage(title, outputfile).run(reader);
}
}
private static String getArgument(String[] args, String option, int index) {
if (index < args.length) {
return args[index];
}
throw new IllegalArgumentException("Argument must be specified for " + option);
}
private static InputStream readTemplate(Path template) throws IOException {
if (template != null) {
return Files.newInputStream(template);
} else {
return GenDocsBundlePage.class.getResourceAsStream(DOCS_BUNDLE_PAGE);
}
}
private static final String HEADER_TITLE = "@HEADER_TITLE@";
final Path outputfile;
final String title;
final Map<String, Set<ModuleDescriptor>> moduleGroups = new HashMap<>();
GenDocsBundlePage(String title, Path outputfile) throws IOException
{
this.outputfile = outputfile;
this.title = title;
// read module groups
ModuleFinder finder = ModuleFinder.ofSystem();
try (InputStream in = GenDocsBundlePage.class.getResourceAsStream(MODULE_GROUPS_PROPS)) {
Properties props = new Properties();
props.load(in);
for (String key: props.stringPropertyNames()) {
Set<ModuleDescriptor> mods =
Stream.of(props.getProperty(key).split("\\s+"))
.map(String::trim)
.flatMap(mn -> finder.find(mn).stream())
.map(ModuleReference::descriptor)
.collect(toSet());
String name = "@" + key.toUpperCase(Locale.ENGLISH) + "@";
moduleGroups.put(name, mods);
};
}
}
void run(BufferedReader reader) throws IOException {
if (Files.notExists(outputfile.getParent())) {
Files.createDirectories(outputfile.getParent());
}
try (BufferedWriter bw = Files.newBufferedWriter(outputfile, StandardCharsets.UTF_8);
PrintWriter writer = new PrintWriter(bw)) {
reader.lines().map(this::genOutputLine)
.forEach(writer::println);
}
}
String genOutputLine(String line) {
if (line.contains(HEADER_TITLE)) {
line = line.replace(HEADER_TITLE, title);
}
int i = line.indexOf('@');
int j = line.indexOf('@', i+1);
if (i >= 0 && i < j) {
String name = line.substring(i, j+1);
if (moduleGroups.containsKey(name)) {
line = line.replace(name, formatModuleGroup(name));
}
}
return line;
}
String toHRef(ModuleDescriptor md) {
String mn = md.name();
String formattedName;
if (hasExportedAPIs(md)) {
// has exported APIs
formattedName = mn;
} else if (!md.provides().isEmpty()) {
// a provider
formattedName = "<i>" + mn + "</i>";
} else {
// a tool
formattedName = "<i>" + mn + "</i>";
}
return String.format("<a href=\"api/%s-summary.html\">%s</a>",
mn, formattedName);
}
String formatModuleGroup(String groupName) {
StringBuilder sb = new StringBuilder();
// organize in Java SE, JDK, JavaFX, JCP groups
Set<ModuleDescriptor> modules = moduleGroups.get(groupName);
Arrays.stream(ModuleGroup.values())
.forEach(g -> {
Set<ModuleDescriptor> mods = modules.stream()
.filter(md -> g.predicate.test(md.name()))
.collect(toSet());
if (!mods.isEmpty()) {
sb.append("<div class=" + g.cssClass + ">\n");
// modules with exported API
mods.stream()
.filter(this::hasExportedAPIs)
.sorted(Comparator.comparing(ModuleDescriptor::name))
.map(this::toHRef)
.forEach(m -> sb.append(m).append("\n"));
// tools and providers
mods.stream()
.filter(md -> !hasExportedAPIs(md))
.sorted(Comparator.comparing(ModuleDescriptor::name))
.map(this::toHRef)
.forEach(m -> sb.append(m).append("\n"));
sb.append("</div>");
}
});
return sb.toString();
}
private boolean hasExportedAPIs(ModuleDescriptor md) {
if (md.exports().stream().anyMatch(e -> !e.isQualified())) {
return true;
}
// this should check if any indirect exports
// checking requires transitive would be sufficient for JDK modules
if (md.requires().stream()
.map(ModuleDescriptor.Requires::modifiers)
.anyMatch(mods -> mods.contains(ModuleDescriptor.Requires.Modifier.TRANSITIVE))) {
return true;
}
return false;
}
private static final Set<String> NON_JAVA_SE_MODULES =
Set.of("java.jnlp", "java.smartcardio");
/**
* CSS class names are defined in docs-bundle-page.html
*/
enum ModuleGroup {
JAVA_SE("javase", mn -> mn.startsWith("java.") && !NON_JAVA_SE_MODULES.contains(mn)),
JDK("jdk", mn -> mn.startsWith("jdk.")),
JAVAFX("javafx", mn -> mn.startsWith("javafx.")),
NON_JAVA_SE("jcp", NON_JAVA_SE_MODULES::contains);
final String cssClass;
final Predicate<String> predicate;
ModuleGroup(String cssClass, Predicate<String> predicate) {
this.cssClass = cssClass;
this.predicate = predicate;
}
}
}

View File

@ -1,171 +0,0 @@
<!--
Copyright (c) 2017, 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.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<title>@HEADER_TITLE@</title>
<meta http-equiv="content-type" content="text/html;" charset="utf-8">
<link rel="stylesheet" href="resources/jdk-default.css" type="text/css" />
<style type="text/css">
table a { text-decoration: none }
table { border: none }
th, td { border: 2px solid white; }
thead th { background-color: #DDD }
tbody th { background-color: #EEE }
table div.javase, ul.key span.javase { background-color: #C6E7F3 }
table div.jdk, ul.key span.jdk { background-color: #ECE1C5 }
table div.javafx, ul.key span.javafx { background-color: #ECEDCC }
table div.jcp, ul.key span.jcp { background-color: #E9E9E9 }
td div { padding: 3px 5px; color: blue }
table tbody td div a { padding: 0 .5em; margin: 0: 1em; }
table tbody td div a:link { color: black }
table tbody td div a:visited { color: black }
table tbody td div a[href]:hover { color: black; text-decoration: underline }
td { padding: 0 }
table tbody td div a { padding: 0 .5em; margin: 0: 1em }
.key { font-size: smaller; }
ul.key li { display:inline-block; padding: 0 1em }
ul.key span {
border: 1px solid black;
font-family: DejaVu Sans Mono, monospace;
}
ul.key span:before { content: " " }
ul.key span:after { content: " " }
caption {
text-align: center;
}
tr:nth-child(even), tr:nth-child(even) th[scope=row] {
background-color: #EEE;
}
tr:nth-child(odd), tr:nth-child(odd) th[scope=row] {
background-color: #EEE;
}
</style>
</head>
<h1>@HEADER_TITLE@</h1>
<ul>
<li><a href="api/index.html">JDK API Specification</a></li>
<li><a href="https://docs.oracle.com/javase/specs/">
Java Language and Virtual Machine Specifications</a></li>
<li><a href="https://www.oracle.com/pls/topic/lookup?ctx=javase9&id=tools_reference_overview">
Tools Reference</a></li>
</ul>
<table>
<caption style="display:none">JDK Modules</caption>
<thead>
<tr>
<th scope="col">Group</th>
<th scope="col">Modules</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Foundation</th>
<td>@JAVA_BASE@</td>
</tr>
<tr>
<th scope="row">Integration</th>
<td>@INTEGRATION_MODULES@</td>
</tr>
<tr>
<th scope="row">User Interface</th>
<td>@UI_MODULES@</td>
</tr>
<tr>
<th scope="row">Compilation</th>
<td>@COMPILER_MODULES@</td>
</tr>
<tr>
<th scope="row">Scripting</th>
<td>@SCRIPTING_MODULES@</td>
</tr>
<tr>
<th scope="row">Security</th>
<td>@SECURITY_MODULES@</td>
</tr>
<tr>
<th scope="row">Management</th>
<td>@MANAGEMENT_MODULES@</td>
</tr>
<tr>
<th scope="row">Instrumentation</th>
<td>@INSTRUMENT_MODULES@</td>
</tr>
<tr>
<th scope="row">Serviceability</th>
<td>@SVC_MODULES@</td>
</tr>
<tr>
<th scope="row">Packaging</th>
<td>@PACKAGING_MODULES@</td>
</tr>
<tr>
<th scope="row">Incubator</th>
<td>@INCUBATOR_MODULES@</td>
</tr>
<tr>
<th scope="row">Non-Java SE</th>
<td>@OTHER_MODULES@</td>
</tr>
<tr>
<th scope="row">Java EE</th>
<td>@JAVA_EE_MODULES@</td>
</tr>
<tr>
<th scope="row">Aggregator</th>
<td>@AGGREGATOR_MODULES@</td>
</tr>
</tbody>
</table>
<p class="key">Key:
<ul class="key">
<li><span class="javase">&nbsp;</span>&nbsp; Java SE
<li><span class="jdk">&nbsp;</span>&nbsp; JDK
<li><span class="javafx">&nbsp;</span>&nbsp; JavaFX
<li><span class="jcp">&nbsp;</span>&nbsp; Non-Java SE
<li><i>italic</i> No Exported API (e.g. a tool or provider)</li>
</ul>
<p>
<hr>
<a href="legal/cpyr.html">Copyright</a> &copy 1993, 2017, Oracle and/or its affiliates. All rights reserved.</p>
</body>
</html>

View File

@ -1,114 +0,0 @@
# Module Grouping for the docs bundle page
#
java_base=\
java.base
java_ee_modules=\
java.activation \
java.corba \
java.transaction \
java.xml.bind \
java.xml.ws \
java.xml.ws.annotation \
jdk.xml.bind \
jdk.xml.ws
aggregator_modules=\
java.se \
java.se.ee
security_modules=\
java.security.jgss \
java.security.sasl \
java.xml.crypto \
jdk.security.auth \
jdk.security.jgss \
jdk.crypto.cryptoki \
jdk.crypto.ec \
jdk.crypto.mscapi \
jdk.crypto.ucrypto \
jdk.policytool
instrument_modules=\
java.instrument
management_modules=\
java.management \
java.management.rmi \
jdk.management \
jdk.management.agent \
jdk.management.cmm \
jdk.management.jfr \
jdk.management.resource \
jdk.snmp \
jdk.jconsole
integration_modules=\
java.logging \
java.naming \
java.prefs \
java.rmi \
java.sql \
java.sql.rowset \
java.xml \
jdk.charsets \
jdk.localedata \
jdk.net \
jdk.sctp \
jdk.jsobject \
jdk.httpserver \
jdk.naming.dns \
jdk.naming.rmi \
jdk.xml.dom \
jdk.zipfs
ui_modules=\
java.datatransfer \
java.desktop \
javafx.base \
javafx.controls \
javafx.fxml \
javafx.graphics \
javafx.media \
javafx.swing \
javafx.web \
jdk.accessibility
svc_modules=\
jdk.jfr \
jdk.attach \
jdk.jcmd \
jdk.jdi \
jdk.jdwp.agent \
jdk.jstatd \
jdk.hotspot.agent
packaging_modules=\
jdk.jartool \
jdk.jlink \
jdk.pack \
jdk.packager.services
compiler_modules=\
java.compiler \
jdk.compiler \
jdk.javadoc \
jdk.jdeps \
jdk.editpad \
jdk.jshell \
jdk.rmic
scripting_modules=\
java.scripting \
jdk.dynalink \
jdk.scripting.nashorn \
jdk.scripting.nashorn.shell
other_modules=\
java.jnlp \
java.smartcardio
incubator_modules=\
jdk.incubator.httpclient

View File

@ -916,23 +916,28 @@ public class File
* Returns the time that the file denoted by this abstract pathname was
* last modified.
*
* @apiNote
* While the unit of time of the return value is milliseconds, the
* granularity of the value depends on the underlying file system and may
* be larger. For example, some file systems use time stamps in units of
* seconds.
*
* <p> Where it is required to distinguish an I/O exception from the case
* where {@code 0L} is returned, or where several attributes of the
* same file are required at the same time, or where the time of last
* access or the creation time are required, then the {@link
* java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
* Files.readAttributes} method may be used.
*
* @apiNote
* While the unit of time of the return value is milliseconds,
* the granularity of the value depends on the underlying
* file system and may be larger. For example, some
* file systems use time stamps in units of seconds.
* Files.readAttributes} method may be used. If however only the
* time of last modification is required, then the
* {@link java.nio.file.Files#getLastModifiedTime(Path,LinkOption[])
* Files.getLastModifiedTime} method may be used instead.
*
* @return A <code>long</code> value representing the time the file was
* last modified, measured in milliseconds since the epoch
* (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
* file does not exist or if an I/O error occurs
* file does not exist or if an I/O error occurs. The value may
* be negative indicating the number of milliseconds before the
* epoch
*
* @throws SecurityException
* If a security manager exists and its {@link

View File

@ -50,6 +50,7 @@ import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@ -2066,25 +2067,6 @@ public final class Class<T> implements java.io.Serializable,
return getReflectionFactory().copyMethod(method);
}
/**
* Returns a {@code Method} object that reflects the specified public
* member method of the class or interface represented by this
* {@code Class} object.
*
* @param name the name of the method
* @param parameterTypes the list of parameters
* @return the {@code Method} object that matches the specified
* {@code name} and {@code parameterTypes}; {@code null}
* if the method is not found or the name is
* "&lt;init&gt;"or "&lt;clinit&gt;".
*/
Method getMethodOrNull(String name, Class<?>... parameterTypes) {
Objects.requireNonNull(name);
Method method = getMethod0(name, parameterTypes);
return method == null ? null : getReflectionFactory().copyMethod(method);
}
/**
* Returns a {@code Constructor} object that reflects the specified
* public constructor of the class represented by this {@code Class}
@ -2225,7 +2207,6 @@ public final class Class<T> implements java.io.Serializable,
/**
*
* Returns an array containing {@code Method} objects reflecting all the
* declared methods of the class or interface represented by this {@code
* Class} object, including public, protected, default (package)
@ -2453,6 +2434,30 @@ public final class Class<T> implements java.io.Serializable,
return getReflectionFactory().copyMethod(method);
}
/**
* Returns the list of {@code Method} objects for the declared public
* methods of this class or interface that have the specified method name
* and parameter types.
*
* @param name the name of the method
* @param parameterTypes the parameter array
* @return the list of {@code Method} objects for the public methods of
* this class matching the specified name and parameters
*/
List<Method> getDeclaredPublicMethods(String name, Class<?>... parameterTypes) {
Method[] methods = privateGetDeclaredMethods(/* publicOnly */ true);
ReflectionFactory factory = getReflectionFactory();
List<Method> result = new ArrayList<>();
for (Method method : methods) {
if (method.getName().equals(name)
&& Arrays.equals(
factory.getExecutableSharedParameterTypes(method),
parameterTypes)) {
result.add(factory.copyMethod(method));
}
}
return result;
}
/**
* Returns a {@code Constructor} object that reflects the specified

View File

@ -93,12 +93,20 @@ import sun.security.util.SecurityConstants;
* <p> Class loaders may typically be used by security managers to indicate
* security domains.
*
* <p> In addition to loading classes, a class loader is also responsible for
* locating resources. A resource is some data (a "{@code .class}" file,
* configuration data, or an image for example) that is identified with an
* abstract '/'-separated path name. Resources are typically packaged with an
* application or library so that they can be located by code in the
* application or library. In some cases, the resources are included so that
* they can be located by other libraries.
*
* <p> The {@code ClassLoader} class uses a delegation model to search for
* classes and resources. Each instance of {@code ClassLoader} has an
* associated parent class loader. When requested to find a class or
* resource, a {@code ClassLoader} instance will delegate the search for the
* class or resource to its parent class loader before attempting to find the
* class or resource itself.
* associated parent class loader. When requested to find a class or
* resource, a {@code ClassLoader} instance will usually delegate the search
* for the class or resource to its parent class loader before attempting to
* find the class or resource itself.
*
* <p> Class loaders that support concurrent loading of classes are known as
* <em>{@linkplain #isRegisteredAsParallelCapable() parallel capable}</em> class
@ -129,11 +137,13 @@ import sun.security.util.SecurityConstants;
* classes and JDK-specific run-time classes that are defined by the
* platform class loader or its ancestors.
* <p> To allow for upgrading/overriding of modules defined to the platform
* class loader, and where classes in the upgraded version link to
* classes in modules defined to the application class loader, the
* platform class loader may delegate to the application class loader.
* In other words, classes in named modules defined to the application
* class loader may be visible to the platform class loader. </li>
* class loader, and where upgraded modules read modules defined to class
* loaders other than the platform class loader and its ancestors, then
* the platform class loader may have to delegate to other class loaders,
* the application class loader for example.
* In other words, classes in named modules defined to class loaders
* other than the platform class loader and its ancestors may be visible
* to the platform class loader. </li>
* <li><p>{@linkplain #getSystemClassLoader() System class loader}.
* It is also known as <em>application class loader</em> and is distinct
* from the platform class loader.
@ -498,7 +508,7 @@ public abstract class ClassLoader {
*
* <li><p> Invoke the {@link #loadClass(String) loadClass} method
* on the parent class loader. If the parent is {@code null} the class
* loader built-in to the virtual machine is used, instead. </p></li>
* loader built into the virtual machine is used, instead. </p></li>
*
* <li><p> Invoke the {@link #findClass(String)} method to find the
* class. </p></li>
@ -681,8 +691,9 @@ public abstract class ClassLoader {
* This method should be overridden by class loader implementations that
* follow the delegation model for loading classes, and will be invoked by
* the {@link #loadClass loadClass} method after checking the
* parent class loader for the requested class. The default implementation
* throws a {@code ClassNotFoundException}.
* parent class loader for the requested class.
*
* @implSpec The default implementation throws {@code ClassNotFoundException}.
*
* @param name
* The <a href="#name">binary name</a> of the class
@ -1127,8 +1138,9 @@ public abstract class ClassLoader {
putIfAbsent(pname, (certs == null? nocerts:certs));
}
if (pcerts != null && !compareCerts(pcerts, certs)) {
throw new SecurityException("class \""+ name +
"\"'s signer information does not match signer information of other classes in the same package");
throw new SecurityException("class \"" + name
+ "\"'s signer information does not match signer information"
+ " of other classes in the same package");
}
}
@ -1329,12 +1341,7 @@ public abstract class ClassLoader {
* that is independent of the location of the code.
*
* <p> The name of a resource is a '{@code /}'-separated path name that
* identifies the resource.
*
* <p> This method will first search the parent class loader for the
* resource; if the parent is {@code null} the path of the class loader
* built-in to the virtual machine is searched. That failing, this method
* will invoke {@link #findResource(String)} to find the resource. </p>
* identifies the resource. </p>
*
* <p> Resources in named modules are subject to the encapsulation rules
* specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
@ -1344,6 +1351,11 @@ public abstract class ClassLoader {
* opened} unconditionally (even if the caller of this method is in the
* same module as the resource). </p>
*
* @implSpec The default implementation will first search the parent class
* loader for the resource; if the parent is {@code null} the path of the
* class loader built into the virtual machine is searched. If not found,
* this method will invoke {@link #findResource(String)} to find the resource.
*
* @apiNote Where several modules are defined to the same class loader,
* and where more than one module contains a resource with the given name,
* then the ordering that modules are searched is not specified and may be
@ -1387,10 +1399,7 @@ public abstract class ClassLoader {
* that is independent of the location of the code.
*
* <p> The name of a resource is a {@code /}-separated path name that
* identifies the resource.
*
* <p> The delegation order for searching is described in the documentation
* for {@link #getResource(String)}. </p>
* identifies the resource. </p>
*
* <p> Resources in named modules are subject to the encapsulation rules
* specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
@ -1398,7 +1407,15 @@ public abstract class ClassLoader {
* name ending with "{@code .class}", this method will only find resources in
* packages of named modules when the package is {@link Module#isOpen(String)
* opened} unconditionally (even if the caller of this method is in the
* same module as the resource).</p>
* same module as the resource). </p>
*
* @implSpec The default implementation will first search the parent class
* loader for the resource; if the parent is {@code null} the path of the
* class loader built into the virtual machine is searched. It then
* invokes {@link #findResources(String)} to find the resources with the
* name in this class loader. It returns an enumeration whose elements
* are the URLs found by searching the parent class loader followed by
* the elements found with {@code findResources}.
*
* @apiNote Where several modules are defined to the same class loader,
* and where more than one module contains a resource with the given name,
@ -1424,8 +1441,6 @@ public abstract class ClassLoader {
* If I/O errors occur
* @throws NullPointerException If {@code name} is {@code null}
*
* @see #findResources(String)
*
* @since 1.2
* @revised 9
* @spec JPMS
@ -1453,9 +1468,6 @@ public abstract class ClassLoader {
* <p> The name of a resource is a {@code /}-separated path name that
* identifies the resource.
*
* <p> The search order is described in the documentation for {@link
* #getResource(String)}.
*
* <p> The resources will be located when the returned stream is evaluated.
* If the evaluation results in an {@code IOException} then the I/O
* exception is wrapped in an {@link UncheckedIOException} that is then
@ -1469,6 +1481,10 @@ public abstract class ClassLoader {
* opened} unconditionally (even if the caller of this method is in the
* same module as the resource). </p>
*
* @implSpec The default implementation invokes {@link #getResources(String)
* getResources} to find all the resources with the given name and returns
* a stream with the elements in the enumeration as the source.
*
* @apiNote When overriding this method it is recommended that an
* implementation ensures that any delegation is consistent with the {@link
* #getResource(java.lang.String) getResource(String)} method. This should
@ -1486,8 +1502,6 @@ public abstract class ClassLoader {
*
* @throws NullPointerException If {@code name} is {@code null}
*
* @see #findResources(String)
*
* @since 9
*/
public Stream<URL> resources(String name) {
@ -1506,7 +1520,7 @@ public abstract class ClassLoader {
/**
* Finds the resource with the given name. Class loader implementations
* should override this method to specify where to find resources.
* should override this method.
*
* <p> For resources in named modules then the method must implement the
* rules for encapsulation specified in the {@code Module} {@link
@ -1515,6 +1529,8 @@ public abstract class ClassLoader {
* modules unless the package is {@link Module#isOpen(String) opened}
* unconditionally. </p>
*
* @implSpec The default implementation returns {@code null}.
*
* @param name
* The resource name
*
@ -1535,8 +1551,7 @@ public abstract class ClassLoader {
/**
* Returns an enumeration of {@link java.net.URL URL} objects
* representing all the resources with the given name. Class loader
* implementations should override this method to specify where to load
* resources from.
* implementations should override this method.
*
* <p> For resources in named modules then the method must implement the
* rules for encapsulation specified in the {@code Module} {@link
@ -1545,6 +1560,9 @@ public abstract class ClassLoader {
* modules unless the package is {@link Module#isOpen(String) opened}
* unconditionally. </p>
*
* @implSpec The default implementation returns an enumeration that
* contains no elements.
*
* @param name
* The resource name
*
@ -1899,7 +1917,8 @@ public abstract class ClassLoader {
// the system class loader is the built-in app class loader during startup
return getBuiltinAppClassLoader();
case 3:
throw new InternalError("getSystemClassLoader should only be called after VM booted");
String msg = "getSystemClassLoader should only be called after VM booted";
throw new InternalError(msg);
case 4:
// system fully initialized
assert VM.isBooted() && scl != null;
@ -2146,7 +2165,7 @@ public abstract class ClassLoader {
* @revised 9
* @spec JPMS
*
* @see <a href="../../../technotes/guides/jar/jar.html#sealing">
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
* The JAR File Specification: Package Sealing</a>
*/
protected Package definePackage(String name, String specTitle,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2017, 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
@ -116,6 +116,10 @@ class FdLibm {
private static final double F = 0x1.9b6db6db6db6ep0; // 45/28 ~= 1.60714285714285720630e+00
private static final double G = 0x1.6db6db6db6db7p-2; // 5/14 ~= 3.57142857142857150787e-01
private Cbrt() {
throw new UnsupportedOperationException();
}
public static strictfp double compute(double x) {
double t = 0.0;
double sign;
@ -195,6 +199,10 @@ class FdLibm {
public static final double TWO_MINUS_600 = 0x1.0p-600;
public static final double TWO_PLUS_600 = 0x1.0p+600;
private Hypot() {
throw new UnsupportedOperationException();
}
public static strictfp double compute(double x, double y) {
double a = Math.abs(x);
double b = Math.abs(y);
@ -331,6 +339,10 @@ class FdLibm {
* representable.
*/
public static class Pow {
private Pow() {
throw new UnsupportedOperationException();
}
public static strictfp double compute(final double x, final double y) {
double z;
double r, s, t, u, v, w;
@ -664,6 +676,10 @@ class FdLibm {
private static final double P4 = -0x1.bbd41c5d26bf1p-20; // -1.65339022054652515390e-06
private static final double P5 = 0x1.6376972bea4d0p-25; // 4.13813679705723846039e-08
private Exp() {
throw new UnsupportedOperationException();
}
// should be able to forgo strictfp due to controlled over/underflow
public static strictfp double compute(double x) {
double y;

View File

@ -63,8 +63,8 @@ public class LayerInstantiationException extends RuntimeException {
}
/**
* Constructs a {@code FindException} with the given detail message
* and cause.
* Constructs a {@code LayerInstantiationException} with the given detail
* message and cause.
*
* @param msg
* The detail message; can be {@code null}
@ -74,6 +74,5 @@ public class LayerInstantiationException extends RuntimeException {
public LayerInstantiationException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -43,6 +43,7 @@ import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -55,8 +56,10 @@ import java.util.stream.Stream;
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.ClassLoaders;
import jdk.internal.misc.JavaLangAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.IllegalAccessLogger;
import jdk.internal.module.ModuleLoaderMap;
import jdk.internal.module.ServicesCatalog;
import jdk.internal.module.Resources;
@ -162,7 +165,6 @@ public final class Module implements AnnotatedElement {
}
/**
* Returns {@code true} if this module is a named module.
*
@ -249,12 +251,10 @@ public final class Module implements AnnotatedElement {
// special Module to mean "all unnamed modules"
private static final Module ALL_UNNAMED_MODULE = new Module(null);
private static final Set<Module> ALL_UNNAMED_MODULE_SET = Set.of(ALL_UNNAMED_MODULE);
// special Module to mean "everyone"
private static final Module EVERYONE_MODULE = new Module(null);
// set contains EVERYONE_MODULE, used when a package is opened or
// exported unconditionally
private static final Set<Module> EVERYONE_SET = Set.of(EVERYONE_MODULE);
@ -534,12 +534,12 @@ public final class Module implements AnnotatedElement {
return true;
// all packages are exported/open to self
if (other == this && containsPackage(pn))
if (other == this && descriptor.packages().contains(pn))
return true;
// all packages in open and automatic modules are open
if (descriptor.isOpen() || descriptor.isAutomatic())
return containsPackage(pn);
return descriptor.packages().contains(pn);
// exported/opened via module declaration/descriptor
if (isStaticallyExportedOrOpen(pn, other, open))
@ -555,42 +555,48 @@ public final class Module implements AnnotatedElement {
/**
* Returns {@code true} if this module exports or opens a package to
* the given module via its module declaration.
* the given module via its module declaration or CLI options.
*/
private boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
// package is open to everyone or <other>
// test if package is open to everyone or <other>
Map<String, Set<Module>> openPackages = this.openPackages;
if (openPackages != null) {
Set<Module> targets = openPackages.get(pn);
if (targets != null) {
if (targets.contains(EVERYONE_MODULE))
return true;
if (other != EVERYONE_MODULE && targets.contains(other))
return true;
}
if (openPackages != null && allows(openPackages.get(pn), other)) {
return true;
}
if (!open) {
// package is exported to everyone or <other>
// test package is exported to everyone or <other>
Map<String, Set<Module>> exportedPackages = this.exportedPackages;
if (exportedPackages != null) {
Set<Module> targets = exportedPackages.get(pn);
if (targets != null) {
if (targets.contains(EVERYONE_MODULE))
return true;
if (other != EVERYONE_MODULE && targets.contains(other))
return true;
}
if (exportedPackages != null && allows(exportedPackages.get(pn), other)) {
return true;
}
}
return false;
}
/**
* Returns {@code true} if targets is non-null and contains EVERYONE_MODULE
* or the given module. Also returns true if the given module is an unnamed
* module and targets contains ALL_UNNAMED_MODULE.
*/
private boolean allows(Set<Module> targets, Module module) {
if (targets != null) {
if (targets.contains(EVERYONE_MODULE))
return true;
if (module != EVERYONE_MODULE) {
if (targets.contains(module))
return true;
if (!module.isNamed() && targets.contains(ALL_UNNAMED_MODULE))
return true;
}
}
return false;
}
/**
* Returns {@code true} if this module reflectively exports or opens given
* package package to the given module.
* Returns {@code true} if this module reflectively exports or opens the
* given package to the given module.
*/
private boolean isReflectivelyExportedOrOpen(String pn, Module other, boolean open) {
// exported or open to all modules
@ -632,6 +638,22 @@ public final class Module implements AnnotatedElement {
return false;
}
/**
* Returns {@code true} if this module reflectively exports the
* given package to the given module.
*/
boolean isReflectivelyExported(String pn, Module other) {
return isReflectivelyExportedOrOpen(pn, other, false);
}
/**
* Returns {@code true} if this module reflectively opens the
* given package to the given module.
*/
boolean isReflectivelyOpened(String pn, Module other) {
return isReflectivelyExportedOrOpen(pn, other, true);
}
/**
* If the caller's module is this module then update this module to export
@ -800,7 +822,7 @@ public final class Module implements AnnotatedElement {
}
/**
* Updates this module to export a package to all unnamed modules.
* Updates this module to open a package to all unnamed modules.
*
* @apiNote Used by the --add-opens command line option.
*/
@ -808,7 +830,6 @@ public final class Module implements AnnotatedElement {
implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true);
}
/**
* Updates a module to export or open a module to another module.
*
@ -825,12 +846,31 @@ public final class Module implements AnnotatedElement {
if (!isNamed() || descriptor.isOpen() || descriptor.isAutomatic())
return;
// nothing to do if already exported/open to other
if (implIsExportedOrOpen(pn, other, open))
return;
// check if the package is already exported/open to other
if (implIsExportedOrOpen(pn, other, open)) {
// if the package is exported/open for illegal access then we need
// to record that it has also been exported/opened reflectively so
// that the IllegalAccessLogger doesn't emit a warning.
boolean needToAdd = false;
if (!other.isNamed()) {
IllegalAccessLogger l = IllegalAccessLogger.illegalAccessLogger();
if (l != null) {
if (open) {
needToAdd = l.isOpenForIllegalAccess(this, pn);
} else {
needToAdd = l.isExportedForIllegalAccess(this, pn);
}
}
}
if (!needToAdd) {
// nothing to do
return;
}
}
// can only export a package in the module
if (!containsPackage(pn)) {
if (!descriptor.packages().contains(pn)) {
throw new IllegalArgumentException("package " + pn
+ " not in contents");
}
@ -850,7 +890,6 @@ public final class Module implements AnnotatedElement {
Map<String, Boolean> map = reflectivelyExports
.computeIfAbsent(this, other,
(m1, m2) -> new ConcurrentHashMap<>());
if (open) {
map.put(pn, Boolean.TRUE); // may need to promote from FALSE to TRUE
} else {
@ -858,6 +897,38 @@ public final class Module implements AnnotatedElement {
}
}
/**
* Updates a module to open all packages returned by the given iterator to
* all unnamed modules.
*
* @apiNote Used during startup to open packages for illegal access.
*/
void implAddOpensToAllUnnamed(Iterator<String> iterator) {
if (jdk.internal.misc.VM.isModuleSystemInited()) {
throw new IllegalStateException("Module system already initialized");
}
// replace this module's openPackages map with a new map that opens
// the packages to all unnamed modules.
Map<String, Set<Module>> openPackages = this.openPackages;
if (openPackages == null) {
openPackages = new HashMap<>();
} else {
openPackages = new HashMap<>(openPackages);
}
while (iterator.hasNext()) {
String pn = iterator.next();
Set<Module> prev = openPackages.putIfAbsent(pn, ALL_UNNAMED_MODULE_SET);
if (prev != null) {
prev.add(ALL_UNNAMED_MODULE);
}
// update VM to export the package
addExportsToAllUnnamed0(this, pn);
}
this.openPackages = openPackages;
}
// -- services --
@ -947,19 +1018,6 @@ public final class Module implements AnnotatedElement {
// -- packages --
// Additional packages that are added to the module at run-time.
private volatile Map<String, Boolean> extraPackages;
private boolean containsPackage(String pn) {
if (descriptor.packages().contains(pn))
return true;
Map<String, Boolean> extraPackages = this.extraPackages;
if (extraPackages != null && extraPackages.containsKey(pn))
return true;
return false;
}
/**
* Returns the set of package names for the packages in this module.
*
@ -974,89 +1032,19 @@ public final class Module implements AnnotatedElement {
*/
public Set<String> getPackages() {
if (isNamed()) {
Set<String> packages = descriptor.packages();
Map<String, Boolean> extraPackages = this.extraPackages;
if (extraPackages == null) {
return packages;
} else {
return Stream.concat(packages.stream(),
extraPackages.keySet().stream())
.collect(Collectors.toSet());
}
return descriptor.packages();
} else {
// unnamed module
Stream<Package> packages;
if (loader == null) {
packages = BootLoader.packages();
} else {
packages = SharedSecrets.getJavaLangAccess().packages(loader);
packages = loader.packages();
}
return packages.map(Package::getName).collect(Collectors.toSet());
}
}
/**
* Add a package to this module without notifying the VM.
*
* @apiNote This method is VM white-box testing.
*/
void implAddPackageNoSync(String pn) {
implAddPackage(pn.replace('/', '.'), false);
}
/**
* Add a package to this module.
*
* If {@code syncVM} is {@code true} then the VM is notified. This method is
* a no-op if this is an unnamed module or the module already contains the
* package.
*
* @throws IllegalArgumentException if the package name is not legal
* @throws IllegalStateException if the package is defined to another module
*/
private void implAddPackage(String pn, boolean syncVM) {
// no-op if unnamed module
if (!isNamed())
return;
// no-op if module contains the package
if (containsPackage(pn))
return;
// check package name is legal for named modules
if (pn.isEmpty())
throw new IllegalArgumentException("Cannot add <unnamed> package");
for (int i=0; i<pn.length(); i++) {
char c = pn.charAt(i);
if (c == '/' || c == ';' || c == '[') {
throw new IllegalArgumentException("Illegal character: " + c);
}
}
// create extraPackages if needed
Map<String, Boolean> extraPackages = this.extraPackages;
if (extraPackages == null) {
synchronized (this) {
extraPackages = this.extraPackages;
if (extraPackages == null)
this.extraPackages = extraPackages = new ConcurrentHashMap<>();
}
}
// update VM first in case it fails. This is a no-op if another thread
// beats us to add the package first
if (syncVM) {
// throws IllegalStateException if defined to another module
addPackage0(this, pn);
if (descriptor.isOpen() || descriptor.isAutomatic()) {
addExportsToAll0(this, pn);
}
}
extraPackages.putIfAbsent(pn, Boolean.TRUE);
}
// -- creating Module objects --
@ -1075,18 +1063,22 @@ public final class Module implements AnnotatedElement {
Map<String, Module> nameToModule = new HashMap<>();
Map<String, ClassLoader> moduleToLoader = new HashMap<>();
boolean isBootLayer = (ModuleLayer.boot() == null);
Set<ClassLoader> loaders = new HashSet<>();
boolean hasPlatformModules = false;
// map each module to a class loader
for (ResolvedModule resolvedModule : cf.modules()) {
String name = resolvedModule.name();
ClassLoader loader = clf.apply(name);
if (loader != null) {
moduleToLoader.put(name, loader);
moduleToLoader.put(name, loader);
if (loader == null || loader == ClassLoaders.platformClassLoader()) {
if (!(clf instanceof ModuleLoaderMap.Mapper)) {
throw new IllegalArgumentException("loader can't be 'null'"
+ " or the platform class loader");
}
hasPlatformModules = true;
} else {
loaders.add(loader);
} else if (!(clf instanceof ModuleLoaderMap.Mapper)) {
throw new IllegalArgumentException("loader can't be 'null'");
}
}
@ -1098,7 +1090,7 @@ public final class Module implements AnnotatedElement {
URI uri = mref.location().orElse(null);
ClassLoader loader = moduleToLoader.get(resolvedModule.name());
Module m;
if (loader == null && isBootLayer && name.equals("java.base")) {
if (loader == null && name.equals("java.base")) {
// java.base is already defined to the VM
m = Object.class.getModule();
} else {
@ -1157,8 +1149,12 @@ public final class Module implements AnnotatedElement {
initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
}
// register the modules in the boot layer
if (isBootLayer) {
// if there are modules defined to the boot or platform class loaders
// then register the modules in the class loader's services catalog
if (hasPlatformModules) {
ClassLoader pcl = ClassLoaders.platformClassLoader();
ServicesCatalog bootCatalog = BootLoader.getServicesCatalog();
ServicesCatalog pclCatalog = ServicesCatalog.getServicesCatalog(pcl);
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleReference mref = resolvedModule.reference();
ModuleDescriptor descriptor = mref.descriptor();
@ -1166,13 +1162,11 @@ public final class Module implements AnnotatedElement {
String name = descriptor.name();
Module m = nameToModule.get(name);
ClassLoader loader = moduleToLoader.get(name);
ServicesCatalog catalog;
if (loader == null) {
catalog = BootLoader.getServicesCatalog();
} else {
catalog = ServicesCatalog.getServicesCatalog(loader);
bootCatalog.register(m);
} else if (loader == pcl) {
pclCatalog.register(m);
}
catalog.register(m);
}
}
}
@ -1587,7 +1581,4 @@ public final class Module implements AnnotatedElement {
// JVM_AddModuleExportsToAllUnnamed
private static native void addExportsToAllUnnamed0(Module from, String pn);
// JVM_AddModulePackage
private static native void addPackage0(Module m, String pn);
}

View File

@ -244,6 +244,32 @@ public final class ModuleLayer {
return this;
}
/**
* Updates module {@code source} in the layer to export a package to
* module {@code target}. This method is a no-op if {@code source}
* already exports the package to at least {@code target}.
*
* @param source
* The source module
* @param pn
* The package name
* @param target
* The target module
*
* @return This controller
*
* @throws IllegalArgumentException
* If {@code source} is not in the module layer or the package
* is not in the source module
*
* @see Module#addExports
*/
public Controller addExports(Module source, String pn, Module target) {
ensureInLayer(source);
source.implAddExports(pn, target);
return this;
}
/**
* Updates module {@code source} in the layer to open a package to
* module {@code target}. This method is a no-op if {@code source}
@ -254,7 +280,7 @@ public final class ModuleLayer {
* @param pn
* The package name
* @param target
* The target module to read
* The target module
*
* @return This controller
*
@ -397,7 +423,7 @@ public final class ModuleLayer {
* class loader and defines all modules to that class loader.
*
* <p> The class loader created by this method implements <em>direct
* delegation</em> when loading types from modules. When its {@link
* delegation</em> when loading classes from modules. If the {@link
* ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
* load a class then it uses the package name of the class to map it to a
* module. This may be a module in this layer and hence defined to the same
@ -408,6 +434,12 @@ public final class ModuleLayer {
* When {@code loadClass} is invoked to load classes that do not map to a
* module then it delegates to the parent class loader. </p>
*
* <p> The class loader created by this method locates resources
* ({@link ClassLoader#getResource(String) getResource}, {@link
* ClassLoader#getResources(String) getResources}, and other resource
* methods) in all modules in the layer before searching the parent class
* loader. </p>
*
* <p> Attempting to create a layer with all modules defined to the same
* class loader can fail for the following reasons:
*
@ -417,8 +449,8 @@ public final class ModuleLayer {
* configuration have the same package. </p></li>
*
* <li><p> <em>Split delegation</em>: The resulting class loader would
* need to delegate to more than one class loader in order to load types
* in a specific package. </p></li>
* need to delegate to more than one class loader in order to load
* classes in a specific package. </p></li>
*
* </ul>
*
@ -481,7 +513,7 @@ public final class ModuleLayer {
* class loader.
*
* <p> The class loaders created by this method implement <em>direct
* delegation</em> when loading types from modules. When {@link
* delegation</em> when loading classes from modules. If the {@link
* ClassLoader#loadClass(String, boolean) loadClass} method is invoked to
* load a class then it uses the package name of the class to map it to a
* module. The package may be in the module defined to the class loader.
@ -489,9 +521,15 @@ public final class ModuleLayer {
* module defined to the class loader. It may be in a package exported by a
* module in a parent layer. The class loader delegates to the class loader
* of the module, throwing {@code ClassNotFoundException} if not found by
* that class loader.
* When {@code loadClass} is invoked to load classes that do not map to a
* module then it delegates to the parent class loader. </p>
* that class loader. When {@code loadClass} is invoked to load a class
* that does not map to a module then it delegates to the parent class
* loader. </p>
*
* <p> The class loaders created by this method locate resources
* ({@link ClassLoader#getResource(String) getResource}, {@link
* ClassLoader#getResources(String) getResources}, and other resource
* methods) in the module defined to the class loader before searching
* the parent class loader. </p>
*
* <p> If there is a security manager then the class loaders created by
* this method will load classes and resources with privileges that are
@ -576,10 +614,9 @@ public final class ModuleLayer {
* <p> In addition, a layer cannot be created if the configuration contains
* a module named "{@code java.base}", a configuration contains a module
* with a package named "{@code java}" or a package name starting with
* "{@code java.}" and the module is mapped to a class loader other than
* the {@link ClassLoader#getPlatformClassLoader() platform class loader},
* or the function to map a module name to a class loader returns
* {@code null}. </p>
* "{@code java.}", or the function to map a module name to a class loader
* returns {@code null} or the {@linkplain ClassLoader#getPlatformClassLoader()
* platform class loader}. </p>
*
* <p> If the function to map a module name to class loader throws an error
* or runtime exception then it is propagated to the caller of this method.

View File

@ -109,7 +109,7 @@ import jdk.internal.reflect.Reflection;
* and have no specification and implementation versioning information.
*
* @jvms 5.3 Run-time package
* @see <a href="../../../technotes/guides/jar/jar.html#sealing">
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
* The JAR File Specification: Package Sealing</a>
* @see ClassLoader#definePackage(String, String, String, String, String, String, String, URL)
*

View File

@ -194,18 +194,15 @@ import sun.security.util.SecurityConstants;
* of system administrators who might need to perform multiple
* tasks that require all (or numerous) permissions.
* <p>
* See <a href ="../../../technotes/guides/security/permissions.html">
* Permissions in the JDK</a> for permission-related information.
* See {@extLink security_guide_permissions
* Permissions in the Java Development Kit (JDK)}
* for permission-related information.
* This document includes, for example, a table listing the various SecurityManager
* <code>check</code> methods and the permission(s) the default
* implementation of each such method requires.
* It also contains a table of all the version 1.2 methods
* that require permissions, and for each such method tells
* which permission it requires.
* <p>
* For more information about <code>SecurityManager</code> changes made in
* the JDK and advice regarding porting of 1.1-style security managers,
* see the <a href="../../../technotes/guides/security/index.html">security documentation</a>.
*
* @author Arthur van Hoff
* @author Roland Schemers
@ -1496,7 +1493,10 @@ class SecurityManager {
* Throws a {@code SecurityException} if the calling thread is not allowed
* to access the specified package.
* <p>
* This method is called by the {@code loadClass} method of class loaders.
* During class loading, this method may be called by the {@code loadClass}
* method of class loaders and by the Java Virtual Machine to ensure that
* the caller is allowed to access the package of the class that is
* being loaded.
* <p>
* This method checks if the specified package starts with or equals
* any of the packages in the {@code package.access} Security Property.

View File

@ -47,6 +47,8 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.nio.channels.Channel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
@ -2069,8 +2071,8 @@ public final class System {
private static void setJavaLangAccess() {
// Allow privileged classes outside of java.lang
SharedSecrets.setJavaLangAccess(new JavaLangAccess() {
public Method getMethodOrNull(Class<?> klass, String name, Class<?>... parameterTypes) {
return klass.getMethodOrNull(name, parameterTypes);
public List<Method> getDeclaredPublicMethods(Class<?> klass, String name, Class<?>... parameterTypes) {
return klass.getDeclaredPublicMethods(name, parameterTypes);
}
public jdk.internal.reflect.ConstantPool getConstantPool(Class<?> klass) {
return klass.getConstantPool();
@ -2094,7 +2096,7 @@ public final class System {
return Class.getExecutableTypeAnnotationBytes(executable);
}
public <E extends Enum<E>>
E[] getEnumConstantsShared(Class<E> klass) {
E[] getEnumConstantsShared(Class<E> klass) {
return klass.getEnumConstantsShared();
}
public void blockedOn(Thread t, Interruptible b) {
@ -2122,9 +2124,6 @@ public final class System {
public Class<?> findBootstrapClassOrNull(ClassLoader cl, String name) {
return cl.findBootstrapClassOrNull(name);
}
public Stream<Package> packages(ClassLoader cl) {
return cl.packages();
}
public Package definePackage(ClassLoader cl, String name, Module module) {
return cl.definePackage(name, module);
}
@ -2163,9 +2162,18 @@ public final class System {
public void addOpensToAllUnnamed(Module m, String pn) {
m.implAddOpensToAllUnnamed(pn);
}
public void addOpensToAllUnnamed(Module m, Iterator<String> packages) {
m.implAddOpensToAllUnnamed(packages);
}
public void addUses(Module m, Class<?> service) {
m.implAddUses(service);
}
public boolean isReflectivelyExported(Module m, String pn, Module other) {
return m.isReflectivelyExported(pn, other);
}
public boolean isReflectivelyOpened(Module m, String pn, Module other) {
return m.isReflectivelyOpened(pn, other);
}
public ServicesCatalog getServicesCatalog(ModuleLayer layer) {
return layer.getServicesCatalog();
}

View File

@ -212,7 +212,7 @@ public class MethodHandles {
if (!callerModule.isNamed() && targetModule.isNamed()) {
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
if (logger != null) {
logger.logIfOpenedByBackdoor(lookup, targetClass);
logger.logIfOpenedForIllegalAccess(lookup, targetClass);
}
}
return new Lookup(targetClass);

View File

@ -110,6 +110,20 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
* boolean r = avh.compareAndSet(sa, 10, "expected", "new");
* }</pre>
*
* <p>Access modes control atomicity and consistency properties.
* <em>Plain</em> read ({@code get}) and write ({@code set})
* accesses are guaranteed to be bitwise atomic only for references
* and for primitive values of at most 32 bits, and impose no observable
* ordering constraints with respect to threads other than the
* executing thread. <em>Opaque</em> operations are bitwise atomic and
* coherently ordered with respect to accesses to the same variable.
* In addition to obeying Opaque properties, <em>Acquire</em> mode
* reads and their subsequent accesses are ordered after matching
* <em>Release</em> mode writes and their previous accesses. In
* addition to obeying Acquire and Release properties, all
* <em>Volatile</em> operations are totally ordered with respect to
* each other.
*
* <p>Access modes are grouped into the following categories:
* <ul>
* <li>read access modes that get the value of a variable under specified

View File

@ -43,11 +43,10 @@ import java.util.stream.Stream;
/**
* A configuration that is the result of <a href="package-summary.html#resolution">
* resolution</a> or resolution with <a href="package-summary.html#servicebinding">
* service binding</a>.
* resolution</a> or resolution with <a href="#service-binding">service binding</a>.
*
* <p> A configuration encapsulates the <em>readability graph</em> that is the
* output of resolution. A readability graph is a directed graph where the nodes
* output of resolution. A readability graph is a directed graph whose vertices
* are of type {@link ResolvedModule} and the edges represent the readability
* amongst the modules. {@code Configuration} defines the {@link #modules()
* modules()} method to get the set of resolved modules in the graph. {@code
@ -176,8 +175,8 @@ public final class Configuration {
* If resolution fails for any of the observability-related reasons
* specified by the static {@code resolve} method
* @throws ResolutionException
* If any of the post-resolution consistency checks specified by
* the static {@code resolve} method fail
* If resolution fails any of the consistency checks specified by
* the static {@code resolve} method
* @throws SecurityException
* If locating a module is denied by the security manager
*/
@ -219,8 +218,8 @@ public final class Configuration {
* If resolution fails for any of the observability-related reasons
* specified by the static {@code resolve} method
* @throws ResolutionException
* If any of the post-resolution consistency checks specified by
* the static {@code resolve} method fail
* If resolution fails any of the consistency checks specified by
* the static {@code resolve} method
* @throws SecurityException
* If locating a module is denied by the security manager
*/
@ -234,7 +233,7 @@ public final class Configuration {
/**
* Resolves a collection of root modules, with service binding, and with
* the empty configuration as its parent. The post resolution checks
* the empty configuration as its parent. The consistency checks
* are optionally run.
*
* This method is used to create the configuration for the boot layer.
@ -264,10 +263,9 @@ public final class Configuration {
* or dependences that are located in a parent configuration are resolved
* no further and are not included in the resulting configuration. </p>
*
* <p> When all modules have been resolved then the resulting dependency
* graph is checked to ensure that it does not contain cycles. A
* readability graph is constructed, and in conjunction with the module
* exports and service use, checked for consistency. </p>
* <p> When all modules have been enumerated then a readability graph
* is computed, and in conjunction with the module exports and service use,
* checked for consistency. </p>
*
* <p> Resolution may fail with {@code FindException} for the following
* <em>observability-related</em> reasons: </p>
@ -284,8 +282,8 @@ public final class Configuration {
*
* </ul>
*
* <p> Post-resolution consistency checks may fail with {@code
* ResolutionException} for the following reasons: </p>
* <p> Resolution may fail with {@code ResolutionException} if any of the
* following consistency checks fail: </p>
*
* <ul>
*
@ -329,9 +327,11 @@ public final class Configuration {
* root modules
*
* @throws FindException
* If resolution fails for an observability-related reason
* If resolution fails for any of observability-related reasons
* specified above
* @throws ResolutionException
* If a post-resolution consistency checks fails
* If resolution fails for any of the consistency checks specified
* above
* @throws IllegalArgumentException
* If the list of parents is empty, or the list has two or more
* parents with modules for different target operating systems,
@ -368,11 +368,11 @@ public final class Configuration {
* resolve} except that the graph of resolved modules is augmented
* with modules induced by the service-use dependence relation. </p>
*
* <p> More specifically, the root modules are resolved as if by calling
* {@code resolve}. The resolved modules, and all modules in the
* parent configurations, with {@link ModuleDescriptor#uses() service
* dependences} are then examined. All modules found by the given module
* finders that {@link ModuleDescriptor#provides() provide} an
* <p id="service-binding"> More specifically, the root modules are
* resolved as if by calling {@code resolve}. The resolved modules, and
* all modules in the parent configurations, with {@link ModuleDescriptor#uses()
* service dependences} are then examined. All modules found by the given
* module finders that {@link ModuleDescriptor#provides() provide} an
* implementation of one or more of the service types are added to the
* module graph and then resolved as if by calling the {@code
* resolve} method. Adding modules to the module graph may introduce new
@ -402,8 +402,8 @@ public final class Configuration {
* If resolution fails for any of the observability-related reasons
* specified by the static {@code resolve} method
* @throws ResolutionException
* If any of the post-resolution consistency checks specified by
* the static {@code resolve} method fail
* If resolution fails any of the consistency checks specified by
* the static {@code resolve} method
* @throws IllegalArgumentException
* If the list of parents is empty, or the list has two or more
* parents with modules for different target operating systems,

View File

@ -48,7 +48,7 @@ import jdk.internal.module.SystemModuleFinder;
/**
* A finder of modules. A {@code ModuleFinder} is used to find modules during
* <a href="package-summary.html#resolution">resolution</a> or
* <a href="package-summary.html#servicebinding">service binding</a>.
* <a href="Configuration.html#service-binding">service binding</a>.
*
* <p> A {@code ModuleFinder} can only find one module with a given name. A
* {@code ModuleFinder} that finds modules in a sequence of directories, for
@ -239,30 +239,35 @@ public interface ModuleFinder {
*
* <ul>
*
* <li><p> The module {@link ModuleDescriptor#name() name}, and {@link
* ModuleDescriptor#version() version} if applicable, is derived from
* the file name of the JAR file as follows: </p>
* <li><p> If the JAR file has the attribute "{@code Automatic-Module-Name}"
* in its main manifest then its value is the {@linkplain
* ModuleDescriptor#name() module name}. The module name is otherwise
* derived from the name of the JAR file. </p></li>
*
* <li><p> The {@link ModuleDescriptor#version() version}, and the
* module name when the attribute "{@code Automatic-Module-Name}" is not
* present, are derived from the file name of the JAR file as follows: </p>
*
* <ul>
*
* <li><p> The {@code .jar} suffix is removed. </p></li>
* <li><p> The "{@code .jar}" suffix is removed. </p></li>
*
* <li><p> If the name matches the regular expression {@code
* "-(\\d+(\\.|$))"} then the module name will be derived from the
* subsequence preceding the hyphen of the first occurrence. The
* subsequence after the hyphen is parsed as a {@link
* ModuleDescriptor.Version} and ignored if it cannot be parsed as
* a {@code Version}. </p></li>
* ModuleDescriptor.Version Version} and ignored if it cannot be
* parsed as a {@code Version}. </p></li>
*
* <li><p> All non-alphanumeric characters ({@code [^A-Za-z0-9]})
* in the module name are replaced with a dot ({@code "."}), all
* repeating dots are replaced with one dot, and all leading and
* trailing dots are removed. </p></li>
*
* <li><p> As an example, a JAR file named {@code foo-bar.jar} will
* derive a module name {@code foo.bar} and no version. A JAR file
* named {@code foo-bar-1.2.3-SNAPSHOT.jar} will derive a module
* name {@code foo.bar} and {@code 1.2.3-SNAPSHOT} as the version.
* <li><p> As an example, a JAR file named "{@code foo-bar.jar}" will
* derive a module name "{@code foo.bar}" and no version. A JAR file
* named "{@code foo-bar-1.2.3-SNAPSHOT.jar}" will derive a module
* name "{@code foo.bar}" and "{@code 1.2.3-SNAPSHOT}" as the version.
* </p></li>
*
* </ul></li>
@ -295,11 +300,12 @@ public interface ModuleFinder {
* <p> If a {@code ModuleDescriptor} cannot be created (by means of the
* {@link ModuleDescriptor.Builder ModuleDescriptor.Builder} API) for an
* automatic module then {@code FindException} is thrown. This can arise
* when a legal module name cannot be derived from the file name of the JAR
* file, where the JAR file contains a {@code .class} in the top-level
* directory of the JAR file, where an entry in a service configuration
* file is not a legal class name or its package name is not in the set of
* packages derived for the module. </p>
* when the value of the "{@code Automatic-Module-Name}" attribute is not a
* legal module name, a legal module name cannot be derived from the file
* name of the JAR file, where the JAR file contains a {@code .class} in
* the top-level directory of the JAR file, where an entry in a service
* configuration file is not a legal class name or its package name is not
* in the set of packages derived for the module. </p>
*
* <p> In addition to JAR files, an implementation may also support modules
* that are packaged in other implementation specific module formats. If

View File

@ -27,118 +27,185 @@
* Classes to support module descriptors and creating configurations of modules
* by means of resolution and service binding.
*
* <h2><a id="resolution">Resolution</a></h2>
*
* <p> Resolution is the process of computing the transitive closure of a set
* of root modules over a set of observable modules by resolving the
* dependences expressed by {@link
* java.lang.module.ModuleDescriptor.Requires requires} clauses.
* The <em>dependence graph</em> is augmented with edges that take account of
* implicitly declared dependences ({@code requires transitive}) to create a
* <em>readability graph</em>. The result of resolution is a {@link
* java.lang.module.Configuration Configuration} that encapsulates the
* readability graph. </p>
*
* <p> As an example, suppose we have the following observable modules: </p>
* <pre> {@code
* module m1 { requires m2; }
* module m2 { requires transitive m3; }
* module m3 { }
* module m4 { }
* } </pre>
*
* <p> If the module {@code m1} is resolved then the resulting configuration
* contains three modules ({@code m1}, {@code m2}, {@code m3}). The edges in
* its readability graph are: </p>
* <pre> {@code
* m1 --> m2 (meaning m1 reads m2)
* m1 --> m3
* m2 --> m3
* } </pre>
*
* <p> Resolution is an additive process. When computing the transitive closure
* then the dependence relation may include dependences on modules in {@link
* java.lang.module.Configuration#parents() parent} configurations. The result
* is a <em>relative configuration</em> that is relative to one or more parent
* configurations and where the readability graph may have edges from modules
* in the configuration to modules in parent configurations. </p>
*
* <p> As an example, suppose we have the following observable modules: </p>
* <pre> {@code
* module m1 { requires m2; requires java.xml; }
* module m2 { }
* } </pre>
*
* <p> If module {@code m1} is resolved with the configuration for the {@link
* java.lang.ModuleLayer#boot() boot} layer as the parent then the resulting
* configuration contains two modules ({@code m1}, {@code m2}). The edges in
* its readability graph are:
* <pre> {@code
* m1 --> m2
* m1 --> java.xml
* } </pre>
* where module {@code java.xml} is in the parent configuration. For
* simplicity, this example omits the implicitly declared dependence on the
* {@code java.base} module.
*
* <p> Requires clauses that are "{@code requires static}" express an optional
* dependence (except at compile-time). If a module declares that it
* "{@code requires static M}" then resolution does not search the observable
* modules for "{@code M}". However, if "{@code M}" is resolved (because resolution
* resolves a module that requires "{@code M}" without the {@link
* java.lang.module.ModuleDescriptor.Requires.Modifier#STATIC static} modifier)
* then the readability graph will contain read edges for each module that
* "{@code requires static M}". </p>
*
* <p> {@link java.lang.module.ModuleDescriptor#isAutomatic() Automatic} modules
* receive special treatment during resolution. Each automatic module is resolved
* as if it "{@code requires transitive}" all observable automatic modules and
* all automatic modules in the parent configurations. Each automatic module is
* resolved so that it reads all other modules in the resulting configuration and
* all modules in parent configurations. </p>
*
* <h2><a id="servicebinding">Service binding</a></h2>
*
* <p> Service binding is the process of augmenting a graph of resolved modules
* from the set of observable modules induced by the service-use dependence
* ({@code uses} and {@code provides} clauses). Any module that was not
* previously in the graph requires resolution to compute its transitive
* closure. Service binding is an iterative process in that adding a module
* that satisfies some service-use dependence may introduce new service-use
* dependences. </p>
*
* <p> Suppose we have the following observable modules: </p>
* <pre> {@code
* module m1 { exports p; uses p.S; }
* module m2 { requires m1; provides p.S with p2.S2; }
* module m3 { requires m1; requires m4; provides p.S with p3.S3; }
* module m4 { }
* } </pre>
*
* <p> If the module {@code m1} is resolved then the resulting graph of modules
* has one module ({@code m1}). If the graph is augmented with modules induced
* by the service-use dependence relation then the configuration will contain
* four modules ({@code m1}, {@code m2}, {@code m3}, {@code m4}). The edges in
* its readability graph are: </p>
* <pre> {@code
* m2 --> m1
* m3 --> m1
* m3 --> m4
* } </pre>
* <p> The edges in the conceptual service-use graph are: </p>
* <pre> {@code
* m1 --> m2 (meaning m1 uses a service that is provided by m2)
* m1 --> m3
* } </pre>
*
* <h2>General Exceptions</h2>
*
* <p> Unless otherwise noted, passing a {@code null} argument to a constructor
* or method of any class or interface in this package will cause a {@link
* java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
* invoking a method with an array or collection containing a {@code null} element
* will cause a {@code NullPointerException}, unless otherwise specified. </p>
*
*
* <h1><a id="resolution">Resolution</a></h1>
*
* <p> Resolution is the process of computing how modules depend on each other.
* The process occurs at compile time and run time. </p>
*
* <p> Resolution is a two-step process. The first step recursively enumerates
* the 'requires' directives of a set of root modules. If all the enumerated
* modules are observable, then the second step computes their readability graph.
* The readability graph embodies how modules depend on each other, which in
* turn controls access across module boundaries. </p>
*
* <h2> Step 1: Recursive enumeration </h2>
*
* <p> Recursive enumeration takes a set of module names, looks up each of their
* module declarations, and for each module declaration, recursively enumerates:
*
* <ul>
* <li> <p> the module names given by the 'requires' directives with the
* 'transitive' modifier, and </p></li>
* <li> <p> at the discretion of the host system, the module names given by
* the 'requires' directives without the 'transitive' modifier. </p></li>
* </ul>
*
* <p> Module declarations are looked up in a set of observable modules. The set
* of observable modules is determined in an implementation specific manner. The
* set of observable modules may include modules with explicit declarations
* (that is, with a {@code module-info.java} source file or {@code module-info.class}
* file) and modules with implicit declarations (that is,
* <a href="ModuleFinder.html#automatic-modules">automatic modules</a>).
* Because an automatic module has no explicit module declaration, it has no
* 'requires' directives of its own, although its name may be given by a
* 'requires' directive of an explicit module declaration. </p>
* <p> The set of root modules, whose names are the initial input to this
* algorithm, is determined in an implementation specific manner. The set of
* root modules may include automatic modules. </p>
*
* <p> If at least one automatic module is enumerated by this algorithm, then
* every observable automatic module must be enumerated, regardless of whether
* any of their names are given by 'requires' directives of explicit module
* declarations. </p>
*
* <p> If any of the following conditions occur, then resolution fails:
* <ul>
* <li><p> Any root module is not observable. </p></li>
* <li><p> Any module whose name is given by a 'requires' directive with the
* 'transitive' modifier is not observable. </p></li>
* <li><p> At the discretion of the host system, any module whose name is given
* by a 'requires' directive without the 'transitive' modifier is not
* observable. </p></li>
* <li><p> The algorithm in this step enumerates the same module name twice. This
* indicates a cycle in the 'requires' directives, disregarding any 'transitive'
* modifiers. </p></li>
* </ul>
*
* <p> Otherwise, resolution proceeds to step 2. </p>
*
* <h2> Step 2: Computing the readability graph </h2>
*
* <p> A 'requires' directive (irrespective of 'transitive') expresses that
* one module depends on some other module. The effect of the 'transitive'
* modifier is to cause additional modules to also depend on the other module.
* If module M 'requires transitive N', then not only does M depend on N, but
* any module that depends on M also depends on N. This allows M to be
* refactored so that some or all of its content can be moved to a new module N
* without breaking modules that have a 'requires M' directive. </p>
*
* <p> Module dependencies are represented by the readability graph. The
* readability graph is a directed graph whose vertices are the modules
* enumerated in step 1 and whose edges represent readability between pairs of
* modules. The edges are specified as follows:
*
* <p> First, readability is determined by the 'requires' directives of the
* enumerated modules, disregarding any 'transitive' modifiers:
*
* <ul>
* <li><p> For each enumerated module A that 'requires' B: A "reads" B. </p></li>
* <li><p> For each enumerated module X that is automatic: X "reads" every
* other enumerated module (it is "as if" an automatic module has 'requires'
* directives for every other enumerated module). </p></li>
* </ul>
*
* <p> Second, readability is augmented to account for 'transitive' modifiers:
* <ul>
* <li> <p> For each enumerated module A that "reads" B: </p>
* <ul>
* <li><p> If B 'requires transitive' C, then A "reads" C as well as B. This
* augmentation is recursive: since A "reads" C, if C 'requires transitive'
* D, then A "reads" D as well as C and B. </p></li>
* <li><p> If B is an automatic module, then A "reads" every other enumerated
* automatic module. (It is "as if" an automatic module has 'requires transitive'
* directives for every other enumerated automatic module).</p> </li>
* </ul>
* </li>
* </ul>
*
* <p> Finally, every module "reads" itself. </p>
*
* <p> If any of the following conditions occur in the readability graph, then
* resolution fails:
* <ul>
* <li><p> A module "reads" two or more modules with the same name. This includes
* the case where a module "reads" another with the same name as itself. </p></li>
* <li><p> Two or more modules export a package with the same name to a module
* that "reads" both. This includes the case where a module M containing package
* p "reads" another module that exports p to M. </p></li>
* <li><p> A module M declares that it 'uses p.S' or 'provides p.S with ...' but
* package p is neither in module M nor exported to M by any module that M
* "reads". </p></li>
* </ul>
* <p> Otherwise, resolution succeeds, and the result of resolution is the
* readability graph.
*
* <h2> Root modules </h2>
*
* <p> The set of root modules at compile-time is usually the set of modules
* being compiled. At run-time, the set of root modules is usually the
* application module specified to the 'java' launcher. When compiling code in
* the unnamed module, or at run-time when the main application class is loaded
* from the class path, then the default set of root modules is implementation
* specific (In the JDK implementation it is the module "java.se", if observable,
* and every observable module that exports an API). </p>
*
* <h2> Observable modules </h2>
*
* <p> The set of observable modules at both compile-time and run-time is
* determined by searching several different paths, and also by searching
* the compiled modules built in to the environment. The search order is as
* follows: </p>
*
* <ol>
* <li><p> At compile time only, the compilation module path. This path
* contains module definitions in source form. </p></li>
*
* <li><p> The upgrade module path. This path contains compiled definitions of
* modules that will be observed in preference to the compiled definitions of
* any <i>upgradeable modules</i> that are present in (3) and (4). See the Java
* SE Platform for the designation of which standard modules are upgradeable.
* </p></li>
*
* <li><p> The system modules, which are the compiled definitions built in to
* the environment. </p></li>
*
* <li><p> The application module path. This path contains compiled definitions
* of library and application modules. </p></li>
*
* </ol>
*
* <h2> 'requires' directives with 'static' modifier </h2>
*
* <p> 'requires' directives that have the 'static' modifier express an optional
* dependence at run time. If a module declares that it 'requires static M' then
* resolution does not search the observable modules for M to satisfy the dependency.
* However, if M is recursively enumerated at step 1 then all modules that are
* enumerated and `requires static M` will read M. </p>
*
* <h2> Completeness </h2>
*
* <p> Resolution may be partial at compile-time in that the complete transitive
* closure may not be required to compile a set of modules. Minimally, the
* readability graph that is constructed and validated at compile-time includes
* the modules being compiled, their direct dependences, and all implicitly
* declared dependences (requires transitive). </p>
*
* <p> At run-time, resolution is an additive process. The recursive enumeration
* at step 1 may be relative to previous resolutions so that a root module,
* or a module named in a 'requires' directive, is not enumerated when it was
* enumerated by a previous (or parent) resolution. The readability graph that
* is the result of resolution may therefore have a vertex for a module enumerated
* in step 1 but with an edge to represent that the module reads a module that
* was enumerated by previous (or parent) resolution. </p>
*
* @since 9
* @spec JPMS
*/

View File

@ -304,7 +304,7 @@ public class AccessibleObject implements AnnotatedElement {
if (isClassPublic && declaringModule.isExported(pn, callerModule)) {
// member is public
if (Modifier.isPublic(modifiers)) {
logIfExportedByBackdoor(caller, declaringClass);
logIfExportedForIllegalAccess(caller, declaringClass);
return true;
}
@ -312,14 +312,14 @@ public class AccessibleObject implements AnnotatedElement {
if (Modifier.isProtected(modifiers)
&& Modifier.isStatic(modifiers)
&& isSubclassOf(caller, declaringClass)) {
logIfExportedByBackdoor(caller, declaringClass);
logIfExportedForIllegalAccess(caller, declaringClass);
return true;
}
}
// package is open to caller
if (declaringModule.isOpen(pn, callerModule)) {
logIfOpenedByBackdoor(caller, declaringClass);
logIfOpenedForIllegalAccess(caller, declaringClass);
return true;
}
@ -353,26 +353,26 @@ public class AccessibleObject implements AnnotatedElement {
return false;
}
private void logIfOpenedByBackdoor(Class<?> caller, Class<?> declaringClass) {
private void logIfOpenedForIllegalAccess(Class<?> caller, Class<?> declaringClass) {
Module callerModule = caller.getModule();
Module targetModule = declaringClass.getModule();
// callerModule is null during early startup
if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
if (logger != null) {
logger.logIfOpenedByBackdoor(caller, declaringClass, this::toShortString);
logger.logIfOpenedForIllegalAccess(caller, declaringClass, this::toShortString);
}
}
}
private void logIfExportedByBackdoor(Class<?> caller, Class<?> declaringClass) {
private void logIfExportedForIllegalAccess(Class<?> caller, Class<?> declaringClass) {
Module callerModule = caller.getModule();
Module targetModule = declaringClass.getModule();
// callerModule is null during early startup
if (callerModule != null && !callerModule.isNamed() && targetModule.isNamed()) {
IllegalAccessLogger logger = IllegalAccessLogger.illegalAccessLogger();
if (logger != null) {
logger.logIfExportedByBackdoor(caller, declaringClass, this::toShortString);
logger.logIfExportedForIllegalAccess(caller, declaringClass, this::toShortString);
}
}
}
@ -634,7 +634,7 @@ public class AccessibleObject implements AnnotatedElement {
}
// access okay
logIfExportedByBackdoor(caller, memberClass);
logIfExportedForIllegalAccess(caller, memberClass);
// Success: Update the cache.
Object cache = (targetClass != null

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, 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
@ -36,4 +36,21 @@ package java.lang.reflect;
*/
public class MalformedParameterizedTypeException extends RuntimeException {
private static final long serialVersionUID = -5696557788586220964L;
/**
* Constructs a {@code MalformedParameterizedTypeException} with
* no detail message.
*/
public MalformedParameterizedTypeException() {
super();
}
/**
* Constructs a {@code MalformedParameterizedTypeException} with
* the given detail message.
* @param message the detail message; may be {@code null}
*/
public MalformedParameterizedTypeException(String message) {
super(message);
}
}

View File

@ -64,8 +64,7 @@ import java.util.Objects;
* AlgorithmParameterGenerator (via a call to an {@code init} method),
* each provider must supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
* JDK Providers</a>
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the AlgorithmParameterGenerator defaults
* used by JDK providers.
* However, note that defaults may vary across different providers.

View File

@ -40,8 +40,7 @@ import java.security.spec.AlgorithmParameterSpec;
* AlgorithmParameterGenerator (via a call to an {@code engineInit}
* method), each provider must supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
* JDK Providers</a>
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the AlgorithmParameterGenerator defaults
* used by JDK providers.
* However, note that defaults may vary across different providers.

View File

@ -114,10 +114,10 @@ public interface Key extends java.io.Serializable {
/**
* Returns the standard algorithm name for this key. For
* example, "DSA" would indicate that this key is a DSA key.
* See Appendix A in the <a href=
* "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture API Specification &amp; Reference </a>
* for information about standard algorithm names.
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for more information.
*
* @return the name of the algorithm associated with this key.
*/

View File

@ -96,8 +96,7 @@ import sun.security.util.Debug;
* (via a call to an {@code initialize} method), each provider must
* supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
* JDK Providers</a>
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the KeyPairGenerator defaults used by
* JDK providers.
* However, note that defaults may vary across different providers.

View File

@ -40,8 +40,7 @@ import java.security.spec.AlgorithmParameterSpec;
* (via a call to an {@code initialize} method), each provider must
* supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
* JDK Providers</a>
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the KeyPairGenerator defaults used by
* JDK providers.
* However, note that defaults may vary across different providers.

View File

@ -94,9 +94,9 @@ import java.util.function.Function;
* The JDK implementation supports static registration of the security
* providers via the {@code conf/security/java.security} file in the Java
* installation directory. These providers are automatically installed by
* the JDK runtime, see <a href =
* "../../../technotes/guides/security/crypto/CryptoSpec.html#Provider">The Provider Class</a>
* in the "Java Cryptography Architecture API Specification &amp; Reference"
* the JDK runtime, see {@extLink security_guide_jca_provider
* The Provider Class}
* in the Java Cryptography Architecture (JCA) Reference Guide
* for information about how a particular type of provider, the cryptographic
* service provider, works and is installed.
*
@ -1310,8 +1310,8 @@ public abstract class Provider extends Properties {
* it is replaced by the new service.
* This method also places information about this service
* in the provider's Hashtable values in the format described in the
* <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">
* Java Cryptography Architecture API Specification &amp; Reference </a>.
* {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}.
*
* <p>Also, if there is a security manager, its
* {@code checkSecurityAccess} method is called with the string
@ -1593,8 +1593,8 @@ public abstract class Provider extends Properties {
* suitable services and instantiates them. The valid arguments to those
* methods depend on the type of service. For the service types defined
* within Java SE, see the
* <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">
* Java Cryptography Architecture API Specification &amp; Reference </a>
* {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}
* for the valid values.
* Note that components outside of Java SE can define additional types of
* services and their behavior.
@ -1769,9 +1769,8 @@ public abstract class Provider extends Properties {
* instantiation in a different way.
* For details and the values of constructorParameter that are
* valid for the various types of services see the
* <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">
* Java Cryptography Architecture API Specification &amp;
* Reference</a>.
* {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}.
*
* @param constructorParameter the value to pass to the constructor,
* or null if this type of service does not use a constructorParameter.
@ -1878,9 +1877,8 @@ public abstract class Provider extends Properties {
*
* <p>For details and the values of parameter that are valid for the
* various types of services see the top of this class and the
* <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">
* Java Cryptography Architecture API Specification &amp;
* Reference</a>.
* {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}.
* Security providers can override it to implement their own test.
*
* @param parameter the parameter to test

View File

@ -1041,8 +1041,8 @@ public final class Security {
* an empty Set if there is no provider that supports the
* specified service or if serviceName is null. For a complete list
* of Java cryptographic services, please see the
* <a href="../../../technotes/guides/security/crypto/CryptoSpec.html">Java
* Cryptography Architecture API Specification &amp; Reference</a>.
* {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}.
* Note: the returned set is immutable.
*
* @param serviceName the name of the Java cryptographic

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2017, 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
@ -52,9 +52,9 @@ public abstract class CRL {
* Creates a CRL of the specified type.
*
* @param type the standard name of the CRL type.
* See Appendix A in the <a href=
* "../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture API Specification &amp; Reference </a>
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard CRL types.
*/
protected CRL(String type) {

View File

@ -32,15 +32,14 @@
* <h2>Package Specification</h2>
*
* <ul>
* <li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
* <b>Java&trade;
* Cryptography Architecture (JCA) Reference Guide</b></a>
* <li>{@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}
* <li>RFC 5280: Internet X.509 Public Key Infrastructure Certificate and
* Certificate Revocation List (CRL) Profile
* <li>RFC 2560: X.509 Internet Public Key Infrastructure Online Certificate
* Status Protocol - OCSP
* <li><a href="{@docRoot}/../specs/security/standard-names.html">
* <b>Java&trade; Security Standard Algorithm Names Specification
* <b>Java Security Standard Algorithm Names Specification
* </b></a></li>
* </ul>
*
@ -50,12 +49,7 @@
* <ul>
* <li><a href="http://www.ietf.org/rfc/rfc5280.txt">
* http://www.ietf.org/rfc/rfc5280.txt</a>
* <li><a href=
* "{@docRoot}/../technotes/guides/security/certpath/CertPathProgGuide.html">
* <b>Java&trade;
* PKI Programmer's Guide</b></a>
* <li><a href="{@docRoot}/../technotes/guides/security/cert3.html">
* <b>X.509 Certificates and Certificate Revocation Lists (CRLs)</b></a>
* <li> {@extLink security_guide_pki Java PKI Programmer's Guide}
* </ul>
*
* @since 1.2

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2017, 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
@ -42,11 +42,10 @@
* {@code Key} classes for hardware devices, please refer
* to these cryptographic provider developer guides:
* <ul>
* <li><a href=
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
* <b>How to Implement a Provider for the
* Java&trade; Cryptography Architecture
* </b></a></li>
* <li>
* {@extLink security_guide_impl_provider
* How to Implement a Provider in the Java Cryptography Architecture}
* </li>
* </ul>
*
* <h2>Package Specification</h2>
@ -61,12 +60,8 @@
*
* For further documentation, please see:
* <ul>
* <li>
* <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
* <b>Java&trade;
* Cryptography Architecture API Specification and Reference
* </b></a></li>
* <li> {extLink security_guide_jca
* Java Cryptography Architecture Reference Guide}</li>
* </ul>
*
* @since 1.1

View File

@ -46,63 +46,36 @@
* <h2>Package Specification</h2>
*
* <ul>
* <li><a href="{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
* <b>Java&trade;
* Cryptography Architecture (JCA) Reference Guide</b></a></li>
* <li> {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}</li>
*
* <li>PKCS #8: Private-Key Information Syntax Standard, Version 1.2,
* November 1993</li>
*
* <li><a href="{@docRoot}/../specs/security/standard-names.html">
* <b>Java&trade; Security Standard Algorithm Names Specification
* </b></a></li>
* Java Security Standard Algorithm Names Specification
* </a></li>
* </ul>
*
* <h2>Related Documentation</h2>
*
* For further documentation, please see:
* <ul>
* <li><a href=
* "{@docRoot}/../technotes/guides/security/spec/security-spec.doc.html">
* <b>Java&trade;
* SE Platform Security Architecture</b></a></li>
* <li> {@extLink security_guide_overview
* Java Security Overview} </li>
*
* <li><a href=
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
* <b>How to Implement a Provider in the
* Java&trade; Cryptography Architecture
* </b></a></li>
* <li> {@extLink security_guide_impl_provider
* How to Implement a Provider in the Java Cryptography Architecture}</li>
*
* <li><a href=
* "{@docRoot}/../technotes/guides/security/PolicyFiles.html"><b>
* Default Policy Implementation and Policy File Syntax
* </b></a></li>
* <li> {@extLink security_guide_default_policy
* Default Policy Implementation and Policy File Syntax}</li>
*
* <li><a href=
* "{@docRoot}/../technotes/guides/security/permissions.html"><b>
* Permissions in the
* Java&trade; SE Development Kit (JDK)
* </b></a></li>
* <li> {@extLink security_guide_permissions
* Permissions in the Java Development Kit (JDK)}</li>
*
* <li><a href=
* "{@docRoot}/../technotes/guides/security/SecurityToolsSummary.html"><b>
* Summary of Tools for
* Java&trade; Platform Security
* </b></a></li>
*
* <li><b>keytool</b>
* (<a href="{@docRoot}/../technotes/tools/unix/keytool.html">
* for Solaris/Linux</a>)
* (<a href="{@docRoot}/../technotes/tools/windows/keytool.html">
* for Windows</a>)
* </li>
*
* <li><b>jarsigner</b>
* (<a href="{@docRoot}/../technotes/tools/unix/jarsigner.html">
* for Solaris/Linux</a>)
* (<a href="{@docRoot}/../technotes/tools/windows/jarsigner.html">
* for Windows</a>)
* </li>
* <li> {@extLink security_guide_tools
* Summary of Tools for Java Platform Security}
* (for example {@code keytool} and {@code jarsigner}),</li>
*
* </ul>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2017, 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
@ -54,18 +54,10 @@
* For documentation that includes information about algorithm parameter
* and key specifications, please see:
* <ul>
* <li>
* <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
* <b>Java&trade;
* Cryptography Architecture API Specification and Reference
* </b></a></li>
* <li>
* <a href=
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
* <b>How to Implement a Provider for the
* Java&trade; Cryptography Architecture
* </b></a></li>
* <li> {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}</li>
* <li> {@extLink security_guide_impl_provider
* How to Implement a Provider in the Java Cryptography Architecture}</li>
* </ul>
*
* @since 1.2

View File

@ -72,24 +72,24 @@ package java.util;
* </tr>
* <tr>
* <td><b>Insert</b></td>
* <td>{@link Deque#addFirst addFirst(e)}</td>
* <td>{@link Deque#offerFirst offerFirst(e)}</td>
* <td>{@link Deque#addLast addLast(e)}</td>
* <td>{@link Deque#offerLast offerLast(e)}</td>
* <td>{@link #addFirst(Object) addFirst(e)}</td>
* <td>{@link #offerFirst(Object) offerFirst(e)}</td>
* <td>{@link #addLast(Object) addLast(e)}</td>
* <td>{@link #offerLast(Object) offerLast(e)}</td>
* </tr>
* <tr>
* <td><b>Remove</b></td>
* <td>{@link Deque#removeFirst removeFirst()}</td>
* <td>{@link Deque#pollFirst pollFirst()}</td>
* <td>{@link Deque#removeLast removeLast()}</td>
* <td>{@link Deque#pollLast pollLast()}</td>
* <td>{@link #removeFirst() removeFirst()}</td>
* <td>{@link #pollFirst() pollFirst()}</td>
* <td>{@link #removeLast() removeLast()}</td>
* <td>{@link #pollLast() pollLast()}</td>
* </tr>
* <tr>
* <td><b>Examine</b></td>
* <td>{@link Deque#getFirst getFirst()}</td>
* <td>{@link Deque#peekFirst peekFirst()}</td>
* <td>{@link Deque#getLast getLast()}</td>
* <td>{@link Deque#peekLast peekLast()}</td>
* <td>{@link #getFirst() getFirst()}</td>
* <td>{@link #peekFirst() peekFirst()}</td>
* <td>{@link #getLast() getLast()}</td>
* <td>{@link #peekLast() peekLast()}</td>
* </tr>
* </table>
*
@ -106,28 +106,28 @@ package java.util;
* <td style="text-align:center"> <b>Equivalent {@code Deque} Method</b></td>
* </tr>
* <tr>
* <td>{@link java.util.Queue#add add(e)}</td>
* <td>{@link #addLast addLast(e)}</td>
* <td>{@link #add(Object) add(e)}</td>
* <td>{@link #addLast(Object) addLast(e)}</td>
* </tr>
* <tr>
* <td>{@link java.util.Queue#offer offer(e)}</td>
* <td>{@link #offerLast offerLast(e)}</td>
* <td>{@link #offer(Object) offer(e)}</td>
* <td>{@link #offerLast(Object) offerLast(e)}</td>
* </tr>
* <tr>
* <td>{@link java.util.Queue#remove remove()}</td>
* <td>{@link #removeFirst removeFirst()}</td>
* <td>{@link #remove() remove()}</td>
* <td>{@link #removeFirst() removeFirst()}</td>
* </tr>
* <tr>
* <td>{@link java.util.Queue#poll poll()}</td>
* <td>{@link #pollFirst pollFirst()}</td>
* <td>{@link #poll() poll()}</td>
* <td>{@link #pollFirst() pollFirst()}</td>
* </tr>
* <tr>
* <td>{@link java.util.Queue#element element()}</td>
* <td>{@link #getFirst getFirst()}</td>
* <td>{@link #element() element()}</td>
* <td>{@link #getFirst() getFirst()}</td>
* </tr>
* <tr>
* <td>{@link java.util.Queue#peek peek()}</td>
* <td>{@link #peek peekFirst()}</td>
* <td>{@link #peek() peek()}</td>
* <td>{@link #peekFirst() peekFirst()}</td>
* </tr>
* </table>
*
@ -144,16 +144,16 @@ package java.util;
* <td style="text-align:center"> <b>Equivalent {@code Deque} Method</b></td>
* </tr>
* <tr>
* <td>{@link #push push(e)}</td>
* <td>{@link #addFirst addFirst(e)}</td>
* <td>{@link #push(Object) push(e)}</td>
* <td>{@link #addFirst(Object) addFirst(e)}</td>
* </tr>
* <tr>
* <td>{@link #pop pop()}</td>
* <td>{@link #removeFirst removeFirst()}</td>
* <td>{@link #pop() pop()}</td>
* <td>{@link #removeFirst() removeFirst()}</td>
* </tr>
* <tr>
* <td>{@link #peek peek()}</td>
* <td>{@link #peekFirst peekFirst()}</td>
* <td>{@link #peek() peek()}</td>
* <td>{@link #peekFirst() peekFirst()}</td>
* </tr>
* </table>
*
@ -430,8 +430,8 @@ public interface Deque<E> extends Queue<E> {
/**
* Retrieves and removes the head of the queue represented by this deque
* (in other words, the first element of this deque).
* This method differs from {@link #poll poll} only in that it throws an
* exception if this deque is empty.
* This method differs from {@link #poll() poll()} only in that it
* throws an exception if this deque is empty.
*
* <p>This method is equivalent to {@link #removeFirst()}.
*
@ -477,6 +477,31 @@ public interface Deque<E> extends Queue<E> {
*/
E peek();
/**
* Adds all of the elements in the specified collection at the end
* of this deque, as if by calling {@link #addLast} on each one,
* in the order that they are returned by the collection's iterator.
*
* <p>When using a capacity-restricted deque, it is generally preferable
* to call {@link #offer(Object) offer} separately on each element.
*
* <p>An exception encountered while trying to add an element may result
* in only some of the elements having been successfully added when
* the associated exception is thrown.
*
* @param c the elements to be inserted into this deque
* @return {@code true} if this deque changed as a result of the call
* @throws IllegalStateException if not all the elements can be added at
* this time due to insertion restrictions
* @throws ClassCastException if the class of an element of the specified
* collection prevents it from being added to this deque
* @throws NullPointerException if the specified collection contains a
* null element and this deque does not permit null elements,
* or if the specified collection is null
* @throws IllegalArgumentException if some property of an element of the
* specified collection prevents it from being added to this deque
*/
boolean addAll(Collection<? extends E> c);
// *** Stack methods ***

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2017, 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
@ -27,33 +27,12 @@ package java.util;
/**
* Error thrown when something goes wrong while loading a service provider.
*
* <p> This error will be thrown in the following situations:
*
* <ul>
*
* <li> The format of a provider-configuration file violates the <a
* href="ServiceLoader.html#format">specification</a>; </li>
*
* <li> An {@link java.io.IOException IOException} occurs while reading a
* provider-configuration file; </li>
*
* <li> A concrete provider class named in a provider-configuration file
* cannot be found; </li>
*
* <li> A concrete provider class is not a subclass of the service class;
* </li>
*
* <li> A concrete provider class cannot be instantiated; or
*
* <li> Some other kind of error occurs. </li>
*
* </ul>
*
* Error thrown when something goes wrong while locating, loading, or
* instantiating a service provider.
*
* @author Mark Reinhold
* @since 1.6
* @see ServiceLoader
*/
public class ServiceConfigurationError

File diff suppressed because it is too large Load Diff

View File

@ -249,7 +249,8 @@ public class AtomicInteger extends Number implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function, returning the previous value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
@ -270,7 +271,8 @@ public class AtomicInteger extends Number implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function, returning the updated value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
@ -291,13 +293,14 @@ public class AtomicInteger extends Number implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function to the current and given values,
* returning the previous value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function
* is applied with the current value as its first argument,
* and the given update as the second argument.
* updates fail due to contention among threads. The function is
* applied with the current value as its first argument, and the
* given update as the second argument.
*
* @param x the update value
* @param accumulatorFunction a side-effect-free function of two arguments
@ -317,13 +320,14 @@ public class AtomicInteger extends Number implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function to the current and given values,
* returning the updated value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function
* is applied with the current value as its first argument,
* and the given update as the second argument.
* updates fail due to contention among threads. The function is
* applied with the current value as its first argument, and the
* given update as the second argument.
*
* @param x the update value
* @param accumulatorFunction a side-effect-free function of two arguments

View File

@ -260,10 +260,12 @@ public class AtomicIntegerArray implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the results
* of applying the given function, returning the previous value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function, returning the
* previous value. The function should be side-effect-free, since
* it may be re-applied when attempted updates fail due to
* contention among threads.
*
* @param i the index
* @param updateFunction a side-effect-free function
@ -282,10 +284,12 @@ public class AtomicIntegerArray implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the results
* of applying the given function, returning the updated value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function, returning the
* updated value. The function should be side-effect-free, since it
* may be re-applied when attempted updates fail due to contention
* among threads.
*
* @param i the index
* @param updateFunction a side-effect-free function
@ -304,10 +308,11 @@ public class AtomicIntegerArray implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the
* results of applying the given function to the current and given
* values, returning the previous value. The function should be
* side-effect-free, since it may be re-applied when attempted
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function to the current and
* given values, returning the previous value. The function should
* be side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function is
* applied with the current value of the element at index {@code i}
* as its first argument, and the given update as the second
@ -332,10 +337,11 @@ public class AtomicIntegerArray implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the
* results of applying the given function to the current and given
* values, returning the updated value. The function should be
* side-effect-free, since it may be re-applied when attempted
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function to the current and
* given values, returning the updated value. The function should
* be side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function is
* applied with the current value of the element at index {@code i}
* as its first argument, and the given update as the second

View File

@ -46,6 +46,7 @@ import java.util.function.IntUnaryOperator;
import jdk.internal.misc.Unsafe;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import java.lang.invoke.VarHandle;
/**
* A reflection-based utility that enables atomic updates to
@ -275,10 +276,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
}
/**
* Atomically updates the field of the given object managed by this updater
* with the results of applying the given function, returning the previous
* value. The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given
* function, returning the previous value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads.
*
* @param obj An object whose field to get and set
* @param updateFunction a side-effect-free function
@ -295,10 +298,12 @@ public abstract class AtomicIntegerFieldUpdater<T> {
}
/**
* Atomically updates the field of the given object managed by this updater
* with the results of applying the given function, returning the updated
* value. The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given
* function, returning the updated value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads.
*
* @param obj An object whose field to get and set
* @param updateFunction a side-effect-free function
@ -315,13 +320,14 @@ public abstract class AtomicIntegerFieldUpdater<T> {
}
/**
* Atomically updates the field of the given object managed by this
* updater with the results of applying the given function to the
* current and given values, returning the previous value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads. The
* function is applied with the current value as its first argument,
* and the given update as the second argument.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given function
* to the current and given values, returning the previous value.
* The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among
* threads. The function is applied with the current value as its
* first argument, and the given update as the second argument.
*
* @param obj An object whose field to get and set
* @param x the update value
@ -340,13 +346,14 @@ public abstract class AtomicIntegerFieldUpdater<T> {
}
/**
* Atomically updates the field of the given object managed by this
* updater with the results of applying the given function to the
* current and given values, returning the updated value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads. The
* function is applied with the current value as its first argument,
* and the given update as the second argument.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given function
* to the current and given values, returning the updated value.
* The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among
* threads. The function is applied with the current value as its
* first argument, and the given update as the second argument.
*
* @param obj An object whose field to get and set
* @param x the update value

View File

@ -118,8 +118,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* @param newValue the new value
*/
public final void set(long newValue) {
// Use putLongVolatile instead of ordinary volatile store when
// using compareAndSetLong, for sake of some 32bit systems.
// See JDK-8180620: Clarify VarHandle mixed-access subtleties
U.putLongVolatile(this, VALUE, newValue);
}
@ -265,7 +264,8 @@ public class AtomicLong extends Number implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function, returning the previous value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
@ -286,7 +286,8 @@ public class AtomicLong extends Number implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function, returning the updated value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
@ -307,13 +308,14 @@ public class AtomicLong extends Number implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function to the current and given values,
* returning the previous value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function
* is applied with the current value as its first argument,
* and the given update as the second argument.
* updates fail due to contention among threads. The function is
* applied with the current value as its first argument, and the
* given update as the second argument.
*
* @param x the update value
* @param accumulatorFunction a side-effect-free function of two arguments
@ -333,13 +335,14 @@ public class AtomicLong extends Number implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function to the current and given values,
* returning the updated value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function
* is applied with the current value as its first argument,
* and the given update as the second argument.
* updates fail due to contention among threads. The function is
* applied with the current value as its first argument, and the
* given update as the second argument.
*
* @param x the update value
* @param accumulatorFunction a side-effect-free function of two arguments

View File

@ -260,10 +260,12 @@ public class AtomicLongArray implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the results
* of applying the given function, returning the previous value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function, returning the
* previous value. The function should be side-effect-free, since
* it may be re-applied when attempted updates fail due to
* contention among threads.
*
* @param i the index
* @param updateFunction a side-effect-free function
@ -282,10 +284,12 @@ public class AtomicLongArray implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the results
* of applying the given function, returning the updated value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function, returning the
* updated value. The function should be side-effect-free, since it
* may be re-applied when attempted updates fail due to contention
* among threads.
*
* @param i the index
* @param updateFunction a side-effect-free function
@ -304,10 +308,11 @@ public class AtomicLongArray implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the
* results of applying the given function to the current and given
* values, returning the previous value. The function should be
* side-effect-free, since it may be re-applied when attempted
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function to the current and
* given values, returning the previous value. The function should
* be side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function is
* applied with the current value of the element at index {@code i}
* as its first argument, and the given update as the second
@ -332,10 +337,11 @@ public class AtomicLongArray implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the
* results of applying the given function to the current and given
* values, returning the updated value. The function should be
* side-effect-free, since it may be re-applied when attempted
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function to the current and
* given values, returning the updated value. The function should
* be side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function is
* applied with the current value of the element at index {@code i}
* as its first argument, and the given update as the second

View File

@ -46,6 +46,7 @@ import java.util.function.LongUnaryOperator;
import jdk.internal.misc.Unsafe;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import java.lang.invoke.VarHandle;
/**
* A reflection-based utility that enables atomic updates to
@ -278,10 +279,12 @@ public abstract class AtomicLongFieldUpdater<T> {
}
/**
* Atomically updates the field of the given object managed by this updater
* with the results of applying the given function, returning the previous
* value. The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given
* function, returning the previous value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads.
*
* @param obj An object whose field to get and set
* @param updateFunction a side-effect-free function
@ -298,10 +301,12 @@ public abstract class AtomicLongFieldUpdater<T> {
}
/**
* Atomically updates the field of the given object managed by this updater
* with the results of applying the given function, returning the updated
* value. The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given
* function, returning the updated value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads.
*
* @param obj An object whose field to get and set
* @param updateFunction a side-effect-free function
@ -318,13 +323,14 @@ public abstract class AtomicLongFieldUpdater<T> {
}
/**
* Atomically updates the field of the given object managed by this
* updater with the results of applying the given function to the
* current and given values, returning the previous value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads. The
* function is applied with the current value as its first argument,
* and the given update as the second argument.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given function
* to the current and given values, returning the previous value.
* The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among
* threads. The function is applied with the current value as its
* first argument, and the given update as the second argument.
*
* @param obj An object whose field to get and set
* @param x the update value
@ -343,13 +349,14 @@ public abstract class AtomicLongFieldUpdater<T> {
}
/**
* Atomically updates the field of the given object managed by this
* updater with the results of applying the given function to the
* current and given values, returning the updated value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads. The
* function is applied with the current value as its first argument,
* and the given update as the second argument.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given function
* to the current and given values, returning the updated value.
* The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among
* threads. The function is applied with the current value as its
* first argument, and the given update as the second argument.
*
* @param obj An object whose field to get and set
* @param x the update value

View File

@ -170,7 +170,8 @@ public class AtomicReference<V> implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function, returning the previous value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
@ -191,7 +192,8 @@ public class AtomicReference<V> implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function, returning the updated value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
@ -212,13 +214,14 @@ public class AtomicReference<V> implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function to the current and given values,
* returning the previous value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function
* is applied with the current value as its first argument,
* and the given update as the second argument.
* updates fail due to contention among threads. The function is
* applied with the current value as its first argument, and the
* given update as the second argument.
*
* @param x the update value
* @param accumulatorFunction a side-effect-free function of two arguments
@ -238,13 +241,14 @@ public class AtomicReference<V> implements java.io.Serializable {
}
/**
* Atomically updates the current value with the results of
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the current value with the results of
* applying the given function to the current and given values,
* returning the updated value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function
* is applied with the current value as its first argument,
* and the given update as the second argument.
* updates fail due to contention among threads. The function is
* applied with the current value as its first argument, and the
* given update as the second argument.
*
* @param x the update value
* @param accumulatorFunction a side-effect-free function of two arguments

View File

@ -190,10 +190,12 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the results
* of applying the given function, returning the previous value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function, returning the
* previous value. The function should be side-effect-free, since
* it may be re-applied when attempted updates fail due to
* contention among threads.
*
* @param i the index
* @param updateFunction a side-effect-free function
@ -212,10 +214,12 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the results
* of applying the given function, returning the updated value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function, returning the
* updated value. The function should be side-effect-free, since it
* may be re-applied when attempted updates fail due to contention
* among threads.
*
* @param i the index
* @param updateFunction a side-effect-free function
@ -234,10 +238,11 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the
* results of applying the given function to the current and given
* values, returning the previous value. The function should be
* side-effect-free, since it may be re-applied when attempted
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function to the current and
* given values, returning the previous value. The function should
* be side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function is
* applied with the current value of the element at index {@code i}
* as its first argument, and the given update as the second
@ -262,10 +267,11 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
}
/**
* Atomically updates the element at index {@code i} with the
* results of applying the given function to the current and given
* values, returning the updated value. The function should be
* side-effect-free, since it may be re-applied when attempted
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the element at index {@code i} with
* the results of applying the given function to the current and
* given values, returning the updated value. The function should
* be side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads. The function is
* applied with the current value of the element at index {@code i}
* as its first argument, and the given update as the second

View File

@ -46,6 +46,7 @@ import java.util.function.UnaryOperator;
import jdk.internal.misc.Unsafe;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import java.lang.invoke.VarHandle;
/**
* A reflection-based utility that enables atomic updates to
@ -199,10 +200,12 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
}
/**
* Atomically updates the field of the given object managed by this updater
* with the results of applying the given function, returning the previous
* value. The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given
* function, returning the previous value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads.
*
* @param obj An object whose field to get and set
* @param updateFunction a side-effect-free function
@ -219,10 +222,12 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
}
/**
* Atomically updates the field of the given object managed by this updater
* with the results of applying the given function, returning the updated
* value. The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among threads.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given
* function, returning the updated value. The function should be
* side-effect-free, since it may be re-applied when attempted
* updates fail due to contention among threads.
*
* @param obj An object whose field to get and set
* @param updateFunction a side-effect-free function
@ -239,13 +244,14 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
}
/**
* Atomically updates the field of the given object managed by this
* updater with the results of applying the given function to the
* current and given values, returning the previous value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads. The
* function is applied with the current value as its first argument,
* and the given update as the second argument.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given function
* to the current and given values, returning the previous value.
* The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among
* threads. The function is applied with the current value as its
* first argument, and the given update as the second argument.
*
* @param obj An object whose field to get and set
* @param x the update value
@ -264,13 +270,14 @@ public abstract class AtomicReferenceFieldUpdater<T,V> {
}
/**
* Atomically updates the field of the given object managed by this
* updater with the results of applying the given function to the
* current and given values, returning the updated value. The
* function should be side-effect-free, since it may be re-applied
* when attempted updates fail due to contention among threads. The
* function is applied with the current value as its first argument,
* and the given update as the second argument.
* Atomically updates (with memory effects as specified by {@link
* VarHandle#compareAndSet}) the field of the given object managed
* by this updater with the results of applying the given function
* to the current and given values, returning the updated value.
* The function should be side-effect-free, since it may be
* re-applied when attempted updates fail due to contention among
* threads. The function is applied with the current value as its
* first argument, and the given update as the second argument.
*
* @param obj An object whose field to get and set
* @param x the update value

View File

@ -0,0 +1,399 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--
Copyright (c) 1998, 2017, 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.
-->
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
"en-US">
<head>
<title>Java Collections API Design FAQ</title>
</head>
<body>
<h2>Java Collections API Design FAQ</h2>
<!-- Body text begins here -->
<hr />
This document answers frequently asked questions concerning the
design of the Java collections framework. It is derived from the
large volume of traffic on the collections-comments alias. It
serves as a design rationale for the collections framework.
<h3>Core Interfaces - General Questions</h3>
<ol>
<li><a href="#a1"><b>Why don't you support immutability directly in
the core collection interfaces so that you can do away with
<em>optional operations</em> (and
UnsupportedOperationException)?</b></a></li>
<li><a href="#a2"><b>Won't programmers have to surround any code
that calls optional operations with a try-catch clause in case they
throw an UnsupportedOperationException?</b></a></li>
<li><a href="#a3"><b>Why isn't there a core interface for "bags"
(AKA multisets)?</b></a></li>
<li><a href="#a28"><b>Why didn't you use "Beans-style names" for
consistency?</b></a></li>
</ol>
<h3>Collection Interface</h3>
<ol>
<li><a href="#a5"><b>Why doesn't Collection extend Cloneable and
Serializable?</b></a></li>
<li><a href="#a6"><b>Why don't you provide an "apply" method in
Collection to apply a given method ("upcall") to all the elements
of the Collection?</b></a></li>
<li><a href="#a7"><b>Why didn't you provide a "Predicate" interface,
and related methods (e.g., a method to find the first element in
the Collection satisfying the predicate)?</b></a></li>
<li><a href="#a8"><b>Why don't you provide a form of the addAll
method that takes an Enumeration (or an Iterator)?</b></a></li>
<li><a href="#a9"><b>Why don't the concrete implementations in the
JDK have Enumeration (or Iterator) constructors?</b></a></li>
<li><a href="#a10"><b>Why don't you provide an Iterator.add
method?</b></a></li>
</ol>
<h3>List Interface</h3>
<ol>
<li><a href="#a11"><b>Why don't you rename the List interface to
Sequence; doesn't "list" generally suggest "linked list"? Also,
doesn't it conflict with java.awt.List?</b></a></li>
<li><a href="#a12"><b>Why don't you rename List's set method to
replace, to avoid confusion with Set.</b></a></li>
</ol>
<h3>Map Interface</h3>
<ol>
<li><a href="#a14"><b>Why doesn't Map extend
Collection?</b></a></li>
</ol>
<h3>Iterator Interface</h3>
<ol>
<li><a href="#a18"><b>Why doesn't Iterator extend
Enumeration?</b></a></li>
<li><a href="#a19"><b>Why don't you provide an Iterator.peek method
that allows you to look at the next element in an iteration without
advancing the iterator?</b></a></li>
</ol>
<h3>Miscellaneous</h3>
<ol>
<li><a href="#a23"><b>Why did you write a new collections framework
instead of adopting JGL (a preexisting collections package from
ObjectSpace, Inc.) into the JDK?</b></a></li>
<li><a href="#a26"><b>Why don't you eliminate all of the methods and
classes that return "views" (Collections backed by other
collection-like objects). This would greatly reduce
aliasing.</b></a></li>
<li><a href="#a27"><b>Why don't you provide for "observable"
collections that send out Events when they're
modified?</b></a></li>
</ol>
<hr size="3" noshade="noshade" />
<h3>Core Interfaces - General Questions</h3>
<ol>
<li><a name="a1" id="a1"><b>Why don't you support immutability
directly in the core collection interfaces so that you can do away
with <em>optional operations</em> (and
UnsupportedOperationException)?</b></a>
<p>This is the most controversial design decision in the whole API.
Clearly, static (compile time) type checking is highly desirable,
and is the norm in Java. We would have supported it if we believed
it were feasible. Unfortunately, attempts to achieve this goal
cause an explosion in the size of the interface hierarchy, and do
not succeed in eliminating the need for runtime exceptions (though
they reduce it substantially).</p>
<p>Doug Lea, who wrote a popular Java collections package that did
reflect mutability distinctions in its interface hierarchy, no
longer believes it is a viable approach, based on user experience
with his collections package. In his words (from personal
correspondence) "Much as it pains me to say it, strong static
typing does not work for collection interfaces in Java."</p>
<p>To illustrate the problem in gory detail, suppose you want to
add the notion of modifiability to the Hierarchy. You need four new
interfaces: ModifiableCollection, ModifiableSet, ModifiableList,
and ModifiableMap. What was previously a simple hierarchy is now a
messy heterarchy. Also, you need a new Iterator interface for use
with unmodifiable Collections, that does not contain the remove
operation. Now can you do away with UnsupportedOperationException?
Unfortunately not.</p>
<p>Consider arrays. They implement most of the List operations, but
not remove and add. They are "fixed-size" Lists. If you want to
capture this notion in the hierarchy, you have to add two new
interfaces: VariableSizeList and VariableSizeMap. You don't have to
add VariableSizeCollection and VariableSizeSet, because they'd be
identical to ModifiableCollection and ModifiableSet, but you might
choose to add them anyway for consistency's sake. Also, you need a
new variety of ListIterator that doesn't support the add and remove
operations, to go along with unmodifiable List. Now we're up to ten
or twelve interfaces, plus two new Iterator interfaces, instead of
our original four. Are we done? No.</p>
<p>Consider logs (such as error logs, audit logs and journals for
recoverable data objects). They are natural append-only sequences,
that support all of the List operations except for remove and set
(replace). They require a new core interface, and a new
iterator.</p>
<p>And what about immutable Collections, as opposed to unmodifiable
ones? (i.e., Collections that cannot be changed by the client AND
will never change for any other reason). Many argue that this is
the most important distinction of all, because it allows multiple
threads to access a collection concurrently without the need for
synchronization. Adding this support to the type hierarchy requires
four more interfaces.</p>
<p>Now we're up to twenty or so interfaces and five iterators, and
it's almost certain that there are still collections arising in
practice that don't fit cleanly into any of the interfaces. For
example, the <em>collection-views</em> returned by Map are natural
delete-only collections. Also, there are collections that will
reject certain elements on the basis of their value, so we still
haven't done away with runtime exceptions.</p>
<p>When all was said and done, we felt that it was a sound
engineering compromise to sidestep the whole issue by providing a
very small set of core interfaces that can throw a runtime
exception.</p>
</li>
<li><a name="a2" id="a2"><b>Won't programmers have to surround any
code that calls optional operations with a try-catch clause in case
they throw an UnsupportedOperationException?</b></a>
<p>It was never our intention that programs should catch these
exceptions: that's why they're unchecked (runtime) exceptions. They
should only arise as a result of programming errors, in which case,
your program will halt due to the uncaught exception.</p>
</li>
<li><a name="a3" id="a3"><b>Why isn't there a core interface for
"bags" (AKA multisets)?</b></a>
<p>The Collection interface provides this functionality. We are not
providing any public implementations of this interface, as we think
that it wouldn't be used frequently enough to "pull its weight." We
occasionally return such Collections, which are implemented easily
atop AbstractCollection (for example, the Collection returned by
Map.values).</p>
</li>
<li><a name="a28" id="a28"><b>Why didn't you use "Beans-style
names" for consistency?</b></a>
<p>While the names of the new collections methods do not adhere to
the "Beans naming conventions", we believe that they are
reasonable, consistent and appropriate to their purpose. It should
be remembered that the Beans naming conventions do not apply to the
JDK as a whole; the AWT did adopt these conventions, but that
decision was somewhat controversial. We suspect that the
collections APIs will be used quite pervasively, often with
multiple method calls on a single line of code, so it is important
that the names be short. Consider, for example, the Iterator
methods. Currently, a loop over a collection looks like this:</p>
<pre>
for (Iterator i = c.iterator(); i.hasNext(); )
System.out.println(i.next());
</pre>
Everything fits neatly on one line, even if the Collection name is
a long expression. If we named the methods "getIterator",
"hasNextElement" and "getNextElement", this would no longer be the
case. Thus, we adopted the "traditional" JDK style rather than the
Beans style.</li>
</ol>
<hr />
<h3>Collection Interface</h3>
<ol>
<li><a name="a5" id="a5"><b>Why doesn't Collection extend Cloneable
and Serializable?</b></a>
<p>Many Collection implementations (including all of the ones
provided by the JDK) will have a public clone method, but it would
be mistake to require it of all Collections. For example, what does
it mean to clone a Collection that's backed by a terabyte SQL
database? Should the method call cause the company to requisition a
new disk farm? Similar arguments hold for serializable.</p>
<p>If the client doesn't know the actual type of a Collection, it's
much more flexible and less error prone to have the client decide
what type of Collection is desired, create an empty Collection of
this type, and use the addAll method to copy the elements of the
original collection into the new one.</p>
</li>
<li><a name="a6" id="a6"><b>Why don't you provide an "apply" method
in Collection to apply a given method ("upcall") to all the
elements of the Collection?</b></a>
<p>This is what is referred to as an "Internal Iterator" in the
"Design Patterns" book (Gamma et al.). We considered providing it,
but decided not to as it seems somewhat redundant to support
internal and external iterators, and Java already has a precedent
for external iterators (with Enumerations). The "throw weight" of
this functionality is increased by the fact that it requires a
public interface to describe upcalls.</p>
</li>
<li><a name="a7" id="a7"><b>Why didn't you provide a "Predicate"
interface, and related methods (e.g., a method to find the first
element in the Collection satisfying the predicate)?</b></a>
<p>It's easy to implement this functionality atop Iterators, and
the resulting code may actually look cleaner as the user can inline
the predicate. Thus, it's not clear whether this facility pulls its
weight. It could be added to the Collections class at a later date
(implemented atop Iterator), if it's deemed useful.</p>
</li>
<li><a name="a8" id="a8"><b>Why don't you provide a form of the
addAll method that takes an Enumeration (or an Iterator)?</b></a>
<p>Because we don't believe in using Enumerations (or Iterators) as
"poor man's collections." This was occasionally done in prior
releases, but now that we have the Collection interface, it is the
preferred way to pass around abstract collections of objects.</p>
</li>
<li><a name="a9" id="a9"><b>Why don't the concrete implementations
in the JDK have Enumeration (or Iterator) constructors?</b></a>
<p>Again, this is an instance of an Enumeration serving as a "poor
man's collection" and we're trying to discourage that. Note
however, that we strongly suggest that all concrete implementations
should have constructors that take a Collection (and create a new
Collection with the same elements).</p>
</li>
<li><a name="a10" id="a10"><b>Why don't you provide an Iterator.add
method?</b></a>
<p>The semantics are unclear, given that the contract for Iterator
makes no guarantees about the order of iteration. Note, however,
that ListIterator does provide an add operation, as it does
guarantee the order of the iteration.</p>
</li>
</ol>
<hr />
<h3>List Interface</h3>
<ol>
<li><a name="a11" id="a11"><b>Why don't you rename the List
interface to Sequence; doesn't "list" generally suggest "linked
list"? Also, doesn't it conflict with java.awt.List?</b></a>
<p>People were evenly divided as to whether List suggests linked
lists. Given the implementation naming convention,
&lt;<em>Implementation</em>&gt;&lt;<em>Interface</em>&gt;, there
was a strong desire to keep the core interface names short. Also,
several existing names (AbstractSequentialList, LinkedList) would
have been decidedly worse if we changed List to Sequence. The
naming conflict can be dealt with by the following incantation:</p>
<pre>
import java.util.*;
import java.awt.*;
import java.util.List; // Dictates interpretation of "List"
</pre></li>
<li><a name="a12" id="a12"><b>Why don't you rename List's set
method to replace, to avoid confusion with Set.</b></a>
<p>It was decided that the "set/get" naming convention was strongly
enough enshrined in the language that we'd stick with it.</p>
</li>
</ol>
<hr />
<h3>Map Interface</h3>
<ol>
<li><a name="a14" id="a14"><b>Why doesn't Map extend
Collection?</b></a>
<p>This was by design. We feel that mappings are not collections
and collections are not mappings. Thus, it makes little sense for
Map to extend the Collection interface (or vice versa).</p>
<p>If a Map is a Collection, what are the elements? The only
reasonable answer is "Key-value pairs", but this provides a very
limited (and not particularly useful) Map abstraction. You can't
ask what value a given key maps to, nor can you delete the entry
for a given key without knowing what value it maps to.</p>
<p>Collection could be made to extend Map, but this raises the
question: what are the keys? There's no really satisfactory answer,
and forcing one leads to an unnatural interface.</p>
<p>Maps can be <em>viewed</em> as Collections (of keys, values, or
pairs), and this fact is reflected in the three "Collection view
operations" on Maps (keySet, entrySet, and values). While it is, in
principle, possible to view a List as a Map mapping indices to
elements, this has the nasty property that deleting an element from
the List changes the Key associated with every element before the
deleted element. That's why we don't have a map view operation on
Lists.</p>
</li>
</ol>
<hr />
<h3>Iterator Interface</h3>
<ol>
<li><a name="a18" id="a18"><b>Why doesn't Iterator extend
Enumeration?</b></a>
<p>We view the method names for Enumeration as unfortunate. They're
very long, and very frequently used. Given that we were adding a
method and creating a whole new framework, we felt that it would be
foolish not to take advantage of the opportunity to improve the
names. Of course we could support the new and old names in
Iterator, but it doesn't seem worthwhile.</p>
</li>
<li><a name="a19" id="a19"><b>Why don't you provide an
Iterator.peek method that allows you to look at the next element in
an iteration without advancing the iterator?</b></a>
<p>It can be implemented atop the current Iterators (a similar
pattern to java.io.PushbackInputStream). We believe that its use
would be rare enough that it isn't worth including in the interface
that everyone has to implement.</p>
</li>
</ol>
<hr />
<h3>Miscellaneous</h3>
<ol>
<li><a name="a23" id="a23"><b>Why did you write a new collections
framework instead of adopting JGL (a preexisting collections
package from ObjectSpace, Inc.) into the JDK?</b></a>
<p>If you examine the goals for our Collections framework (in the
Overview), you'll see that we are not really "playing in the same
space" as JGL. Quoting from the "Design Goals" Section of the Java
Collections Overview: "Our main design goal was to produce an API
that was reasonably small, both in size, and (more importantly) in
'conceptual weight.'"</p>
<p>JGL consists of approximately 130 classes and interfaces; its
main goal was consistency with the C++ Standard Template Library
(STL). This was <em>not</em> one of our goals. Java has
traditionally stayed away from C++'s more complex features (e.g.,
multiple inheritance, operator overloading). Our entire framework,
including all infrastructure, contains approximately 25 classes and
interfaces.</p>
<p>While this may cause some discomfort for some C++ programmers,
we feel that it will be good for Java in the long run. As the Java
libraries mature, they inevitably grow, but we are trying as hard
as we can to keep them small and manageable, so that Java continues
to be an easy, fun language to learn and to use.</p>
</li>
<li><a name="a26" id="a26"><b>Why don't you eliminate all of the
methods and classes that return "views" (Collections backed by
other collection-like objects). This would greatly reduce
aliasing.</b></a>
<p>Given that we provide core collection interfaces behind which
programmers can "hide" their own implementations, there will be
aliased collections whether the JDK provides them or not.
Eliminating all views from the JDK would greatly increase the cost
of common operations like making a Collection out of an array, and
would do away with many useful facilities (like synchronizing
wrappers). One view that we see as being particularly useful is
<a href=
"../List.html#subList-int-int-">List.subList</a>.
The existence of this method means that people who write methods
taking List on input do not have to write secondary forms taking an
offset and a length (as they do for arrays).</p>
</li>
<li><a name="a27" id="a27"><b>Why don't you provide for
"observable" collections that send out Events when they're
modified?</b></a>
<p>Primarily, resource constraints. If we're going to commit to
such an API, it has to be something that works for everyone, that
we can live with for the long haul. We may provide such a facility
some day. In the meantime, it's not difficult to implement such a
facility on top of the public APIs.</p>
</li>
</ol>
<hr />
<p style="font-size:smaller">
Copyright &copy; 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
Redwood Shores, CA 94065 USA. All rights reserved.</p>
<!-- Body text ends here -->
</body>
</html>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--
Copyright (c) 1998, 2017, 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.
-->
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
"en-US">
<head>
<meta name="generator" content="HTML Tidy, see www.w3.org" />
<title>The Collections Framework</title>
<style type="text/css">
/*<![CDATA[*/
ul li, ul ul li {font-weight: normal;}
pre {margin-left: 42pt;}
a {font-weight: bold;}
/*]]>*/
</style>
</head>
<body>
<h1>The Collections Framework</h1>
<!-- Body text begins here -->
<p>The collections framework is a unified architecture for
representing and manipulating collections, enabling them to be
manipulated independently of the details of their representation.
It reduces programming effort while increasing performance. It
enables interoperability among unrelated APIs, reduces effort in
designing and learning new APIs, and fosters software reuse. The
framework is based on more than a dozen collection interfaces. It
includes implementations of these interfaces and algorithms to
manipulate them.</p>
<p>The documents in this section are non-normative portions of
the Java&trade; Platform, Standard Edition API Specification.</p>
<ul>
<li><b><a href="coll-overview.html">Overview</a></b> - An overview of
the collections framework.</li>
</ul>
<ul>
<li><b><a href="coll-reference.html">Annotated API Outline</a></b> - An
annotated outline of the classes and interfaces comprising the
collections framework, with links into the API Specification.</li>
</ul>
<ul>
<li><b><a href="coll-designfaq.html">Design FAQ</a></b> - Answers to
frequently asked questions (FAQ) about the design of the
collections framework.</li>
</ul>
<hr />
<p style="font-size:smaller">
Copyright &copy; 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
Redwood Shores, CA 94065 USA. All rights reserved.</p>
<!-- Body text ends here -->
</body>
</html>

View File

@ -0,0 +1,359 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--
Copyright (c) 1998, 2017, 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.
-->
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
"en-US">
<head>
<title>Collections Framework Overview</title>
</head>
<body>
<h1>Collections Framework Overview</h1>
<!-- Body text begins here -->
<h2>Introduction</h2>
The Java platform includes a <i>collections framework</i>. A
<i>collection</i> is an object that represents a group of objects
(such as the classic <a href="../ArrayList.html">ArrayList</a> class).
A collections framework is a unified architecture for representing
and manipulating collections, enabling collections to be
manipulated independently of implementation details.
<p>The primary advantages of a collections framework are that
it:</p>
<ul>
<li><strong>Reduces programming effort</strong> by providing data
structures and algorithms so you don't have to write them
yourself.</li>
<li><strong>Increases performance</strong> by providing
high-performance implementations of data structures and algorithms.
Because the various implementations of each interface are
interchangeable, programs can be tuned by switching
implementations.</li>
<li><strong>Provides interoperability between unrelated
APIs</strong> by establishing a common language to pass collections
back and forth.</li>
<li><strong>Reduces the effort required to learn APIs</strong> by
requiring you to learn multiple ad hoc collection APIs.</li>
<li><strong>Reduces the effort required to design and implement
APIs</strong> by not requiring you to produce ad hoc collections
APIs.</li>
<li><strong>Fosters software reuse</strong> by providing a standard
interface for collections and algorithms with which to manipulate
them.</li>
</ul>
<p>The collections framework consists of:</p>
<ul>
<li><strong>Collection interfaces</strong>. Represent different
types of collections, such as sets, lists, and maps. These
interfaces form the basis of the framework.</li>
<li><strong>General-purpose implementations</strong>. Primary
implementations of the collection interfaces.</li>
<li><strong>Legacy implementations</strong>. The collection classes
from earlier releases, <tt>Vector</tt> and <tt>Hashtable</tt>, were
retrofitted to implement the collection interfaces.</li>
<li><strong>Special-purpose implementations</strong>.
Implementations designed for use in special situations. These
implementations display nonstandard performance characteristics,
usage restrictions, or behavior.</li>
<li><strong>Concurrent implementations</strong>. Implementations
designed for highly concurrent use.</li>
<li><strong>Wrapper implementations</strong>. Add functionality,
such as synchronization, to other implementations.</li>
<li><strong>Convenience implementations</strong>. High-performance
"mini-implementations" of the collection interfaces.</li>
<li><strong>Abstract implementations</strong>. Partial
implementations of the collection interfaces to facilitate custom
implementations.</li>
<li><strong>Algorithms</strong>. Static methods that perform useful
functions on collections, such as sorting a list.</li>
<li><strong>Infrastructure</strong>. Interfaces that provide
essential support for the collection interfaces.</li>
<li><strong>Array Utilities</strong>. Utility functions for arrays
of primitive types and reference objects. Not, strictly speaking, a
part of the collections framework, this feature was added to the
Java platform at the same time as the collections framework and
relies on some of the same infrastructure.</li>
</ul>
<hr />
<h2>Collection Interfaces</h2>
<p>The <i>collection interfaces</i> are divided into two groups.
The most basic interface, <tt><a href=
"../Collection.html">java.util.Collection</a></tt>,
has the following descendants:</p>
<ul>
<li><tt><a href=
"../Set.html">java.util.Set</a></tt></li>
<li><tt><a href=
"../SortedSet.html">java.util.SortedSet</a></tt></li>
<li><tt><a href=
"../NavigableSet.html">java.util.NavigableSet</a></tt></li>
<li><tt><a href=
"../Queue.html">java.util.Queue</a></tt></li>
<li><tt><a href=
"../concurrent/BlockingQueue.html">java.util.concurrent.BlockingQueue</a></tt></li>
<li><tt><a href=
"../concurrent/TransferQueue.html">java.util.concurrent.TransferQueue</a></tt></li>
<li><tt><a href=
"../Deque.html">java.util.Deque</a></tt></li>
<li><tt><a href=
"../concurrent/BlockingDeque.html">java.util.concurrent.BlockingDeque</a></tt></li>
</ul>
<p>The other collection interfaces are based on <tt><a href=
"../Map.html">java.util.Map</a></tt> and are
not true collections. However, these interfaces contain
<i>collection-view</i> operations, which enable them to be
manipulated as collections. <tt>Map</tt> has the following
offspring:</p>
<ul>
<li><tt><a href=
"../SortedMap.html">java.util.SortedMap</a></tt></li>
<li><tt><a href=
"../NavigableMap.html">java.util.NavigableMap</a></tt></li>
<li><tt><a href=
"../concurrent/ConcurrentMap.html">java.util.concurrent.ConcurrentMap</a></tt></li>
<li><tt><a href=
"../concurrent/ConcurrentNavigableMap.html">java.util.concurrent.ConcurrentNavigableMap</a></tt></li>
</ul>
<p>Many of the modification methods in the collection interfaces
are labeled <i>optional</i>. Implementations are permitted to not
perform one or more of these operations, throwing a runtime
exception (<tt>UnsupportedOperationException</tt>) if they are
attempted. The documentation for each implementation must specify
which optional operations are supported. Several terms are
introduced to aid in this specification:</p>
<ul>
<li>Collections that do not support modification operations (such
as <tt>add</tt>, <tt>remove</tt> and <tt>clear</tt>) are referred
to as <i>unmodifiable</i>. Collections that are not unmodifiable
are <i>modifiable.</i></li>
<li>Collections that additionally guarantee that no change in the
<tt>Collection</tt> object will be visible are referred to as
<i>immutable</i>. Collections that are not immutable are
<i>mutable</i>.</li>
<li>Lists that guarantee that their size remains constant even
though the elements can change are referred to as
<i>fixed-size</i>. Lists that are not fixed-size are referred to as
<i>variable-size</i>.</li>
<li>Lists that support fast (generally constant time) indexed
element access are known as <i>random access</i> lists. Lists that
do not support fast indexed element access are known as
<i>sequential access</i> lists. The <tt><a href=
"../RandomAccess.html">RandomAccess</a></tt>
marker interface enables lists to advertise the fact that they
support random access. This enables generic algorithms to change
their behavior to provide good performance when applied to either
random or sequential access lists.</li>
</ul>
<p>Some implementations restrict what elements (or in the case of
<tt>Maps</tt>, keys and values) can be stored. Possible
restrictions include requiring elements to:</p>
<ul>
<li>Be of a particular type.</li>
<li>Be not null.</li>
<li>Obey some arbitrary predicate.</li>
</ul>
<p>Attempting to add an element that violates an implementation's
restrictions results in a runtime exception, typically a
<tt>ClassCastException</tt>, an <tt>IllegalArgumentException</tt>,
or a <tt>NullPointerException</tt>. Attempting to remove or test
for the presence of an element that violates an implementation's
restrictions can result in an exception. Some restricted
collections permit this usage.</p>
<hr />
<h2>Collection Implementations</h2>
<p>Classes that implement the collection interfaces typically have
names in the form of
&lt;<em>Implementation-style</em>&gt;&lt;<em>Interface</em>&gt;.
The general purpose implementations are summarized in the following
table:</p>
<table border="2" summary=
"general purpose implementations and interfaces" align="center">
<thead>
<tr>
<th id="interfaces">Interface</th>
<th id="hashtable">Hash Table</th>
<th id="resizablearray">Resizable Array</th>
<th id="balancedtree">Balanced Tree</th>
<th id="linkedlist">Linked List</th>
<th id="hashtableandlinkedlist">Hash Table + Linked List</th>
</tr>
<tr>
<td headers="interfaces"><code>Set</code></td>
<td headers="hashtable"><a href=
"../HashSet.html"><tt>HashSet</tt></a></td>
<td headers="resizablearray">&nbsp;</td>
<td headers="balancedtree"><a href=
"../TreeSet.html"><tt>TreeSet</tt></a></td>
<td headers="linkedlist">&nbsp;</td>
<td headers="hashtableandlinkedlist"><a href=
"../LinkedHashSet.html"><tt>LinkedHashSet</tt></a></td>
</tr>
<tr>
<td headers="interfaces"><code>List</code></td>
<td headers="hashtable">&nbsp;</td>
<td headers="resizablearray"><a href=
"../ArrayList.html"><tt>ArrayList</tt></a></td>
<td headers="balancedtree">&nbsp;</td>
<td headers="linkedlist"><a href=
"../LinkedList.html"><tt>LinkedList</tt></a></td>
<td headers="hashtableandlinkedlist">&nbsp;</td>
</tr>
<tr>
<td headers="interfaces"><code>Deque</code></td>
<td headers="hashtable">&nbsp;</td>
<td headers="resizablearray"><a href=
"../ArrayDeque.html"><tt>ArrayDeque</tt></a></td>
<td headers="balancedtree">&nbsp;</td>
<td headers="linkedlist"><a href=
"../LinkedList.html"><tt>LinkedList</tt></a></td>
<td headers="hashtableandlinkedlist">&nbsp;</td>
</tr>
<tr>
<td headers="interfaces"><code>Map</code></td>
<td headers="hashtable"><a href=
"../HashMap.html"><tt>HashMap</tt></a></td>
<td headers="resizablearray">&nbsp;</td>
<td headers="balancedtree"><a href=
"../TreeMap.html"><tt>TreeMap</tt></a></td>
<td headers="linkedlist">&nbsp;</td>
<td headers="hashtableandlinkedlist"><a href=
"../LinkedHashMap.html"><tt>LinkedHashMap</tt></a></td>
</tr>
</thead>
</table>
<p>The general-purpose implementations support all of the
<i>optional operations</i> in the collection interfaces and have no
restrictions on the elements they may contain. They are
unsynchronized, but the <tt>Collections</tt> class contains static
factories called <a href=
"../Collections.html#synchronizedCollection-java.util.Collection-">
<em>synchronization wrappers</em></a> that can be used to add
synchronization to many unsynchronized collections. All of the new
implementations have <i>fail-fast iterators</i>, which detect
invalid concurrent modification, and fail quickly and cleanly
(rather than behaving erratically).</p>
<p>The <tt>AbstractCollection</tt>, <tt>AbstractSet</tt>,
<tt>AbstractList</tt>, <tt>AbstractSequentialList</tt> and
<tt>AbstractMap</tt> classes provide basic implementations of the
core collection interfaces, to minimize the effort required to
implement them. The API documentation for these classes describes
precisely how each method is implemented so the implementer knows
which methods must be overridden, given the performance of the
basic operations of a specific implementation.</p>
<hr />
<h2>Concurrent Collections</h2>
<p>Applications that use collections from more than one thread must
be carefully programmed. In general, this is known as <i>concurrent
programming</i>. The Java platform includes extensive support for
concurrent programming. See <a href=
"../concurrent/package-summary.html">Java Concurrency
Utilities</a> for details.</p>
<p>Collections are so frequently used that various concurrent
friendly interfaces and implementations of collections are included
in the APIs. These types go beyond the synchronization wrappers
discussed previously to provide features that are frequently needed
in concurrent programming.</p>
<p>These concurrent-aware interfaces are available:</p>
<ul>
<li><tt><a href=
"../concurrent/BlockingQueue.html">BlockingQueue</a></tt></li>
<li><tt><a href=
"../concurrent/TransferQueue.html">TransferQueue</a></tt></li>
<li><tt><a href=
"../concurrent/BlockingDeque.html">BlockingDeque</a></tt></li>
<li><tt><a href=
"../concurrent/ConcurrentMap.html">ConcurrentMap</a></tt></li>
<li><tt><a href=
"../concurrent/ConcurrentNavigableMap.html">ConcurrentNavigableMap</a></tt></li>
</ul>
<p>The following concurrent-aware implementation classes are
available. See the API documentation for the correct usage of these
implementations.</p>
<ul>
<li><tt><a href=
"../concurrent/LinkedBlockingQueue.html">LinkedBlockingQueue</a></tt></li>
<li><tt><a href=
"../concurrent/ArrayBlockingQueue.html">ArrayBlockingQueue</a></tt></li>
<li><tt><a href=
"../concurrent/PriorityBlockingQueue.html">PriorityBlockingQueue</a></tt></li>
<li><tt><a href=
"../concurrent/DelayQueue.html">DelayQueue</a></tt></li>
<li><tt><a href=
"../concurrent/SynchronousQueue.html">SynchronousQueue</a></tt></li>
<li><a href=
"../concurrent/LinkedBlockingDeque.html"><tt>LinkedBlockingDeque</tt></a></li>
<li><a href=
"../concurrent/LinkedTransferQueue.html"><tt>LinkedTransferQueue</tt></a></li>
<li><tt><a href=
"../concurrent/CopyOnWriteArrayList.html">CopyOnWriteArrayList</a></tt></li>
<li><tt><a href=
"../concurrent/CopyOnWriteArraySet.html">CopyOnWriteArraySet</a></tt></li>
<li><tt><a href=
"../concurrent/ConcurrentSkipListSet.html">ConcurrentSkipListSet</a></tt></li>
<li><tt><a href=
"../concurrent/ConcurrentHashMap.html">ConcurrentHashMap</a></tt></li>
<li><tt><a href=
"../concurrent/ConcurrentSkipListMap.html">ConcurrentSkipListMap</a></tt></li>
</ul>
<hr />
<h2>Design Goals</h2>
<p>The main design goal was to produce an API that was small in
size and, more importantly, in &quot;conceptual weight.&quot; It
was critical that the new functionality not seem too different to
current Java programmers; it had to augment current facilities,
rather than replace them. At the same time, the new API had to be
powerful enough to provide all the advantages described
previously.</p>
<p>To keep the number of core interfaces small, the interfaces do
not attempt to capture such subtle distinctions as mutability,
modifiability, and resizability. Instead, certain calls in the core
interfaces are <i>optional</i>, enabling implementations to throw
an <tt>UnsupportedOperationException</tt> to indicate that they do
not support a specified optional operation. Collection implementers
must clearly document which optional operations are supported by an
implementation.</p>
<p>To keep the number of methods in each core interface small, an
interface contains a method only if either:</p>
<ul>
<li>It is a truly <i>fundamental operation</i>: a basic operations
in terms of which others could be reasonably defined,</li>
<li>There is a compelling performance reason why an important
implementation would want to override it.</li>
</ul>
<p>It was critical that all reasonable representations of
collections interoperate well. This included arrays, which cannot
be made to implement the <tt>Collection</tt> interface directly
without changing the language. Thus, the framework includes methods
to enable collections to be moved into arrays, arrays to be viewed
as collections, and maps to be viewed as collections.</p>
<hr />
<p style="font-size:smaller">
Copyright &copy; 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
Redwood Shores, CA 94065 USA. All rights reserved.</p>
<!-- Body text ends here -->
</body>
</html>

View File

@ -0,0 +1,564 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--
Copyright (c) 1998, 2017, 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.
-->
<html lang="en-US" xmlns="http://www.w3.org/1999/xhtml" xml:lang=
"en-US">
<head>
<title>Outline of the Collections Framework</title>
</head>
<body>
<h1>Outline of the Collections Framework</h1>
<!-- Body text begins here -->
The collections framework consists of:
<ul>
<li><strong>Collection interfaces</strong> - The primary means by
which collections are manipulated.
<ul>
<li><a href=
"../Collection.html"><strong>Collection</strong></a>
- A group of objects. No assumptions are made about the order of
the collection (if any) or whether it can contain duplicate
elements.</li>
<li><a href=
"../Set.html"><strong>Set</strong></a> - The
familiar set abstraction. No duplicate elements permitted. May or
may not be ordered. Extends the <tt>Collection</tt> interface.</li>
<li><a href=
"../List.html"><strong>List</strong></a> -
Ordered collection, also known as a <i>sequence</i>. Duplicates are
generally permitted. Allows positional access. Extends the
<tt>Collection</tt> interface.</li>
<li><a href=
"../Queue.html"><strong>Queue</strong></a> - A
collection designed for holding elements before processing. Besides
basic <tt>Collection</tt> operations, queues provide additional
insertion, extraction, and inspection operations.</li>
<li><a href=
"../Deque.html"><strong>Deque</strong></a> - A
<em>double ended queue</em>, supporting element insertion and
removal at both ends. Extends the <tt>Queue</tt> interface.</li>
<li><a href=
"../Map.html"><strong>Map</strong></a> - A
mapping from keys to values. Each key can map to one value.</li>
<li><a href=
"../SortedSet.html"><strong>SortedSet</strong></a>
- A set whose elements are automatically sorted, either in their
<i>natural ordering</i> (see the <a href=
"../../lang/Comparable.html"><tt>Comparable</tt></a>
interface) or by a <a href=
"../Comparator.html"><tt>Comparator</tt></a>
object provided when a <tt>SortedSet</tt> instance is created.
Extends the <tt>Set</tt> interface.</li>
<li><a href=
"../SortedMap.html"><strong>SortedMap</strong></a>
- A map whose mappings are automatically sorted by key, either
using the <i>natural ordering</i> of the keys or by a comparator
provided when a <tt>SortedMap</tt> instance is created. Extends the
<tt>Map</tt> interface.</li>
<li><a href=
"../NavigableSet.html"><strong>NavigableSet</strong></a>
- A <tt>SortedSet</tt> extended with navigation methods reporting
closest matches for given search targets. A <tt>NavigableSet</tt>
may be accessed and traversed in either ascending or descending
order.</li>
<li><a href=
"../NavigableMap.html"><strong>NavigableMap</strong></a>
- A <tt>SortedMap</tt> extended with navigation methods returning
the closest matches for given search targets. A
<tt>NavigableMap</tt> can be accessed and traversed in either
ascending or descending key order.</li>
<li><a href=
"../concurrent/BlockingQueue.html"><strong>BlockingQueue</strong></a>
- A <tt>Queue</tt> with operations that wait for the queue to
become nonempty when retrieving an element and that wait for space
to become available in the queue when storing an element. (This
interface is part of the <tt><a href=
"../concurrent/package-summary.html">java.util.concurrent</a></tt>
package.)</li>
<li><a href=
"../concurrent/TransferQueue.html"><strong>TransferQueue</strong></a>
- A <tt>BlockingQueue</tt> in which producers can wait for
consumers to receive elements. (This interface is part of the
<tt><a href=
"../concurrent/package-summary.html">java.util.concurrent</a></tt>
package.)</li>
<li><a href=
"../concurrent/BlockingDeque.html"><strong>BlockingDeque</strong></a>
- A <tt>Deque</tt> with operations that wait for the deque to
become nonempty when retrieving an element and wait for space to
become available in the deque when storing an element. Extends both
the <tt>Deque</tt> and <tt>BlockingQueue</tt> interfaces. (This
interface is part of the <tt><a href=
"../concurrent/package-summary.html">java.util.concurrent</a></tt>
package.)</li>
<li><a href=
"../concurrent/ConcurrentMap.html"><strong>ConcurrentMap</strong></a>
- A <tt>Map</tt> with atomic <tt>putIfAbsent</tt>, <tt>remove</tt>,
and <tt>replace</tt> methods. (This interface is part of the
<tt>java.util.concurrent</tt> package.)</li>
<li><a href=
"../concurrent/ConcurrentNavigableMap.html"><strong>
ConcurrentNavigableMap</strong></a> - A <tt>ConcurrentMap</tt> that
is also a <tt>NavigableMap</tt>.</li>
</ul>
</li>
<li><strong>General-purpose implementations</strong> - The primary
implementations of the collection interfaces.
<ul>
<li><strong><a href=
"../HashSet.html">HashSet</a></strong> - Hash
table implementation of the <tt>Set</tt> interface. The best
all-around implementation of the <tt>Set</tt> interface.</li>
<li><a href=
"../TreeSet.html"><strong>TreeSet</strong></a>
- Red-black tree implementation of the <tt>NavigableSet</tt>
interface.</li>
<li><strong><a href=
"../LinkedHashSet.html">LinkedHashSet</a></strong>
- Hash table and linked list implementation of the <tt>Set</tt>
interface. An insertion-ordered <tt>Set</tt> implementation that
runs nearly as fast as <tt>HashSet</tt>.</li>
<li><strong><a href=
"../ArrayList.html">ArrayList</a></strong> -
Resizable array implementation of the <tt>List</tt> interface (an
unsynchronized <tt>Vector</tt>). The best all-around implementation
of the <tt>List</tt> interface.</li>
<li><strong><a href=
"../ArrayDeque.html">ArrayDeque</a></strong> -
Efficient, resizable array implementation of the <tt>Deque</tt>
interface.</li>
<li><a href=
"../LinkedList.html"><strong>LinkedList</strong></a>
- Doubly-linked list implementation of the <tt>List</tt> interface.
Provides better performance than the <tt>ArrayList</tt>
implementation if elements are frequently inserted or deleted
within the list. Also implements the <tt>Deque</tt> interface. When
accessed through the <tt>Queue</tt> interface, <tt>LinkedList</tt>
acts as a FIFO queue.</li>
<li><strong><a href=
"../PriorityQueue.html">PriorityQueue</a></strong>
- Heap implementation of an unbounded priority queue.</li>
<li><strong><a href=
"../HashMap.html">HashMap</a></strong> - Hash
table implementation of the <tt>Map</tt> interface (an
unsynchronized <tt>Hashtable</tt> that supports <tt>null</tt> keys
and values). The best all-around implementation of the <tt>Map</tt>
interface.</li>
<li><a href=
"../TreeMap.html"><strong>TreeMap</strong></a>
Red-black tree implementation of the <tt>NavigableMap</tt>
interface.</li>
<li><strong><a href=
"../LinkedHashMap.html">LinkedHashMap</a></strong>
- Hash table and linked list implementation of the <tt>Map</tt>
interface. An insertion-ordered <tt>Map</tt> implementation that
runs nearly as fast as <tt>HashMap</tt>. Also useful for building
caches (see <a href=
"../LinkedHashMap.html#removeEldestEntry-java.util.Map.Entry-">
removeEldestEntry(Map.Entry)</a> ).</li>
</ul>
</li>
<li><strong>Wrapper implementations</strong> -
Functionality-enhancing implementations for use with other
implementations. Accessed solely through static factory methods.
<ul>
<li><a href=
"../Collections.html#unmodifiableCollection-java.util.Collection-">
<strong>Collections.unmodifiable<i>Interface</i></strong></a> -
Returns an unmodifiable view of a specified collection that throws
an <tt>UnsupportedOperationException</tt> if the user attempts to
modify it.</li>
<li><a name="synchWrappers" href=
"../Collections.html#synchronizedCollection-java.util.Collection-"
id=
"synchWrappers"><strong>Collections.synchronized<i>Interface</i></strong></a>
- Returns a synchronized collection that is backed by the specified
(typically unsynchronized) collection. As long as all accesses to
the backing collection are through the returned collection, thread
safety is guaranteed.</li>
<li><a href=
"../Collections.html#checkedCollection-java.util.Collection-java.lang.Class-">
<strong>Collections.checked<i>Interface</i></strong></a> - Returns
a dynamically type-safe view of the specified collection, which
throws a <tt>ClassCastException</tt> if a client attempts to add an
element of the wrong type. The generics mechanism in the language
provides compile-time (static) type checking, but it is possible to
bypass this mechanism. Dynamically type-safe views eliminate this
possibility.</li>
</ul>
</li>
<li><strong>Adapter implementations</strong> - Implementations that
adapt one collections interface to another:
<ul>
<li><strong><a href=
"../Collections.html#newSetFromMap-java.util.Map-">
newSetFromMap(Map)</a></strong> - Creates a general-purpose
<tt>Set</tt> implementation from a general-purpose <tt>Map</tt>
implementation.</li>
<li><strong><a href=
"../Collections.html#asLifoQueue-java.util.Deque-">
asLifoQueue(Deque)</a></strong> - Returns a view of a
<tt>Deque</tt> as a Last In First Out (LIFO) <tt>Queue</tt>.</li>
</ul>
</li>
<li><strong>Convenience implementations</strong> - High-performance
"mini-implementations" of the collection interfaces.
<ul>
<li><a href=
"../Arrays.html#asList-T...-"><strong>Arrays.asList</strong></a>
- Enables an array to be viewed as a list.</li>
<li><strong><a href=
"../Collections.html#emptySet--">emptySet</a>,
<a href=
"../Collections.html#emptyList--">emptyList</a>
and <a href=
"../Collections.html#emptyMap--">emptyMap</a></strong>
- Return an immutable empty set, list, or map.</li>
<li><strong><a href=
"../Collections.html#singleton-java.lang.Object-">
singleton</a>, <a href=
"../Collections.html#singletonList-java.lang.Object-">
singletonList</a>, and <a href=
"../Collections.html#singletonMap-K-V-">singletonMap</a></strong>
- Return an immutable singleton set, list, or map, containing only
the specified object (or key-value mapping).</li>
<li><a href=
"../Collections.html#nCopies-int-T-"><strong>
nCopies</strong></a> - Returns an immutable list consisting of n
copies of a specified object.</li>
</ul>
</li>
<li><strong>Legacy implementations</strong> - Older collection
classes were retrofitted to implement the collection interfaces.
<ul>
<li><a href=
"../Vector.html"><strong>Vector</strong></a> -
Synchronized resizable array implementation of the <tt>List</tt>
interface with additional legacy methods.</li>
<li><a href=
"../Hashtable.html"><strong>Hashtable</strong></a>
- Synchronized hash table implementation of the <tt>Map</tt>
interface that does not allow <tt>null</tt> keys or values, plus
additional legacy methods.</li>
</ul>
</li>
<li><strong>Special-purpose implementations</strong>
<ul>
<li><strong><a href=
"../WeakHashMap.html">WeakHashMap</a></strong>
- An implementation of the <tt>Map</tt> interface that stores only
<a href="../../lang/ref/WeakReference.html"><i>weak
references</i></a> to its keys. Storing only weak references
enables key-value pairs to be garbage collected when the key is no
longer referenced outside of the <tt>WeakHashMap</tt>. This class
is the easiest way to use the power of weak references. It is
useful for implementing registry-like data structures, where the
utility of an entry vanishes when its key is no longer reachable by
any thread.</li>
<li><strong><a href=
"../IdentityHashMap.html">IdentityHashMap</a></strong>
- Identity-based <tt>Map</tt> implementation based on a hash table.
This class is useful for topology-preserving object graph
transformations (such as serialization or deep copying). To perform
these transformations, you must maintain an identity-based "node
table" that keeps track of which objects have already been seen.
Identity-based maps are also used to maintain
object-to-meta-information mappings in dynamic debuggers and
similar systems. Finally, identity-based maps are useful in
preventing "spoof attacks" resulting from intentionally perverse
equals methods. (<tt>IdentityHashMap</tt> never invokes the equals
method on its keys.) An added benefit of this implementation is
that it is fast.</li>
<li><strong><a href=
"../concurrent/CopyOnWriteArrayList.html">CopyOnWriteArrayList</a></strong>
- A <tt>List</tt> implementation backed by an copy-on-write array.
All mutative operations (such as <tt>add</tt>, <tt>set</tt>, and
<tt>remove</tt>) are implemented by making a new copy of the array.
No synchronization is necessary, even during iteration, and
iterators are guaranteed never to throw
<tt>ConcurrentModificationException</tt>. This implementation is
well-suited to maintaining event-handler lists (where change is
infrequent, and traversal is frequent and potentially
time-consuming).</li>
<li><strong><a href=
"../concurrent/CopyOnWriteArraySet.html">CopyOnWriteArraySet</a></strong>
- A <tt>Set</tt> implementation backed by a copy-on-write array.
This implementation is similar to <tt>CopyOnWriteArrayList</tt>.
Unlike most <tt>Set</tt> implementations, the <tt>add</tt>,
<tt>remove</tt>, and <tt>contains</tt> methods require time
proportional to the size of the set. This implementation is well
suited to maintaining event-handler lists that must prevent
duplicates.</li>
<li><strong><a href=
"../EnumSet.html">EnumSet</a></strong> - A
high-performance <tt>Set</tt> implementation backed by a bit
vector. All elements of each <tt>EnumSet</tt> instance must be
elements of a single enum type.</li>
<li><strong><a href=
"../EnumMap.html">EnumMap</a></strong> - A
high-performance <tt>Map</tt> implementation backed by an array.
All keys in each <tt>EnumMap</tt> instance must be elements of a
single enum type.</li>
</ul>
</li>
<li><strong>Concurrent implementations</strong> - These
implementations are part of <tt>java.util.concurrent</tt>.
<ul>
<li><strong><a href=
"../concurrent/ConcurrentLinkedQueue.html">ConcurrentLinkedQueue</a></strong>
- An unbounded first in, first out (FIFO) queue based on linked
nodes.</li>
<li><a href=
"../concurrent/LinkedBlockingQueue.html"><strong>
LinkedBlockingQueue</strong></a> - An optionally bounded FIFO
blocking queue backed by linked nodes.</li>
<li><a href=
"../concurrent/ArrayBlockingQueue.html"><strong>
ArrayBlockingQueue</strong></a> - A bounded FIFO blocking queue
backed by an array.</li>
<li><a href=
"../concurrent/PriorityBlockingQueue.html"><strong>
PriorityBlockingQueue</strong></a> - An unbounded blocking priority
queue backed by a priority heap.</li>
<li><a href=
"../concurrent/DelayQueue.html"><strong>DelayQueue</strong></a>
- A time-based scheduling queue backed by a priority heap.</li>
<li><a href=
"../concurrent/SynchronousQueue.html"><strong>SynchronousQueue</strong></a>
- A simple rendezvous mechanism that uses the
<tt>BlockingQueue</tt> interface.</li>
<li><a href=
"../concurrent/LinkedBlockingDeque.html"><strong>
LinkedBlockingDeque</strong></a> - An optionally bounded FIFO
blocking deque backed by linked nodes.</li>
<li><a href=
"../concurrent/LinkedTransferQueue.html"><strong>
LinkedTransferQueue</strong></a> - An unbounded
<tt>TransferQueue</tt> backed by linked nodes.</li>
<li><a href=
"../concurrent/ConcurrentHashMap.html"><strong>ConcurrentHashMap</strong></a>
- A highly concurrent, high-performance <tt>ConcurrentMap</tt>
implementation based on a hash table. This implementation never
blocks when performing retrievals and enables the client to select
the concurrency level for updates. It is intended as a drop-in
replacement for <tt><a href=
"../Hashtable.html">Hashtable</a></tt>. In
addition to implementing <tt>ConcurrentMap</tt>, it supports all of
the legacy methods of <tt>Hashtable</tt>.</li>
<li><a href=
"../concurrent/ConcurrentSkipListSet.html"><strong>
ConcurrentSkipListSet</strong></a> - Skips list implementation of
the <tt>NavigableSet</tt> interface.</li>
<li><a href=
"../concurrent/ConcurrentSkipListMap.html"><strong>
ConcurrentSkipListMap</strong></a> - Skips list implementation of
the <tt>ConcurrentNavigableMap</tt> interface.</li>
</ul>
</li>
<li><strong>Abstract implementations</strong> - Skeletal
implementations of the collection interfaces to facilitate custom
implementations.
<ul>
<li><a href=
"../AbstractCollection.html"><strong>AbstractCollection</strong></a>
- Skeletal <tt>Collection</tt> implementation that is neither a set
nor a list (such as a "bag" or multiset).</li>
<li><a href=
"../AbstractSet.html"><strong>AbstractSet</strong></a>
- Skeletal <tt>Set</tt> implementation.</li>
<li><a href=
"../AbstractList.html"><strong>AbstractList</strong></a>
- Skeletal <tt>List</tt> implementation backed by a random access
data store (such as an array).</li>
<li><a href=
"../AbstractSequentialList.html"><strong>AbstractSequentialList</strong></a>
- Skeletal <tt>List</tt> implementation backed by a sequential
access data store (such as a linked list).</li>
<li><a href=
"../AbstractQueue.html"><strong>AbstractQueue</strong></a>
- Skeletal <tt>Queue</tt> implementation.</li>
<li><a href=
"../AbstractMap.html"><strong>AbstractMap</strong></a>
- Skeletal <tt>Map</tt> implementation.</li>
</ul>
</li>
<li><strong>Algorithms</strong> - The <a href=
"../Collections.html"><strong>Collections</strong></a>
class contains these useful static methods.
<ul>
<li><strong><a href=
"../Collections.html#sort-java.util.List-">sort(List)</a></strong>
- Sorts a list using a merge sort algorithm, which provides average
case performance comparable to a high quality quicksort, guaranteed
O(n*log n) performance (unlike quicksort), and <em>stability</em>
(unlike quicksort). A stable sort is one that does not reorder
equal elements.</li>
<li><strong><a href=
"../Collections.html#binarySearch-java.util.List-T-">
binarySearch(List, Object)</a></strong> - Searches for an element
in an ordered list using the binary search algorithm.</li>
<li><strong><a href=
"../Collections.html#reverse-java.util.List-">reverse(List)</a></strong>
- Reverses the order of the elements in a list.</li>
<li><strong><a href=
"../Collections.html#shuffle-java.util.List-">shuffle(List)</a></strong>
- Randomly changes the order of the elements in a list.</li>
<li><strong><a href=
"../Collections.html#fill-java.util.List-T-">
fill(List, Object)</a></strong> - Overwrites every element in a
list with the specified value.</li>
<li><strong><a href=
"../Collections.html#copy-java.util.List-java.util.List-">
copy(List dest, List src)</a></strong> - Copies the source list
into the destination list.</li>
<li><strong><a href=
"../Collections.html#min-java.util.Collection-">
min(Collection)</a></strong> - Returns the minimum element in a
collection.</li>
<li><strong><a href=
"../Collections.html#max-java.util.Collection-">
max(Collection)</a></strong> - Returns the maximum element in a
collection.</li>
<li><strong><a href=
"../Collections.html#rotate-java.util.List-int-">
rotate(List list, int distance)</a></strong> - Rotates all of the
elements in the list by the specified distance.</li>
<li><strong><a href=
"../Collections.html#replaceAll-java.util.List-T-T-">
replaceAll(List list, Object oldVal, Object newVal)</a></strong> -
Replaces all occurrences of one specified value with another.</li>
<li><strong><a href=
"../Collections.html#indexOfSubList-java.util.List-java.util.List-">
indexOfSubList(List source, List target)</a></strong> - Returns the
index of the first sublist of source that is equal to target.</li>
<li><strong><a href=
"../Collections.html#lastIndexOfSubList-java.util.List-java.util.List-">
lastIndexOfSubList(List source, List target)</a></strong> - Returns
the index of the last sublist of source that is equal to
target.</li>
<li><strong><a href=
"../Collections.html#swap-java.util.List-int-int-">
swap(List, int, int)</a></strong> - Swaps the elements at the
specified positions in the specified list.</li>
<li><strong><a href=
"../Collections.html#frequency-java.util.Collection-java.lang.Object-">
frequency(Collection, Object)</a></strong> - Counts the number of
times the specified element occurs in the specified
collection.</li>
<li><strong><a href=
"../Collections.html#disjoint-java.util.Collection-java.util.Collection-">
disjoint(Collection, Collection)</a></strong> - Determines whether
two collections are disjoint, in other words, whether they contain
no elements in common.</li>
<li><strong><a href=
"../Collections.html#addAll-java.util.Collection-T...-">
addAll(Collection&lt;? super T&gt;, T...)</a></strong> - Adds all
of the elements in the specified array to the specified
collection.</li>
</ul>
</li>
<li><strong>Infrastructure</strong>
<ul>
<li><strong>Iterators</strong> - Similar to the familiar <a href=
"../Enumeration.html">Enumeration</a>
interface, but more powerful, and with improved method names.
<ul>
<li><a href=
"../Iterator.html"><strong>Iterator</strong></a>
- In addition to the functionality of the <tt>Enumeration</tt>
interface, enables the user to remove elements from the backing
collection with well-defined, useful semantics.</li>
<li><a href=
"../ListIterator.html"><strong>ListIterator</strong></a>
- Iterator for use with lists. In addition to the functionality of
the <tt>Iterator</tt> interface, supports bidirectional iteration,
element replacement, element insertion, and index retrieval.</li>
</ul>
</li>
<li><strong>Ordering</strong>
<ul>
<li><a href=
"../../lang/Comparable.html"><strong>Comparable</strong></a>
- Imparts a <i>natural ordering</i> to classes that implement it.
The natural ordering can be used to sort a list or maintain order
in a sorted set or map. Many classes were retrofitted to implement
this interface.</li>
<li><a href=
"../Comparator.html"><strong>Comparator</strong></a>
- Represents an order relation, which can be used to sort a list or
maintain order in a sorted set or map. Can override a type's
natural ordering or order objects of a type that does not implement
the <tt>Comparable</tt> interface.</li>
</ul>
</li>
<li><strong>Runtime exceptions</strong>
<ul>
<li><a href=
"../../lang/UnsupportedOperationException.html"><strong>
UnsupportedOperationException</strong></a> - Thrown by collections
if an unsupported optional operation is called.</li>
<li><a href=
"../ConcurrentModificationException.html"><strong>
ConcurrentModificationException</strong></a> - Thrown by iterators
and list iterators if the backing collection is changed
unexpectedly while the iteration is in progress. Also thrown by
<i>sublist</i> views of lists if the backing list is changed
unexpectedly.</li>
</ul>
</li>
<li><strong>Performance</strong>
<ul>
<li><strong><a href=
"../RandomAccess.html">RandomAccess</a></strong>
- Marker interface that lets <tt>List</tt> implementations indicate
that they support fast (generally constant time) random access.
This lets generic algorithms change their behavior to provide good
performance when applied to either random or sequential access
lists.</li>
</ul>
</li>
</ul>
</li>
<li><strong>Array Utilities</strong>
<ul>
<li><a href=
"../Arrays.html"><strong>Arrays</strong></a> -
Contains static methods to sort, search, compare, hash, copy,
resize, convert to <tt>String</tt>, and fill arrays of primitives
and objects.</li>
</ul>
</li>
</ul>
<hr />
<p style="font-size:smaller">
Copyright &copy; 1998, 2017, Oracle and/or its affiliates. 500 Oracle Parkway<br />
Redwood Shores, CA 94065 USA. All rights reserved.</p>
<!-- Body text ends here -->
</body>
</html>

View File

@ -44,7 +44,7 @@ import java.util.Comparator;
* the ASCII characters in the set [0-9a-zA-Z_-], and cannot exceed 70
* characters in length. Attribute values can contain any characters and
* will be UTF8-encoded when written to the output stream. See the
* <a href="../../../../technotes/guides/jar/jar.html">JAR File Specification</a>
* <a href="{@docRoot}/../specs/jar/jar.html">JAR File Specification</a>
* for more information about valid attribute names and values.
*
* <p>This map and its views have a predictable iteration order, namely the
@ -443,7 +443,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
* to the ASCII characters in the set [0-9a-zA-Z_-], and cannot exceed
* 70 characters in length. Attribute values can contain any characters
* and will be UTF8-encoded when written to the output stream. See the
* <a href="../../../../technotes/guides/jar/jar.html">JAR File Specification</a>
* <a href="{@docRoot}/../specs/jar/jar.html">JAR File Specification</a>
* for more information about valid attribute names and values.
*/
public static class Name {
@ -529,7 +529,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
* {@code Name} object for {@code Manifest-Version}
* manifest attribute. This attribute indicates the version number
* of the manifest standard to which a JAR file's manifest conforms.
* @see <a href="../../../../technotes/guides/jar/jar.html#JAR_Manifest">
* @see <a href="{@docRoot}/../specs/jar/jar.html#JAR_Manifest">
* Manifest and Signature Specification</a>
*/
public static final Name MANIFEST_VERSION = new Name("Manifest-Version");
@ -537,7 +537,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
/**
* {@code Name} object for {@code Signature-Version}
* manifest attribute used when signing JAR files.
* @see <a href="../../../../technotes/guides/jar/jar.html#JAR_Manifest">
* @see <a href="{@docRoot}/../specs/jar/jar.html#JAR_Manifest">
* Manifest and Signature Specification</a>
*/
public static final Name SIGNATURE_VERSION = new Name("Signature-Version");
@ -551,7 +551,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
/**
* {@code Name} object for {@code Class-Path}
* manifest attribute.
* @see <a href="../../../../technotes/guides/jar/jar.html#classpath">
* @see <a href="{@docRoot}/../specs/jar/jar.html#classpath">
* JAR file specification</a>
*/
public static final Name CLASS_PATH = new Name("Class-Path");
@ -568,7 +568,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
/**
* {@code Name} object for {@code Sealed} manifest attribute
* used for sealing.
* @see <a href="../../../../technotes/guides/jar/jar.html#sealing">
* @see <a href="{@docRoot}/../specs/jar/jar.html#sealing">
* Package Sealing</a>
*/
public static final Name SEALED = new Name("Sealed");

View File

@ -39,7 +39,7 @@ import java.util.Iterator;
* associated Attributes. There are main Manifest Attributes as well as
* per-entry Attributes. For information on the Manifest format, please
* see the
* <a href="../../../../technotes/guides/jar/jar.html">
* <a href="{@docRoot}/../specs/jar/jar.html">
* Manifest format specification</a>.
*
* @author David Connelly

View File

@ -34,8 +34,7 @@ import sun.security.action.GetPropertyAction;
/**
* Transforms a JAR file to or from a packed stream in Pack200 format.
* Please refer to Network Transfer Format JSR 200 Specification at
* <a href=http://jcp.org/aboutJava/communityprocess/review/jsr200/index.html>http://jcp.org/aboutJava/communityprocess/review/jsr200/index.html</a>
* Please refer to <a href="{@docRoot}/../specs/pack-spec.html">Network Transfer Format JSR 200 Specification</a>
* <p>
* Typically the packer engine is used by application developers
* to deploy or host JAR files on a website.

View File

@ -40,7 +40,7 @@
* <a href="../zip/package-summary.html#package_description">java.util.zip
* package description.</a> <p>
* In JAR files, all file names must be encoded in the UTF-8 encoding.
* <li><a href="../../../../technotes/guides/jar/jar.html">
* <li><a href="{@docRoot}/../specs/jar/jar.html">
* Manifest and Signature Specification</a> - The manifest format specification.
* </ul>
*

View File

@ -24,27 +24,24 @@
*/
/**
* Contains the collections framework, legacy collection classes,
* event model, date and time facilities, internationalization, and
* miscellaneous utility classes (a string tokenizer, a random-number
* generator, and a bit array).
* Contains the collections framework, some internationalization support classes,
* a service loader, properties, random number generation, string parsing
* and scanning classes, base64 encoding and decoding, a bit array, and
* several miscellaneous utility classes. This package also contains
* legacy collection classes and legacy date and time classes.
*
* <h2><a id="CollectionsFramework"></a>{@index "Java Collections Framework"}</h2>
* <p>For an overview, API outline, and design rationale, please see:
* <ul>
* <li><a href="../../../technotes/guides/collections/overview.html"><b>Collections Framework Overview</b></a>
* <li><a href="../../../technotes/guides/collections/reference.html"><b>
* Collections Framework Annotated Outline</b></a>
* <li><a href="doc-files/coll-index.html">
* <b>Collections Framework Documentation</b></a>
* </ul>
*
* <h2>Related Documentation</h2>
* For overviews, tutorials, examples, guides, and tool documentation,
* please see:
* <p>For a tutorial and programming guide with examples of use
* of the collections framework, please see:
* <ul>
* <li><a href="http://docs.oracle.com/javase/tutorial/collections/index.html">
* <b>Collections Framework Tutorial</b></a>
* <li><a
* href="../../../technotes/guides/collections/designfaq.html"><b>Collections
* Framework Design FAQ</b></a>
* <li><a href="http://docs.oracle.com/javase/tutorial/collections/index.html">
* <b>Collections Framework Tutorial</b></a>
* </ul>
*
* @since 1.0

View File

@ -2616,11 +2616,9 @@ public class Cipher {
* according to the installed JCE jurisdiction policy files. If
* JCE unlimited strength jurisdiction policy files are installed,
* Integer.MAX_VALUE will be returned.
* For more information on default key size in JCE jurisdiction
* policy files, please see Appendix E in the
* <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppC">
* Java Cryptography Architecture Reference Guide</a>.
* For more information on the default key sizes and the JCE jurisdiction
* policy files, please see the Cryptographic defaults and limitations in
* the {@extLink security_guide_jdk_providers JDK Providers Documentation}.
*
* @param transformation the cipher transformation.
* @return the maximum key length in bits or Integer.MAX_VALUE.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2017, 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
@ -116,10 +116,9 @@ public class EncryptedPrivateKeyInfo {
* e.g. EncryptedPrivateKeyInfo(AlgorithmParameters, byte[]),
* should be used.
*
* @param algName encryption algorithm name. See Appendix A in the
* <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture Reference Guide</a>
* @param algName encryption algorithm name. See the
* <a href="{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard Cipher algorithm names.
* @param encryptedData encrypted data. The contents of
* <code>encrypedData</code> are copied to protect against subsequent
@ -199,10 +198,8 @@ public class EncryptedPrivateKeyInfo {
* Returns the encryption algorithm.
* <p>Note: Standard name is returned instead of the specified one
* in the constructor when such mapping is available.
* See Appendix A in the
* <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture Reference Guide</a>
* See the <a href="{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard Cipher algorithm names.
*
* @return the encryption algorithm name.

View File

@ -84,8 +84,7 @@ import sun.security.util.Debug;
* (via a call to an {@code init} method), each provider must
* supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
* JDK Providers</a>
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the KeyGenerator defaults used by
* JDK providers.
* However, note that defaults may vary across different providers.

View File

@ -39,8 +39,7 @@ import java.security.spec.*;
* (via a call to an {@code init} method), each provider must
* supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* <a href="{@docRoot}/../technotes/guides/security/SunProviders.html">
* JDK Providers</a>
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the KeyGenerator defaults used by
* JDK providers.
* However, note that defaults may vary across different providers.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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
@ -39,10 +39,8 @@
* developer guide:
*
* <ul>
* <li><a href=
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
* <b>How to Implement a Provider for the Java&trade; Cryptography Architecture
* </b></a></li>
* <li> {@extLink security_guide_impl_provider
* How to Implement a Provider in the Java Cryptography Architecture}</li>
* </ul>
*
* <h2>Package Specification</h2>
@ -57,10 +55,8 @@
* For further documentation, please see:
* <ul>
* <li>
* <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
* <b>Java&trade; Cryptography Architecture API Specification and Reference
* </b></a></li>
* {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}</li>
* </ul>
*
* @since 1.4

View File

@ -43,7 +43,7 @@
*
* <ul>
* <li><a href="{@docRoot}/../specs/security/standard-names.html">
* <b>Java&trade; Security Standard Algorithm Names Specification
* <b>Java Security Standard Algorithm Names Specification
* </b></a></li>
* </ul>
*
@ -52,15 +52,11 @@
* For further documentation, please see:
* <ul>
* <li>
* <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
* <b>Java&trade; Cryptography Architecture (JCA) Reference Guide
* </b></a></li>
* {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}</li>
* <li>
* <a href=
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
* <b>How to Implement a Provider in the Java&trade; Cryptography
* Architecture </b></a></li>
* {@extLink security_guide_impl_provider
* How to Implement a Provider in the Java Cryptography Architecture}</li>
* </ul>
*
* @since 1.4

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2017, 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
@ -81,9 +81,8 @@ public class SecretKeySpec implements KeySpec, SecretKey {
* the array are copied to protect against subsequent modification.
* @param algorithm the name of the secret-key algorithm to be associated
* with the given key material.
* See Appendix A in the <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture Reference Guide</a>
* See the <a href="{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
* @exception IllegalArgumentException if <code>algorithm</code>
* is null or <code>key</code> is null or empty.
@ -126,9 +125,8 @@ public class SecretKeySpec implements KeySpec, SecretKey {
* @param len the length of the key material.
* @param algorithm the name of the secret-key algorithm to be associated
* with the given key material.
* See Appendix A in the <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture Reference Guide</a>
* See the <a href="{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
* @exception IllegalArgumentException if <code>algorithm</code>
* is null or <code>key</code> is null, empty, or too short,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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
@ -57,16 +57,11 @@
*
* <ul>
* <li>
* <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html">
* <b>Java&trade; Cryptography Architecture API Specification and Reference
* </b></a></li>
* {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide} </li>
* <li>
* <a href=
* "{@docRoot}/../technotes/guides/security/crypto/HowToImplAProvider.html">
* <b>How to Implement a Provider for the
* Java&trade; Cryptography Architecture
* </b></a></li>
* {@extLink security_guide_impl_provider
* How to Implement a Provider in the Java Cryptography Architecture}</li>
* </ul>
*
* @since 1.4

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2017, 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
@ -44,9 +44,9 @@ public abstract class ExtendedSSLSession implements SSLSession {
* <p>
* The signature algorithm name must be a standard Java Security
* name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
* See Appendix A in the <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture API Specification &amp; Reference </a>
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
* <p>
* Note: the local supported signature algorithms should conform to
@ -72,9 +72,9 @@ public abstract class ExtendedSSLSession implements SSLSession {
* <p>
* The signature algorithm name must be a standard Java Security
* name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
* See Appendix A in the <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture API Specification &amp; Reference </a>
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @return An array of supported signature algorithms, in descending

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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
@ -127,8 +127,8 @@ public class KeyManagerFactory {
*
* @param algorithm the standard name of the requested algorithm.
* See the <a href=
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
* Java Secure Socket Extension Reference Guide </a>
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @return the new {@code KeyManagerFactory} object
@ -165,8 +165,8 @@ public class KeyManagerFactory {
* @param algorithm the standard name of the requested algorithm.
* See the <a href=
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
* Java Secure Socket Extension Reference Guide </a>
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@ -209,8 +209,8 @@ public class KeyManagerFactory {
*
* @param algorithm the standard name of the requested algorithm.
* See the <a href=
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
* Java Secure Socket Extension Reference Guide </a>
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @param provider an instance of the provider.

View File

@ -294,9 +294,10 @@ public class SSLParameters {
* SSL/TLS/DTLS handshaking. This is to prevent man-in-the-middle attacks.
*
* @param algorithm The standard string name of the endpoint
* identification algorithm (or null). See Appendix A in the <a href=
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
* Java Cryptography Architecture API Specification &amp; Reference </a>
* identification algorithm (or null).
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @see X509ExtendedTrustManager

View File

@ -141,8 +141,8 @@ public class TrustManagerFactory {
*
* @param algorithm the standard name of the requested trust management
* algorithm. See the <a href=
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
* Java Secure Socket Extension Reference Guide </a>
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @return the new {@code TrustManagerFactory} object
@ -179,8 +179,8 @@ public class TrustManagerFactory {
*
* @param algorithm the standard name of the requested trust management
* algorithm. See the <a href=
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
* Java Secure Socket Extension Reference Guide </a>
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @param provider the name of the provider.
@ -223,8 +223,8 @@ public class TrustManagerFactory {
*
* @param algorithm the standard name of the requested trust management
* algorithm. See the <a href=
* "{@docRoot}/../technotes/guides/security/jsse/JSSERefGuide.html">
* Java Secure Socket Extension Reference Guide </a>
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @param provider an instance of the provider.

View File

@ -49,8 +49,10 @@ import java.security.SecureClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.Attributes;
@ -336,16 +338,43 @@ public class BuiltinClassLoader
}
}
// search class path
// class path (not checked)
Enumeration<URL> e = findResourcesOnClassPath(name);
while (e.hasMoreElements()) {
URL url = checkURL(e.nextElement());
if (url != null) {
checked.add(url);
}
}
return Collections.enumeration(checked);
// concat the checked URLs and the (not checked) class path
return new Enumeration<>() {
final Iterator<URL> iterator = checked.iterator();
URL next;
private boolean hasNext() {
if (next != null) {
return true;
} else if (iterator.hasNext()) {
next = iterator.next();
return true;
} else {
// need to check each URL
while (e.hasMoreElements() && next == null) {
next = checkURL(e.nextElement());
}
return next != null;
}
}
@Override
public boolean hasMoreElements() {
return hasNext();
}
@Override
public URL nextElement() {
if (hasNext()) {
URL result = next;
next = null;
return result;
} else {
throw new NoSuchElementException();
}
}
};
}
/**

View File

@ -28,6 +28,7 @@ package jdk.internal.loader;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.module.Configuration;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleReader;
@ -52,11 +53,17 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.Resources;
@ -79,8 +86,8 @@ import jdk.internal.module.Resources;
* loader. This allows automatic modules (for example) to link to types in the
* unnamed module of the parent class loader.
*
* @see ModuleModuleLayer#defineModulesWithOneLoader
* @see ModuleModuleLayer#defineModulesWithManyLoaders
* @see ModuleLayer#defineModulesWithOneLoader
* @see ModuleLayer#defineModulesWithManyLoaders
*/
public final class Loader extends SecureClassLoader {
@ -303,7 +310,6 @@ public final class Loader extends SecureClassLoader {
// -- resources --
/**
* Returns a URL to a resource of the given name in a module defined to
* this class loader.
@ -388,33 +394,96 @@ public final class Loader extends SecureClassLoader {
@Override
public Enumeration<URL> findResources(String name) throws IOException {
List<URL> urls = new ArrayList<>();
return Collections.enumeration(findResourcesAsList(name));
}
@Override
public URL getResource(String name) {
Objects.requireNonNull(name);
// this loader
URL url = findResource(name);
if (url != null) {
return url;
} else {
// parent loader
return parent.getResource(name);
}
}
@Override
public Enumeration<URL> getResources(String name) throws IOException {
Objects.requireNonNull(name);
// this loader
List<URL> urls = findResourcesAsList(name);
// parent loader
Enumeration<URL> e = parent.getResources(name);
// concat the URLs with the URLs returned by the parent
return new Enumeration<>() {
final Iterator<URL> iterator = urls.iterator();
@Override
public boolean hasMoreElements() {
return (iterator.hasNext() || e.hasMoreElements());
}
@Override
public URL nextElement() {
if (iterator.hasNext()) {
return iterator.next();
} else {
return e.nextElement();
}
}
};
}
@Override
public Stream<URL> resources(String name) {
Objects.requireNonNull(name);
// ordering not specified
int characteristics = (Spliterator.NONNULL | Spliterator.IMMUTABLE |
Spliterator.SIZED | Spliterator.SUBSIZED);
Supplier<Spliterator<URL>> supplier = () -> {
try {
List<URL> urls = findResourcesAsList(name);
return Spliterators.spliterator(urls, characteristics);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
};
Stream<URL> s1 = StreamSupport.stream(supplier, characteristics, false);
Stream<URL> s2 = parent.resources(name);
return Stream.concat(s1, s2);
}
/**
* Finds the resources with the given name in this class loader.
*/
private List<URL> findResourcesAsList(String name) throws IOException {
String pn = Resources.toPackageName(name);
LoadedModule module = localPackageToModule.get(pn);
if (module != null) {
try {
URL url = findResource(module.name(), name);
if (url != null
URL url = findResource(module.name(), name);
if (url != null
&& (name.endsWith(".class")
|| url.toString().endsWith("/")
|| isOpen(module.mref(), pn))) {
urls.add(url);
}
} catch (IOException ioe) {
// ignore
|| url.toString().endsWith("/")
|| isOpen(module.mref(), pn))) {
return List.of(url);
} else {
return Collections.emptyList();
}
} else {
List<URL> urls = new ArrayList<>();
for (ModuleReference mref : nameToModule.values()) {
try {
URL url = findResource(mref.descriptor().name(), name);
if (url != null)
urls.add(url);
} catch (IOException ioe) {
// ignore
URL url = findResource(mref.descriptor().name(), name);
if (url != null) {
urls.add(url);
}
}
return urls;
}
return Collections.enumeration(urls);
}

View File

@ -32,6 +32,8 @@ import java.lang.reflect.Method;
import java.net.URI;
import java.security.AccessControlContext;
import java.security.ProtectionDomain;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
@ -44,13 +46,15 @@ import sun.nio.ch.Interruptible;
public interface JavaLangAccess {
/**
* Returns a {@code Method} object that reflects the specified public
* member method of the given class. Returns {@code null} if the
* method is not defined.
* Returns the list of {@code Method} objects for the declared public
* methods of this class or interface that have the specified method name
* and parameter types.
*/
Method getMethodOrNull(Class<?> klass, String name, Class<?>... parameterTypes);
List<Method> getDeclaredPublicMethods(Class<?> klass, String name, Class<?>... parameterTypes);
/** Return the constant pool for a class. */
/**
* Return the constant pool for a class.
*/
ConstantPool getConstantPool(Class<?> klass);
/**
@ -95,7 +99,9 @@ public interface JavaLangAccess {
*/
<E extends Enum<E>> E[] getEnumConstantsShared(Class<E> klass);
/** Set thread's blocker field. */
/**
* Set thread's blocker field.
*/
void blockedOn(Thread t, Interruptible b);
/**
@ -154,11 +160,6 @@ public interface JavaLangAccess {
*/
Class<?> findBootstrapClassOrNull(ClassLoader cl, String name);
/**
* Returns the Packages for the given class loader.
*/
Stream<Package> packages(ClassLoader cl);
/**
* Define a Package of the given name and module by the given class loader.
*/
@ -223,15 +224,30 @@ public interface JavaLangAccess {
void addOpens(Module m1, String pkg, Module m2);
/**
* Updates a module m to open a package to all unnamed modules.
* Updates module m to open a package to all unnamed modules.
*/
void addOpensToAllUnnamed(Module m, String pkg);
/**
* Updates a module m to use a service.
* Updates module m to open all packages returned by the given iterator.
*/
void addOpensToAllUnnamed(Module m, Iterator<String> packages);
/**
* Updates module m to use a service.
*/
void addUses(Module m, Class<?> service);
/**
* Returns true if module m reflectively exports a package to other
*/
boolean isReflectivelyExported(Module module, String pn, Module other);
/**
* Returns true if module m reflectively opens a package to other
*/
boolean isReflectivelyOpened(Module module, String pn, Module other);
/**
* Returns the ServicesCatalog for the given Layer.
*/

View File

@ -33,146 +33,240 @@ import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.StringJoiner;
import java.util.WeakHashMap;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import static java.util.Collections.*;
import jdk.internal.loader.BootLoader;
import sun.security.action.GetPropertyAction;
import jdk.internal.misc.JavaLangAccess;
import jdk.internal.misc.SharedSecrets;
/**
* Supports logging of access to members of API packages that are exported or
* opened via backdoor mechanisms to code in unnamed modules.
* Supports logging of access to members of exported and concealed packages
* that are opened to code in unnamed modules for illegal access.
*/
public final class IllegalAccessLogger {
/**
* Holder class to lazily create the StackWalker object and determine
* if the stack trace should be printed
* Logger modes
*/
static class Holder {
static final StackWalker STACK_WALKER;
static final boolean PRINT_STACK_TRACE;
public static enum Mode {
/**
* Prints a warning when an illegal access succeeds and then
* discards the logger so that there is no further output.
*/
ONESHOT,
/**
* Print warnings when illegal access succeeds
*/
WARN,
/**
* Prints warnings and a stack trace when illegal access succeeds
*/
DEBUG,
}
static {
PrivilegedAction<StackWalker> pa = () ->
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
STACK_WALKER = AccessController.doPrivileged(pa);
/**
* A builder for IllegalAccessLogger objects.
*/
public static class Builder {
private final Mode mode;
private final PrintStream warningStream;
private final Map<Module, Set<String>> moduleToConcealedPackages;
private final Map<Module, Set<String>> moduleToExportedPackages;
private boolean complete;
String name = "sun.reflect.debugModuleAccessChecks";
String value = GetPropertyAction.privilegedGetProperty(name, null);
PRINT_STACK_TRACE = "access" .equals(value);
private void ensureNotComplete() {
if (complete) throw new IllegalStateException();
}
/**
* Creates a builder.
*/
public Builder(Mode mode, PrintStream warningStream) {
this.mode = mode;
this.warningStream = warningStream;
this.moduleToConcealedPackages = new HashMap<>();
this.moduleToExportedPackages = new HashMap<>();
}
/**
* Adding logging of reflective-access to any member of a type in
* otherwise concealed packages.
*/
public Builder logAccessToConcealedPackages(Module m, Set<String> packages) {
ensureNotComplete();
moduleToConcealedPackages.put(m, unmodifiableSet(packages));
return this;
}
/**
* Adding logging of reflective-access to non-public members/types in
* otherwise exported (not open) packages.
*/
public Builder logAccessToExportedPackages(Module m, Set<String> packages) {
ensureNotComplete();
moduleToExportedPackages.put(m, unmodifiableSet(packages));
return this;
}
/**
* Builds the IllegalAccessLogger and sets it as the system-wise logger.
*/
public void complete() {
Map<Module, Set<String>> map1 = unmodifiableMap(moduleToConcealedPackages);
Map<Module, Set<String>> map2 = unmodifiableMap(moduleToExportedPackages);
logger = new IllegalAccessLogger(mode, warningStream, map1, map2);
complete = true;
}
}
// the maximum number of frames to capture
private static final int MAX_STACK_FRAMES = 32;
// need access to java.lang.Module
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
// lock to avoid interference when printing stack traces
private static final Object OUTPUT_LOCK = new Object();
// system-wide IllegalAccessLogger
private static volatile IllegalAccessLogger logger;
// caller -> usages
private final Map<Class<?>, Set<Usage>> callerToUsages = new WeakHashMap<>();
// module -> (package name -> CLI option)
private final Map<Module, Map<String, String>> exported;
private final Map<Module, Map<String, String>> opened;
// logger mode
private final Mode mode;
// the print stream to send the warnings
private final PrintStream warningStream;
private IllegalAccessLogger(Map<Module, Map<String, String>> exported,
Map<Module, Map<String, String>> opened,
PrintStream warningStream) {
this.exported = deepCopy(exported);
this.opened = deepCopy(opened);
// module -> packages open for illegal access
private final Map<Module, Set<String>> moduleToConcealedPackages;
private final Map<Module, Set<String>> moduleToExportedPackages;
// caller -> usages
private final Map<Class<?>, Usages> callerToUsages = new WeakHashMap<>();
private IllegalAccessLogger(Mode mode,
PrintStream warningStream,
Map<Module, Set<String>> moduleToConcealedPackages,
Map<Module, Set<String>> moduleToExportedPackages)
{
this.mode = mode;
this.warningStream = warningStream;
this.moduleToConcealedPackages = moduleToConcealedPackages;
this.moduleToExportedPackages = moduleToExportedPackages;
}
/**
* Returns that a Builder that is seeded with the packages known to this logger.
* Returns the system-wide IllegalAccessLogger or {@code null} if there is
* no logger.
*/
public Builder toBuilder() {
return new Builder(exported, opened);
public static IllegalAccessLogger illegalAccessLogger() {
return logger;
}
/**
* Returns true if the module exports a concealed package for illegal
* access.
*/
public boolean isExportedForIllegalAccess(Module module, String pn) {
Set<String> packages = moduleToConcealedPackages.get(module);
if (packages != null && packages.contains(pn))
return true;
return false;
}
/**
* Returns true if the module opens a concealed or exported package for
* illegal access.
*/
public boolean isOpenForIllegalAccess(Module module, String pn) {
if (isExportedForIllegalAccess(module, pn))
return true;
Set<String> packages = moduleToExportedPackages.get(module);
if (packages != null && packages.contains(pn))
return true;
return false;
}
/**
* Logs access to the member of a target class by a caller class if the class
* is in a package that is exported via a backdoor mechanism.
* is in a package that is exported for illegal access.
*
* The {@code whatSupplier} supplies the message that describes the member.
*/
public void logIfExportedByBackdoor(Class<?> caller,
Class<?> target,
Supplier<String> whatSupplier) {
Map<String, String> packages = exported.get(target.getModule());
if (packages != null) {
String how = packages.get(target.getPackageName());
if (how != null) {
log(caller, whatSupplier.get(), how);
public void logIfExportedForIllegalAccess(Class<?> caller,
Class<?> target,
Supplier<String> whatSupplier) {
Module targetModule = target.getModule();
String targetPackage = target.getPackageName();
if (isExportedForIllegalAccess(targetModule, targetPackage)) {
Module callerModule = caller.getModule();
if (!JLA.isReflectivelyExported(targetModule, targetPackage, callerModule)) {
log(caller, whatSupplier.get());
}
}
}
/**
* Logs access to the member of a target class by a caller class if the class
* is in a package that is opened via a backdoor mechanism.
* is in a package that is opened for illegal access.
*
* The {@code what} parameter supplies the message that describes the member.
*/
public void logIfOpenedByBackdoor(Class<?> caller,
Class<?> target,
Supplier<String> whatSupplier) {
Map<String, String> packages = opened.get(target.getModule());
if (packages != null) {
String how = packages.get(target.getPackageName());
if (how != null) {
log(caller, whatSupplier.get(), how);
public void logIfOpenedForIllegalAccess(Class<?> caller,
Class<?> target,
Supplier<String> whatSupplier) {
Module targetModule = target.getModule();
String targetPackage = target.getPackageName();
if (isOpenForIllegalAccess(targetModule, targetPackage)) {
Module callerModule = caller.getModule();
if (!JLA.isReflectivelyOpened(targetModule, targetPackage, callerModule)) {
log(caller, whatSupplier.get());
}
}
}
/**
* Logs access by caller lookup if the target class is in a package that is
* opened for illegal access.
*/
public void logIfOpenedForIllegalAccess(MethodHandles.Lookup caller, Class<?> target) {
Module targetModule = target.getModule();
String targetPackage = target.getPackageName();
if (isOpenForIllegalAccess(targetModule, targetPackage)) {
Class<?> callerClass = caller.lookupClass();
Module callerModule = callerClass.getModule();
if (!JLA.isReflectivelyOpened(targetModule, targetPackage, callerModule)) {
URL url = codeSource(callerClass);
final String source;
if (url == null) {
source = callerClass.getName();
} else {
source = callerClass.getName() + " (" + url + ")";
}
log(callerClass, target.getName(), () ->
"WARNING: Illegal reflective access using Lookup on " + source
+ " to " + target);
}
}
}
/**
* Logs access by a caller class. The {@code what} parameter describes
* the member is accessed, the {@code how} parameter is the means by which
* access is allocated (CLI option for example).
* the member being accessed.
*/
private void log(Class<?> caller, String what, String how) {
private void log(Class<?> caller, String what) {
log(caller, what, () -> {
PrivilegedAction<ProtectionDomain> pa = caller::getProtectionDomain;
CodeSource cs = AccessController.doPrivileged(pa).getCodeSource();
URL url = (cs != null) ? cs.getLocation() : null;
URL url = codeSource(caller);
String source = caller.getName();
if (url != null)
source += " (" + url + ")";
return "WARNING: Illegal access by " + source + " to " + what
+ " (permitted by " + how + ")";
return "WARNING: Illegal reflective access by " + source + " to " + what;
});
}
/**
* Logs access to caller class if the class is in a package that is opened via
* a backdoor mechanism.
*/
public void logIfOpenedByBackdoor(MethodHandles.Lookup caller, Class<?> target) {
Map<String, String> packages = opened.get(target.getModule());
if (packages != null) {
String how = packages.get(target.getPackageName());
if (how != null) {
log(caller.lookupClass(), target.getName(), () ->
"WARNING: Illegal access using Lookup on " + caller.lookupClass()
+ " to " + target + " (permitted by " + how + ")");
}
}
}
/**
* Log access by a caller. The {@code what} parameter describes the class or
* member that is being accessed. The {@code msgSupplier} supplies the log
@ -184,53 +278,73 @@ public final class IllegalAccessLogger {
* keys so it can be expunged when the caller is GC'ed/unloaded.
*/
private void log(Class<?> caller, String what, Supplier<String> msgSupplier) {
if (mode == Mode.ONESHOT) {
synchronized (IllegalAccessLogger.class) {
// discard the system wide logger
if (logger == null)
return;
logger = null;
}
warningStream.println(loudWarning(caller, msgSupplier));
return;
}
// stack trace without the top-most frames in java.base
List<StackWalker.StackFrame> stack = Holder.STACK_WALKER.walk(s ->
List<StackWalker.StackFrame> stack = StackWalkerHolder.INSTANCE.walk(s ->
s.dropWhile(this::isJavaBase)
.limit(MAX_STACK_FRAMES)
.limit(32)
.collect(Collectors.toList())
);
// check if the access has already been recorded
// record usage if this is the first (or not recently recorded)
Usage u = new Usage(what, hash(stack));
boolean firstUsage;
boolean added;
synchronized (this) {
firstUsage = callerToUsages.computeIfAbsent(caller, k -> new HashSet<>()).add(u);
added = callerToUsages.computeIfAbsent(caller, k -> new Usages()).add(u);
}
// log message if first usage
if (firstUsage) {
// print warning if this is the first (or not a recent) usage
if (added) {
String msg = msgSupplier.get();
if (Holder.PRINT_STACK_TRACE) {
synchronized (OUTPUT_LOCK) {
warningStream.println(msg);
stack.forEach(f -> warningStream.println("\tat " + f));
}
} else {
warningStream.println(msg);
if (mode == Mode.DEBUG) {
StringBuilder sb = new StringBuilder(msg);
stack.forEach(f ->
sb.append(System.lineSeparator()).append("\tat " + f)
);
msg = sb.toString();
}
warningStream.println(msg);
}
}
private static class Usage {
private final String what;
private final int stack;
Usage(String what, int stack) {
this.what = what;
this.stack = stack;
}
@Override
public int hashCode() {
return what.hashCode() ^ stack;
}
@Override
public boolean equals(Object ob) {
if (ob instanceof Usage) {
Usage that = (Usage)ob;
return what.equals(that.what) && stack == (that.stack);
} else {
return false;
}
/**
* Returns the code source for the given class or null if there is no code source
*/
private URL codeSource(Class<?> clazz) {
PrivilegedAction<ProtectionDomain> pa = clazz::getProtectionDomain;
CodeSource cs = AccessController.doPrivileged(pa).getCodeSource();
return (cs != null) ? cs.getLocation() : null;
}
private String loudWarning(Class<?> caller, Supplier<String> msgSupplier) {
StringJoiner sj = new StringJoiner(System.lineSeparator());
sj.add("WARNING: An illegal reflective access operation has occurred");
sj.add(msgSupplier.get());
sj.add("WARNING: Please consider reporting this to the maintainers of "
+ caller.getName());
sj.add("WARNING: Use --illegal-access=warn to enable warnings of further"
+ " illegal reflective access operations");
sj.add("WARNING: All illegal access operations will be denied in a"
+ " future release");
return sj.toString();
}
private static class StackWalkerHolder {
static final StackWalker INSTANCE;
static {
PrivilegedAction<StackWalker> pa = () ->
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
INSTANCE = AccessController.doPrivileged(pa);
}
}
@ -256,89 +370,39 @@ public final class IllegalAccessLogger {
return hash;
}
// system-wide IllegalAccessLogger
private static volatile IllegalAccessLogger logger;
/**
* Sets the system-wide IllegalAccessLogger
*/
public static void setIllegalAccessLogger(IllegalAccessLogger l) {
if (l.exported.isEmpty() && l.opened.isEmpty()) {
logger = null;
} else {
logger = l;
private static class Usage {
private final String what;
private final int stack;
Usage(String what, int stack) {
this.what = what;
this.stack = stack;
}
@Override
public int hashCode() {
return what.hashCode() ^ stack;
}
@Override
public boolean equals(Object ob) {
if (ob instanceof Usage) {
Usage that = (Usage)ob;
return what.equals(that.what) && stack == (that.stack);
} else {
return false;
}
}
}
/**
* Returns the system-wide IllegalAccessLogger or {@code null} if there is
* no logger.
*/
public static IllegalAccessLogger illegalAccessLogger() {
return logger;
}
/**
* A builder for IllegalAccessLogger objects.
*/
public static class Builder {
private final Module UNNAMED = BootLoader.getUnnamedModule();
private Map<Module, Map<String, String>> exported;
private Map<Module, Map<String, String>> opened;
private PrintStream warningStream = System.err;
public Builder() { }
public Builder(Map<Module, Map<String, String>> exported,
Map<Module, Map<String, String>> opened) {
this.exported = deepCopy(exported);
this.opened = deepCopy(opened);
@SuppressWarnings("serial")
private static class Usages extends LinkedHashMap<Usage, Boolean> {
Usages() { }
boolean add(Usage u) {
return (putIfAbsent(u, Boolean.TRUE) == null);
}
public Builder logAccessToExportedPackage(Module m, String pn, String how) {
if (!m.isExported(pn, UNNAMED)) {
if (exported == null)
exported = new HashMap<>();
exported.computeIfAbsent(m, k -> new HashMap<>()).putIfAbsent(pn, how);
}
return this;
}
public Builder logAccessToOpenPackage(Module m, String pn, String how) {
// opens implies exported at run-time.
logAccessToExportedPackage(m, pn, how);
if (!m.isOpen(pn, UNNAMED)) {
if (opened == null)
opened = new HashMap<>();
opened.computeIfAbsent(m, k -> new HashMap<>()).putIfAbsent(pn, how);
}
return this;
}
public Builder warningStream(PrintStream warningStream) {
this.warningStream = Objects.requireNonNull(warningStream);
return this;
}
/**
* Builds the logger.
*/
public IllegalAccessLogger build() {
return new IllegalAccessLogger(exported, opened, warningStream);
}
}
static Map<Module, Map<String, String>> deepCopy(Map<Module, Map<String, String>> map) {
if (map == null || map.isEmpty()) {
return new HashMap<>();
} else {
Map<Module, Map<String, String>> newMap = new HashMap<>();
for (Map.Entry<Module, Map<String, String>> e : map.entrySet()) {
newMap.put(e.getKey(), new HashMap<>(e.getValue()));
}
return newMap;
@Override
protected boolean removeEldestEntry(Map.Entry<Usage, Boolean> oldest) {
// prevent map growing too big, say where a utility class
// is used by generated code to do illegal access
return size() > 16;
}
}
}

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 2017, 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 jdk.internal.module;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static java.nio.charset.StandardCharsets.*;
/**
* Generates the maps of concealed and exported packages to open at run-time.
*
* This is used at run-time for exploded builds, and at link-time to generate
* the maps for the system modules in the run-time image.
*/
public class IllegalAccessMaps {
private final Map<String, Set<String>> concealedPackagesToOpen;
private final Map<String, Set<String>> exportedPackagesToOpen;
private IllegalAccessMaps(Map<String, Set<String>> map1,
Map<String, Set<String>> map2) {
this.concealedPackagesToOpen = map1;
this.exportedPackagesToOpen = map2;
}
/**
* Returns the map of concealed packages to open. The map key is the
* module name, the value is the set of concealed packages to open.
*/
public Map<String, Set<String>> concealedPackagesToOpen() {
return concealedPackagesToOpen;
}
/**
* Returns the map of exported packages to open. The map key is the
* module name, the value is the set of exported packages to open.
*/
public Map<String, Set<String>> exportedPackagesToOpen() {
return exportedPackagesToOpen;
}
/**
* Generate the maps of module to concealed and exported packages for
* the system modules that are observable with the given module finder.
*/
public static IllegalAccessMaps generate(ModuleFinder finder) {
Map<String, ModuleDescriptor> map = new HashMap<>();
finder.findAll().stream()
.map(ModuleReference::descriptor)
.forEach(md -> md.packages().forEach(pn -> map.putIfAbsent(pn, md)));
Map<String, Set<String>> concealedPackagesToOpen = new HashMap<>();
Map<String, Set<String>> exportedPackagesToOpen = new HashMap<>();
String rn = "jdk8_packages.dat";
InputStream in = IllegalAccessMaps.class.getResourceAsStream(rn);
if (in == null) {
throw new InternalError(rn + " not found");
}
try (BufferedReader br = new BufferedReader(new InputStreamReader(in, UTF_8))) {
br.lines()
.filter(line -> !line.isEmpty() && !line.startsWith("#"))
.forEach(pn -> {
ModuleDescriptor descriptor = map.get(pn);
if (descriptor != null && !isOpen(descriptor, pn)) {
String name = descriptor.name();
if (isExported(descriptor, pn)) {
exportedPackagesToOpen.computeIfAbsent(name,
k -> new HashSet<>()).add(pn);
} else {
concealedPackagesToOpen.computeIfAbsent(name,
k -> new HashSet<>()).add(pn);
}
}
});
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
return new IllegalAccessMaps(concealedPackagesToOpen, exportedPackagesToOpen);
}
private static boolean isExported(ModuleDescriptor descriptor, String pn) {
return descriptor.exports()
.stream()
.anyMatch(e -> e.source().equals(pn) && !e.isQualified());
}
private static boolean isOpen(ModuleDescriptor descriptor, String pn) {
return descriptor.opens()
.stream()
.anyMatch(e -> e.source().equals(pn) && !e.isQualified());
}
}

View File

@ -39,14 +39,17 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.misc.JavaLangAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.perf.PerfCounter;
@ -59,7 +62,7 @@ import jdk.internal.perf.PerfCounter;
* -m and --add-modules options. The modules are located on a module path that
* is constructed from the upgrade module path, system modules, and application
* module path. The Configuration is instantiated as the boot layer with each
* module in the the configuration defined to one of the built-in class loaders.
* module in the the configuration defined to a class loader.
*/
public final class ModuleBootstrap {
@ -119,20 +122,20 @@ public final class ModuleBootstrap {
*/
public static ModuleLayer boot() {
long t0 = System.nanoTime();
// system modules (may be patched)
ModuleFinder systemModules = ModuleFinder.ofSystem();
PerfCounters.systemModulesTime.addElapsedTimeFrom(t0);
// Step 1: Locate system modules (may be patched)
long t1 = System.nanoTime();
ModuleFinder systemModules = ModuleFinder.ofSystem();
PerfCounters.systemModulesTime.addElapsedTimeFrom(t1);
// Step 2: Define and load java.base. This patches all classes loaded
// to date so that they are members of java.base. Once java.base is
// loaded then resources in java.base are available for error messages
// needed from here on.
long t2 = System.nanoTime();
// Once we have the system modules then we define the base module to
// the VM. We do this here so that java.base is defined as early as
// possible and also that resources in the base module can be located
// for error messages that may happen from here on.
ModuleReference base = systemModules.find(JAVA_BASE).orElse(null);
if (base == null)
throw new InternalError(JAVA_BASE + " not found");
@ -142,15 +145,23 @@ public final class ModuleBootstrap {
BootLoader.loadModule(base);
Modules.defineModule(null, base.descriptor(), baseUri);
PerfCounters.defineBaseTime.addElapsedTimeFrom(t1);
PerfCounters.defineBaseTime.addElapsedTimeFrom(t2);
// Step 2a: If --validate-modules is specified then the VM needs to
// start with only java.base, all other options are ignored.
// special mode to boot with only java.base, ignores other options
String propValue = getAndRemoveProperty("jdk.module.minimumBoot");
if (propValue != null) {
return createMinimalBootLayer();
}
long t2 = System.nanoTime();
// Step 3: Construct the module path and the set of root modules to
// resolve. If --limit-modules is specified then it limits the set
// modules that are observable.
long t3 = System.nanoTime();
// --upgrade-module-path option specified to launcher
ModuleFinder upgradeModulePath
@ -269,10 +280,13 @@ public final class ModuleBootstrap {
.forEach(mn -> roots.add(mn));
}
PerfCounters.optionsAndRootsTime.addElapsedTimeFrom(t2);
PerfCounters.optionsAndRootsTime.addElapsedTimeFrom(t3);
long t3 = System.nanoTime();
// Step 4: Resolve the root modules, with service binding, to create
// the configuration for the boot layer.
long t4 = System.nanoTime();
// determine if post resolution checks are needed
boolean needPostResolutionChecks = true;
@ -295,11 +309,17 @@ public final class ModuleBootstrap {
needPostResolutionChecks,
traceOutput);
// time to create configuration
PerfCounters.resolveTime.addElapsedTimeFrom(t3);
PerfCounters.resolveTime.addElapsedTimeFrom(t4);
// check module names and incubating status
checkModuleNamesAndStatus(cf);
// Step 5: Map the modules in the configuration to class loaders.
// The static configuration provides the mapping of standard and JDK
// modules to the boot and platform loaders. All other modules (JDK
// tool modules, and both explicit and automatic modules on the
// application module path) are defined to the application class
// loader.
long t5 = System.nanoTime();
// mapping of modules to class loaders
Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
@ -312,11 +332,9 @@ public final class ModuleBootstrap {
String name = mref.descriptor().name();
ClassLoader cl = clf.apply(name);
if (cl == null) {
if (upgradeModulePath != null
&& upgradeModulePath.find(name).isPresent())
fail(name + ": cannot be loaded from upgrade module path");
if (!systemModules.find(name).isPresent())
fail(name + ": cannot be loaded from application module path");
}
@ -330,55 +348,38 @@ public final class ModuleBootstrap {
}
}
// if needed check that there are no split packages in the set of
// resolved modules for the boot layer
// check for split packages in the modules mapped to the built-in loaders
if (SystemModules.hasSplitPackages() || needPostResolutionChecks) {
Map<String, String> packageToModule = new HashMap<>();
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
String name = descriptor.name();
for (String p : descriptor.packages()) {
String other = packageToModule.putIfAbsent(p, name);
if (other != null) {
String msg = "Package " + p + " in both module "
+ name + " and module " + other;
throw new LayerInstantiationException(msg);
}
}
}
checkSplitPackages(cf, clf);
}
long t4 = System.nanoTime();
// define modules to VM/runtime
ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
PerfCounters.layerCreateTime.addElapsedTimeFrom(t4);
long t5 = System.nanoTime();
// define the module to its class loader, except java.base
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleReference mref = resolvedModule.reference();
String name = mref.descriptor().name();
ClassLoader cl = clf.apply(name);
if (cl == null) {
if (!name.equals(JAVA_BASE)) BootLoader.loadModule(mref);
} else {
((BuiltinClassLoader)cl).loadModule(mref);
}
}
// load/register the modules with the built-in class loaders
loadModules(cf, clf);
PerfCounters.loadModulesTime.addElapsedTimeFrom(t5);
// --add-reads, --add-exports/--add-opens
// Step 6: Define all modules to the VM
long t6 = System.nanoTime();
ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
PerfCounters.layerCreateTime.addElapsedTimeFrom(t6);
// Step 7: Miscellaneous
// check incubating status
checkIncubatingStatus(cf);
// --add-reads, --add-exports/--add-opens, and -illegal-access
long t7 = System.nanoTime();
addExtraReads(bootLayer);
addExtraExportsAndOpens(bootLayer);
boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
addIllegalAccess(bootLayer, upgradeModulePath, extraExportsOrOpens);
PerfCounters.adjustModulesTime.addElapsedTimeFrom(t7);
// total time to initialize
PerfCounters.bootstrapTime.addElapsedTimeFrom(t0);
PerfCounters.bootstrapTime.addElapsedTimeFrom(t1);
return bootLayer;
}
@ -397,6 +398,51 @@ public final class ModuleBootstrap {
return ModuleLayer.empty().defineModules(cf, clf);
}
/**
* Load/register the modules to the built-in class loaders.
*/
private static void loadModules(Configuration cf,
Function<String, ClassLoader> clf) {
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleReference mref = resolvedModule.reference();
String name = resolvedModule.name();
ClassLoader loader = clf.apply(name);
if (loader == null) {
// skip java.base as it is already loaded
if (!name.equals(JAVA_BASE)) {
BootLoader.loadModule(mref);
}
} else if (loader instanceof BuiltinClassLoader) {
((BuiltinClassLoader) loader).loadModule(mref);
}
}
}
/**
* Checks for split packages between modules defined to the built-in class
* loaders.
*/
private static void checkSplitPackages(Configuration cf,
Function<String, ClassLoader> clf) {
Map<String, String> packageToModule = new HashMap<>();
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
String name = descriptor.name();
ClassLoader loader = clf.apply(name);
if (loader == null || loader instanceof BuiltinClassLoader) {
for (String p : descriptor.packages()) {
String other = packageToModule.putIfAbsent(p, name);
if (other != null) {
String msg = "Package " + p + " in both module "
+ name + " and module " + other;
throw new LayerInstantiationException(msg);
}
}
}
}
}
/**
* Returns a ModuleFinder that limits observability to the given root
* modules, their transitive dependences, plus a set of other modules.
@ -458,15 +504,14 @@ public final class ModuleBootstrap {
}
}
/**
* Initialize the module patcher for the initial configuration passed on the
* value of the --patch-module options.
*/
private static ModulePatcher initModulePatcher() {
Map<String, List<String>> map = decode("jdk.module.patch.",
File.pathSeparator,
false);
File.pathSeparator,
false);
return new ModulePatcher(map);
}
@ -538,38 +583,27 @@ public final class ModuleBootstrap {
* Process the --add-exports and --add-opens options to export/open
* additional packages specified on the command-line.
*/
private static void addExtraExportsAndOpens(ModuleLayer bootLayer) {
private static boolean addExtraExportsAndOpens(ModuleLayer bootLayer) {
boolean extraExportsOrOpens = false;
// --add-exports
String prefix = "jdk.module.addexports.";
Map<String, List<String>> extraExports = decode(prefix);
if (!extraExports.isEmpty()) {
addExtraExportsOrOpens(bootLayer, extraExports, false);
extraExportsOrOpens = true;
}
// --add-opens
prefix = "jdk.module.addopens.";
Map<String, List<String>> extraOpens = decode(prefix);
if (!extraOpens.isEmpty()) {
addExtraExportsOrOpens(bootLayer, extraOpens, true);
extraExportsOrOpens = true;
}
// --permit-illegal-access
if (getAndRemoveProperty("jdk.module.permitIllegalAccess") != null) {
warn("--permit-illegal-access will be removed in the next major release");
IllegalAccessLogger.Builder builder = new IllegalAccessLogger.Builder();
Module unnamed = BootLoader.getUnnamedModule();
bootLayer.modules().stream().forEach(m -> {
m.getDescriptor()
.packages()
.stream()
.filter(pn -> !m.isOpen(pn, unnamed)) // skip if opened by --add-opens
.forEach(pn -> {
builder.logAccessToOpenPackage(m, pn, "--permit-illegal-access");
Modules.addOpensToAllUnnamed(m, pn);
});
});
IllegalAccessLogger.setIllegalAccessLogger(builder.build());
}
return extraExportsOrOpens;
}
private static void addExtraExportsOrOpens(ModuleLayer bootLayer,
@ -638,6 +672,102 @@ public final class ModuleBootstrap {
}
}
/**
* Process the --illegal-access option (and its default) to open packages
* of system modules in the boot layer to code in unnamed modules.
*/
private static void addIllegalAccess(ModuleLayer bootLayer,
ModuleFinder upgradeModulePath,
boolean extraExportsOrOpens) {
String value = getAndRemoveProperty("jdk.module.illegalAccess");
IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
if (value != null) {
switch (value) {
case "deny":
return;
case "permit":
break;
case "warn":
mode = IllegalAccessLogger.Mode.WARN;
break;
case "debug":
mode = IllegalAccessLogger.Mode.DEBUG;
break;
default:
fail("Value specified to --illegal-access not recognized:"
+ " '" + value + "'");
return;
}
}
IllegalAccessLogger.Builder builder
= new IllegalAccessLogger.Builder(mode, System.err);
Map<String, Set<String>> map1 = SystemModules.concealedPackagesToOpen();
Map<String, Set<String>> map2 = SystemModules.exportedPackagesToOpen();
if (map1.isEmpty() && map2.isEmpty()) {
// need to generate maps when on exploded build
IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
map1 = maps.concealedPackagesToOpen();
map2 = maps.exportedPackagesToOpen();
}
// open specific packages in the system modules
for (Module m : bootLayer.modules()) {
ModuleDescriptor descriptor = m.getDescriptor();
String name = m.getName();
// skip open modules
if (descriptor.isOpen()) {
continue;
}
// skip modules loaded from the upgrade module path
if (upgradeModulePath != null
&& upgradeModulePath.find(name).isPresent()) {
continue;
}
Set<String> concealedPackages = map1.getOrDefault(name, Set.of());
Set<String> exportedPackages = map2.getOrDefault(name, Set.of());
// refresh the set of concealed and exported packages if needed
if (extraExportsOrOpens) {
concealedPackages = new HashSet<>(concealedPackages);
exportedPackages = new HashSet<>(exportedPackages);
Iterator<String> iterator = concealedPackages.iterator();
while (iterator.hasNext()) {
String pn = iterator.next();
if (m.isExported(pn, BootLoader.getUnnamedModule())) {
// concealed package is exported to ALL-UNNAMED
iterator.remove();
exportedPackages.add(pn);
}
}
iterator = exportedPackages.iterator();
while (iterator.hasNext()) {
String pn = iterator.next();
if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
// exported package is opened to ALL-UNNAMED
iterator.remove();
}
}
}
// log reflective access to all types in concealed packages
builder.logAccessToConcealedPackages(m, concealedPackages);
// log reflective access to non-public members/types in exported packages
builder.logAccessToExportedPackages(m, exportedPackages);
// open the packages to unnamed modules
JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
jla.addOpensToAllUnnamed(m, concat(concealedPackages.iterator(),
exportedPackages.iterator()));
}
builder.complete();
}
/**
* Decodes the values of --add-reads, -add-exports, --add-opens or
* --patch-modules options that are encoded in system properties.
@ -708,17 +838,16 @@ public final class ModuleBootstrap {
}
/**
* Checks the names and resolution bit of each module in the configuration,
* emitting warnings if needed.
* Checks incubating status of modules in the configuration
*/
private static void checkModuleNamesAndStatus(Configuration cf) {
private static void checkIncubatingStatus(Configuration cf) {
String incubating = null;
for (ResolvedModule rm : cf.modules()) {
ModuleReference mref = rm.reference();
String mn = mref.descriptor().name();
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleReference mref = resolvedModule.reference();
// emit warning if the WARN_INCUBATING module resolution bit set
if (ModuleResolution.hasIncubatingWarning(mref)) {
String mn = mref.descriptor().name();
if (incubating == null) {
incubating = mn;
} else {
@ -777,6 +906,21 @@ public final class ModuleBootstrap {
}
}
static <T> Iterator<T> concat(Iterator<T> iterator1, Iterator<T> iterator2) {
return new Iterator<T>() {
@Override
public boolean hasNext() {
return iterator1.hasNext() || iterator2.hasNext();
}
@Override
public T next() {
if (iterator1.hasNext()) return iterator1.next();
if (iterator2.hasNext()) return iterator2.next();
throw new NoSuchElementException();
}
};
}
static class PerfCounters {
static PerfCounter systemModulesTime
@ -791,6 +935,8 @@ public final class ModuleBootstrap {
= PerfCounter.newPerfCounter("jdk.module.bootstrap.layerCreateTime");
static PerfCounter loadModulesTime
= PerfCounter.newPerfCounter("jdk.module.bootstrap.loadModulesTime");
static PerfCounter adjustModulesTime
= PerfCounter.newPerfCounter("jdk.module.bootstrap.adjustModulesTime");
static PerfCounter bootstrapTime
= PerfCounter.newPerfCounter("jdk.module.bootstrap.totalTime");
}

View File

@ -35,6 +35,7 @@ import java.io.UncheckedIOException;
import java.lang.module.FindException;
import java.lang.module.InvalidModuleDescriptorException;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleDescriptor.Builder;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.net.URI;
@ -404,6 +405,9 @@ public class ModulePath implements ModuleFinder {
private static final String SERVICES_PREFIX = "META-INF/services/";
private static final Attributes.Name AUTOMATIC_MODULE_NAME
= new Attributes.Name("Automatic-Module-Name");
/**
* Returns the service type corresponding to the name of a services
* configuration file if it is a legal type name.
@ -445,48 +449,68 @@ public class ModulePath implements ModuleFinder {
/**
* Treat the given JAR file as a module as follows:
*
* 1. The module name (and optionally the version) is derived from the file
* name of the JAR file
* 2. All packages are derived from the .class files in the JAR file
* 3. The contents of any META-INF/services configuration files are mapped
* 1. The value of the Automatic-Module-Name attribute is the module name
* 2. The version, and the module name when the Automatic-Module-Name
* attribute is not present, is derived from the file ame of the JAR file
* 3. All packages are derived from the .class files in the JAR file
* 4. The contents of any META-INF/services configuration files are mapped
* to "provides" declarations
* 4. The Main-Class attribute in the main attributes of the JAR manifest
* 5. The Main-Class attribute in the main attributes of the JAR manifest
* is mapped to the module descriptor mainClass if possible
*/
private ModuleDescriptor deriveModuleDescriptor(JarFile jf)
throws IOException
{
// Derive module name and version from JAR file name
// Read Automatic-Module-Name attribute if present
Manifest man = jf.getManifest();
Attributes attrs = null;
String moduleName = null;
if (man != null) {
attrs = man.getMainAttributes();
if (attrs != null) {
moduleName = attrs.getValue(AUTOMATIC_MODULE_NAME);
}
}
// Derive the version, and the module name if needed, from JAR file name
String fn = jf.getName();
int i = fn.lastIndexOf(File.separator);
if (i != -1)
fn = fn.substring(i+1);
fn = fn.substring(i + 1);
// drop .jar
String mn = fn.substring(0, fn.length()-4);
// drop ".jar"
String name = fn.substring(0, fn.length() - 4);
String vs = null;
// find first occurrence of -${NUMBER}. or -${NUMBER}$
Matcher matcher = Patterns.DASH_VERSION.matcher(mn);
Matcher matcher = Patterns.DASH_VERSION.matcher(name);
if (matcher.find()) {
int start = matcher.start();
// attempt to parse the tail as a version string
try {
String tail = mn.substring(start+1);
String tail = name.substring(start + 1);
ModuleDescriptor.Version.parse(tail);
vs = tail;
} catch (IllegalArgumentException ignore) { }
mn = mn.substring(0, start);
name = name.substring(0, start);
}
// finally clean up the module name
mn = cleanModuleName(mn);
// Create builder, using the name derived from file name when
// Automatic-Module-Name not present
Builder builder;
if (moduleName != null) {
try {
builder = ModuleDescriptor.newAutomaticModule(moduleName);
} catch (IllegalArgumentException e) {
throw new FindException(AUTOMATIC_MODULE_NAME + ": " + e.getMessage());
}
} else {
builder = ModuleDescriptor.newAutomaticModule(cleanModuleName(name));
}
// Builder throws IAE if module name is empty or invalid
ModuleDescriptor.Builder builder = ModuleDescriptor.newAutomaticModule(mn);
// module version if present
if (vs != null)
builder.version(vs);
@ -541,9 +565,7 @@ public class ModulePath implements ModuleFinder {
}
// Main-Class attribute if it exists
Manifest man = jf.getManifest();
if (man != null) {
Attributes attrs = man.getMainAttributes();
if (attrs != null) {
String mainClass = attrs.getValue(Attributes.Name.MAIN_CLASS);
if (mainClass != null) {
mainClass = mainClass.replace("/", ".");

View File

@ -41,6 +41,10 @@ import java.util.function.Supplier;
public class ModuleReferenceImpl extends ModuleReference {
// location of module
private final URI location;
// the module reader
private final Supplier<ModuleReader> readerSupplier;
// non-null if the module is patched
@ -74,6 +78,7 @@ public class ModuleReferenceImpl extends ModuleReference {
ModuleResolution moduleResolution)
{
super(descriptor, Objects.requireNonNull(location));
this.location = location;
this.readerSupplier = readerSupplier;
this.patcher = patcher;
this.target = target;
@ -148,7 +153,7 @@ public class ModuleReferenceImpl extends ModuleReference {
int hc = hash;
if (hc == 0) {
hc = descriptor().hashCode();
hc = 43 * hc + Objects.hashCode(location());
hc = 43 * hc + Objects.hashCode(location);
hc = 43 * hc + Objects.hashCode(patcher);
if (hc == 0)
hc = -1;
@ -169,7 +174,7 @@ public class ModuleReferenceImpl extends ModuleReference {
// when the modules have equal module descriptors, are at the
// same location, and are patched by the same patcher.
return Objects.equals(this.descriptor(), that.descriptor())
&& Objects.equals(this.location(), that.location())
&& Objects.equals(this.location, that.location)
&& Objects.equals(this.patcher, that.patcher);
}
@ -179,7 +184,7 @@ public class ModuleReferenceImpl extends ModuleReference {
sb.append("[module ");
sb.append(descriptor().name());
sb.append(", location=");
sb.append(location().orElseThrow(() -> new InternalError()));
sb.append(location);
if (isPatched()) sb.append(" (patched)");
sb.append("]");
return sb.toString();

View File

@ -136,10 +136,12 @@ public class Modules {
public static void addProvides(Module m, Class<?> service, Class<?> impl) {
ModuleLayer layer = m.getLayer();
if (layer == null || layer == ModuleLayer.boot()) {
PrivilegedAction<ClassLoader> pa = m::getClassLoader;
ClassLoader loader = AccessController.doPrivileged(pa);
ClassLoader platformClassLoader = ClassLoaders.platformClassLoader();
if (layer == null || loader == null || loader == platformClassLoader) {
// update ClassLoader catalog
PrivilegedAction<ClassLoader> pa = m::getClassLoader;
ClassLoader loader = AccessController.doPrivileged(pa);
ServicesCatalog catalog;
if (loader == null) {
catalog = BootLoader.getServicesCatalog();

View File

@ -26,6 +26,9 @@
package jdk.internal.module;
import java.lang.module.ModuleDescriptor;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
/**
* SystemModules class will be generated at link time to create
@ -57,8 +60,7 @@ public final class SystemModules {
public static int PACKAGES_IN_BOOT_LAYER = 1024;
/**
* @return {@code false} if there are no split packages in the run-time
* image, {@code true} if there are or if it's not been checked.
* Return true if there are no split packages in the run-time image.
*/
public static boolean hasSplitPackages() {
return true;
@ -98,4 +100,20 @@ public final class SystemModules {
public static ModuleResolution[] moduleResolutions() {
throw new InternalError("expected to be overridden at link time");
}
/**
* Returns the map of module concealed packages to open. The map key is the
* module name, the value is the set of concealed packages to open.
*/
public static Map<String, Set<String>> concealedPackagesToOpen() {
return Collections.emptyMap();
}
/**
* Returns the map of module exported packages to open. The map key is the
* module name, the value is the set of exported packages to open.
*/
public static Map<String, Set<String>> exportedPackagesToOpen() {
return Collections.emptyMap();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -129,37 +129,6 @@ module java.base {
exports javax.security.cert;
// the service types defined by the APIs in this module
uses java.lang.System.LoggerFinder;
uses java.net.ContentHandlerFactory;
uses java.net.spi.URLStreamHandlerProvider;
uses java.nio.channels.spi.AsynchronousChannelProvider;
uses java.nio.channels.spi.SelectorProvider;
uses java.nio.charset.spi.CharsetProvider;
uses java.nio.file.spi.FileSystemProvider;
uses java.nio.file.spi.FileTypeDetector;
uses java.security.Provider;
uses java.text.spi.BreakIteratorProvider;
uses java.text.spi.CollatorProvider;
uses java.text.spi.DateFormatProvider;
uses java.text.spi.DateFormatSymbolsProvider;
uses java.text.spi.DecimalFormatSymbolsProvider;
uses java.text.spi.NumberFormatProvider;
uses java.time.chrono.AbstractChronology;
uses java.time.chrono.Chronology;
uses java.time.zone.ZoneRulesProvider;
uses java.util.spi.CalendarDataProvider;
uses java.util.spi.CalendarNameProvider;
uses java.util.spi.CurrencyNameProvider;
uses java.util.spi.LocaleNameProvider;
uses java.util.spi.ResourceBundleControlProvider;
uses java.util.spi.ResourceBundleProvider;
uses java.util.spi.TimeZoneNameProvider;
uses java.util.spi.ToolProvider;
uses javax.security.auth.spi.LoginModule;
// additional qualified exports may be inserted at build time
// see make/gensrc/GenModuleInfo.gmk
@ -192,11 +161,6 @@ module java.base {
jdk.scripting.nashorn;
exports jdk.internal.math to
java.desktop;
exports jdk.internal.module to
java.instrument,
java.management.rmi,
jdk.jartool,
jdk.jlink;
exports jdk.internal.misc to
java.desktop,
java.logging,
@ -218,6 +182,11 @@ module java.base {
jdk.scripting.nashorn.shell,
jdk.unsupported,
jdk.internal.vm.ci;
exports jdk.internal.module to
java.instrument,
java.management.rmi,
jdk.jartool,
jdk.jlink;
exports jdk.internal.perf to
java.desktop,
java.management,
@ -233,6 +202,9 @@ module java.base {
jdk.dynalink,
jdk.scripting.nashorn,
jdk.unsupported;
exports jdk.internal.vm to
jdk.management.agent,
jdk.internal.jvmstat;
exports jdk.internal.vm.annotation to
jdk.unsupported,
jdk.internal.vm.ci,
@ -241,9 +213,6 @@ module java.base {
jdk.jartool,
jdk.jdeps,
jdk.jlink;
exports jdk.internal.vm to
jdk.management.agent,
jdk.internal.jvmstat;
exports sun.net to
jdk.incubator.httpclient;
exports sun.net.ext to
@ -253,7 +222,8 @@ module java.base {
jdk.naming.dns;
exports sun.net.util to
java.desktop,
jdk.jconsole;
jdk.jconsole,
jdk.incubator.httpclient;
exports sun.net.www to
java.desktop,
jdk.incubator.httpclient,
@ -349,7 +319,39 @@ module java.base {
exports sun.util.resources to
jdk.localedata;
// the service types defined by the APIs in this module
uses java.lang.System.LoggerFinder;
uses java.net.ContentHandlerFactory;
uses java.net.spi.URLStreamHandlerProvider;
uses java.nio.channels.spi.AsynchronousChannelProvider;
uses java.nio.channels.spi.SelectorProvider;
uses java.nio.charset.spi.CharsetProvider;
uses java.nio.file.spi.FileSystemProvider;
uses java.nio.file.spi.FileTypeDetector;
uses java.security.Provider;
uses java.text.spi.BreakIteratorProvider;
uses java.text.spi.CollatorProvider;
uses java.text.spi.DateFormatProvider;
uses java.text.spi.DateFormatSymbolsProvider;
uses java.text.spi.DecimalFormatSymbolsProvider;
uses java.text.spi.NumberFormatProvider;
uses java.time.chrono.AbstractChronology;
uses java.time.chrono.Chronology;
uses java.time.zone.ZoneRulesProvider;
uses java.util.spi.CalendarDataProvider;
uses java.util.spi.CalendarNameProvider;
uses java.util.spi.CurrencyNameProvider;
uses java.util.spi.LocaleNameProvider;
uses java.util.spi.ResourceBundleControlProvider;
uses java.util.spi.ResourceBundleProvider;
uses java.util.spi.TimeZoneNameProvider;
uses java.util.spi.ToolProvider;
uses javax.security.auth.spi.LoginModule;
// JDK-internal service types
uses jdk.internal.logger.DefaultLoggerFinder;
uses sun.security.ssl.ClientKeyExchangeService;
uses sun.text.spi.JavaTimeDateTimePatternProvider;
@ -358,7 +360,6 @@ module java.base {
uses sun.util.resources.LocaleData.CommonResourceBundleProvider;
uses sun.util.resources.LocaleData.SupplementaryResourceBundleProvider;
// Built-in service providers that are located via ServiceLoader
provides java.nio.file.spi.FileSystemProvider with

View File

@ -92,7 +92,6 @@ import jdk.internal.misc.VM;
import jdk.internal.module.ModuleBootstrap;
import jdk.internal.module.Modules;
public final class LauncherHelper {
// No instantiation
@ -488,16 +487,16 @@ public final class LauncherHelper {
if (s.length == 2) {
String mn = s[0];
String pn = s[1];
ModuleLayer.boot().findModule(mn).ifPresent(m -> {
if (m.getDescriptor().packages().contains(pn)) {
ModuleLayer.boot()
.findModule(mn)
.filter(m -> m.getDescriptor().packages().contains(pn))
.ifPresent(m -> {
if (open) {
Modules.addOpensToAllUnnamed(m, pn);
} else {
Modules.addExportsToAllUnnamed(m, pn);
}
}
});
});
}
}
}
@ -614,7 +613,7 @@ public final class LauncherHelper {
}
} catch (LinkageError le) {
abort(null, "java.launcher.module.error3", mainClass, m.getName(),
le.getClass().getName() + ": " + le.getLocalizedMessage());
le.getClass().getName() + ": " + le.getLocalizedMessage());
}
if (c == null) {
abort(null, "java.launcher.module.error2", mainClass, mainModule);
@ -715,7 +714,7 @@ public final class LauncherHelper {
mainClass.getName(), mainClass.getModule(),
e.getClass().getName(), e.getLocalizedMessage());
} else {
abort(e,"java.launcher.cls.error7", mainClass.getName(),
abort(e, "java.launcher.cls.error7", mainClass.getName(),
e.getClass().getName(), e.getLocalizedMessage());
}
}

View File

@ -58,7 +58,7 @@ java.launcher.opt.footer = \
\ ALL-MODULE-PATH.\n\
\ --list-modules\n\
\ list observable modules and exit\n\
\ --d <module name>\n\
\ -d <module name>\n\
\ --describe-module <module name>\n\
\ describe a module and exit\n\
\ --dry-run create VM and load main class but do not execute main method.\n\
@ -165,10 +165,11 @@ java.launcher.X.usage=\n\
\ --add-opens <module>/<package>=<target-module>(,<target-module>)*\n\
\ updates <module> to open <package> to\n\
\ <target-module>, regardless of module declaration.\n\
\ --permit-illegal-access\n\
\ permit illegal access to members of types in named modules\n\
\ by code in unnamed modules. This compatibility option will\n\
\ be removed in the next release.\n\
\ --illegal-access=<value>\n\
\ permit or deny access to members of types in named modules\n\
\ by code in unnamed modules.\n\
\ <value> is one of "deny", "permit", "warn", or "debug"\n\
\ This option will be removed in a future release.\n\
\ --limit-modules <module name>[,<module name>...]\n\
\ limit the universe of observable modules\n\
\ --patch-module <module>=<file>({0}<file>)*\n\

View File

@ -2408,9 +2408,9 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
{ 0x3081000201033081L, 0x0006092A864886F7L, 0x0D010701A0810004L },
{ 0x3082000002010330L, 0x810006092A864886L, 0xF70D010701A08100L },
{ 0x3083000000020103L, 0x3082000006092A86L, 0x4886F70D010701A0L },
{ 0x3083000000020103L, 0x308200000006092AL, 0x864886F70D010701L },
{ 0x3084000000000201L, 0x0330820000000609L, 0x2A864886F70D0107L },
{ 0x3084000000000201L, 0x0330820000000006L, 0x092A864886F70D01L }
{ 0x3083000000020103L, 0x308300000006092AL, 0x864886F70D010701L },
{ 0x3084000000000201L, 0x0330830000000609L, 0x2A864886F70D0107L },
{ 0x3084000000000201L, 0x0330840000000006L, 0x092A864886F70D01L }
};
private static final long[][] PKCS12_HEADER_MASKS = {

View File

@ -20,9 +20,6 @@ grant codeBase "jrt:/java.corba" {
permission java.security.AllPermission;
};
grant codeBase "jrt:/jdk.incubator.httpclient" {
};
grant codeBase "jrt:/java.scripting" {
permission java.security.AllPermission;
};
@ -69,17 +66,7 @@ grant codeBase "jrt:/java.sql.rowset" {
};
grant codeBase "jrt:/java.xml.bind" {
permission java.lang.RuntimePermission
"accessClassInPackage.sun.misc";
permission java.lang.RuntimePermission
"accessClassInPackage.com.sun.xml.internal.*";
permission java.lang.RuntimePermission
"accessClassInPackage.com.sun.istack.internal";
permission java.lang.RuntimePermission
"accessClassInPackage.com.sun.istack.internal.*";
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
permission java.util.PropertyPermission "*", "read";
permission java.security.AllPermission;
};
grant codeBase "jrt:/java.xml.crypto" {
@ -104,19 +91,11 @@ grant codeBase "jrt:/java.xml.crypto" {
};
grant codeBase "jrt:/java.xml.ws" {
permission java.net.NetPermission
"getProxySelector";
permission java.lang.RuntimePermission
"accessClassInPackage.sun.misc";
permission java.lang.RuntimePermission
"accessClassInPackage.com.sun.xml.internal.*";
permission java.lang.RuntimePermission
"accessClassInPackage.com.sun.istack.internal";
permission java.lang.RuntimePermission
"accessClassInPackage.com.sun.istack.internal.*";
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
permission java.util.PropertyPermission "*", "read";
permission java.security.AllPermission;
};
grant codeBase "jrt:/jdk.accessibility" {
permission java.lang.RuntimePermission "accessClassInPackage.sun.awt";
};
grant codeBase "jrt:/jdk.charsets" {
@ -155,6 +134,10 @@ grant codeBase "jrt:/jdk.crypto.cryptoki" {
permission java.io.FilePermission "<<ALL FILES>>", "read";
};
grant codeBase "jrt:/jdk.desktop" {
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.awt";
};
grant codeBase "jrt:/jdk.dynalink" {
permission java.security.AllPermission;
};
@ -163,6 +146,10 @@ grant codeBase "jrt:/jdk.internal.le" {
permission java.security.AllPermission;
};
grant codeBase "jrt:/jdk.internal.vm.compiler" {
permission java.security.AllPermission;
};
grant codeBase "jrt:/jdk.jsobject" {
permission java.security.AllPermission;
};
@ -198,14 +185,6 @@ grant codeBase "jrt:/jdk.zipfs" {
permission java.util.PropertyPermission "os.name", "read";
};
grant codeBase "jrt:/jdk.accessibility" {
permission java.lang.RuntimePermission "accessClassInPackage.sun.awt";
};
grant codeBase "jrt:/jdk.desktop" {
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.awt";
};
// permissions needed by applications using java.desktop module
grant {
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.beans";
@ -213,7 +192,3 @@ grant {
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.java.swing.plaf.*";
permission java.lang.RuntimePermission "accessClassInPackage.com.apple.*";
};
grant codeBase "jrt:/jdk.internal.vm.compiler" {
permission java.security.AllPermission;
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -455,14 +455,6 @@ JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, const char* package)
JNIEXPORT void JNICALL
JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject source_module);
/*
* Add a package to a module.
* module: module that will contain the package
* package: package to add to the module
*/
JNIEXPORT void JNICALL
JVM_AddModulePackage(JNIEnv* env, jobject module, const char* package);
/*
* Reflection support functions
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2017, 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
@ -176,23 +176,3 @@ Java_java_lang_Module_addExportsToAllUnnamed0(JNIEnv *env, jclass cls,
}
}
}
JNIEXPORT void JNICALL
Java_java_lang_Module_addPackage0(JNIEnv *env, jclass cls, jobject m, jstring pkg)
{
char buf[128];
char* pkg_name;
if (pkg == NULL) {
JNU_ThrowNullPointerException(env, "package is null");
return;
}
pkg_name = GetInternalPackageName(env, pkg, buf, (jsize)sizeof(buf));
if (pkg_name != NULL) {
JVM_AddModulePackage(env, m, pkg_name);
if (pkg_name != buf) {
free(pkg_name);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, 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
@ -25,29 +25,26 @@
package java.awt.datatransfer;
import sun.datatransfer.DataFlavorUtil;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;
import java.io.IOException;
import sun.datatransfer.DataFlavorUtil;
/**
* A class that implements a mechanism to transfer data using
* cut/copy/paste operations.
* A class that implements a mechanism to transfer data using cut/copy/paste
* operations.
* <p>
* {@link FlavorListener}s may be registered on an instance of the
* Clipboard class to be notified about changes to the set of
* {@link DataFlavor}s available on this clipboard (see
* {@link #addFlavorListener}).
* {@link FlavorListener}s may be registered on an instance of the Clipboard
* class to be notified about changes to the set of {@link DataFlavor}s
* available on this clipboard (see {@link #addFlavorListener}).
*
* @author Amy Fowler
* @author Alexander Gerasimov
* @see java.awt.Toolkit#getSystemClipboard
* @see java.awt.Toolkit#getSystemSelection
*
* @author Amy Fowler
* @author Alexander Gerasimov
* @since 1.1
*/
public class Clipboard {
@ -58,6 +55,7 @@ public class Clipboard {
* The owner of the clipboard.
*/
protected ClipboardOwner owner;
/**
* Contents of the clipboard.
*/
@ -71,9 +69,9 @@ public class Clipboard {
private Set<FlavorListener> flavorListeners;
/**
* A set of <code>DataFlavor</code>s that is available on
* this local clipboard. It is used for tracking changes
* of <code>DataFlavor</code>s available on this clipboard.
* A set of {@code DataFlavor}s that is available on this local clipboard.
* It is used for tracking changes of {@code DataFlavor}s available on this
* clipboard.
*
* @since 1.5
*/
@ -81,7 +79,8 @@ public class Clipboard {
/**
* Creates a clipboard object.
* @param name for the clipboard
*
* @param name for the clipboard
* @see java.awt.Toolkit#getSystemClipboard
*/
public Clipboard(String name) {
@ -90,8 +89,8 @@ public class Clipboard {
/**
* Returns the name of this clipboard object.
* @return the name of this clipboard object
*
* @return the name of this clipboard object
* @see java.awt.Toolkit#getSystemClipboard
*/
public String getName() {
@ -99,27 +98,25 @@ public class Clipboard {
}
/**
* Sets the current contents of the clipboard to the specified
* transferable object and registers the specified clipboard owner
* as the owner of the new contents.
* Sets the current contents of the clipboard to the specified transferable
* object and registers the specified clipboard owner as the owner of the
* new contents.
* <p>
* If there is an existing owner different from the argument
* <code>owner</code>, that owner is notified that it no longer
* holds ownership of the clipboard contents via an invocation
* of <code>ClipboardOwner.lostOwnership()</code> on that owner.
* An implementation of <code>setContents()</code> is free not
* to invoke <code>lostOwnership()</code> directly from this method.
* For example, <code>lostOwnership()</code> may be invoked later on
* a different thread. The same applies to <code>FlavorListener</code>s
* registered on this clipboard.
* If there is an existing owner different from the argument {@code owner},
* that owner is notified that it no longer holds ownership of the clipboard
* contents via an invocation of {@code ClipboardOwner.lostOwnership()} on
* that owner. An implementation of {@code setContents()} is free not to
* invoke {@code lostOwnership()} directly from this method. For example,
* {@code lostOwnership()} may be invoked later on a different thread. The
* same applies to {@code FlavorListener}s registered on this clipboard.
* <p>
* The method throws <code>IllegalStateException</code> if the clipboard
* is currently unavailable. For example, on some platforms, the system
* The method throws {@code IllegalStateException} if the clipboard is
* currently unavailable. For example, on some platforms, the system
* clipboard is unavailable while it is accessed by another application.
*
* @param contents the transferable object representing the
* clipboard content
* @param owner the object which owns the clipboard content
* @param contents the transferable object representing the clipboard
* content
* @param owner the object which owns the clipboard content
* @throws IllegalStateException if the clipboard is currently unavailable
* @see java.awt.Toolkit#getSystemClipboard
*/
@ -138,15 +135,14 @@ public class Clipboard {
}
/**
* Returns a transferable object representing the current contents
* of the clipboard. If the clipboard currently has no contents,
* it returns <code>null</code>. The parameter Object requestor is
* not currently used. The method throws
* <code>IllegalStateException</code> if the clipboard is currently
* unavailable. For example, on some platforms, the system clipboard is
* Returns a transferable object representing the current contents of the
* clipboard. If the clipboard currently has no contents, it returns
* {@code null}. The parameter Object requestor is not currently used. The
* method throws {@code IllegalStateException} if the clipboard is currently
* unavailable. For example, on some platforms, the system clipboard is
* unavailable while it is accessed by another application.
*
* @param requestor the object requesting the clip data (not used)
* @param requestor the object requesting the clip data (not used)
* @return the current transferable object on the clipboard
* @throws IllegalStateException if the clipboard is currently unavailable
* @see java.awt.Toolkit#getSystemClipboard
@ -155,18 +151,14 @@ public class Clipboard {
return contents;
}
/**
* Returns an array of <code>DataFlavor</code>s in which the current
* contents of this clipboard can be provided. If there are no
* <code>DataFlavor</code>s available, this method returns a zero-length
* array.
*
* @return an array of <code>DataFlavor</code>s in which the current
* contents of this clipboard can be provided
* Returns an array of {@code DataFlavor}s in which the current contents of
* this clipboard can be provided. If there are no {@code DataFlavor}s
* available, this method returns a zero-length array.
*
* @return an array of {@code DataFlavor}s in which the current contents of
* this clipboard can be provided
* @throws IllegalStateException if this clipboard is currently unavailable
*
* @since 1.5
*/
public DataFlavor[] getAvailableDataFlavors() {
@ -179,17 +171,14 @@ public class Clipboard {
/**
* Returns whether or not the current contents of this clipboard can be
* provided in the specified <code>DataFlavor</code>.
* provided in the specified {@code DataFlavor}.
*
* @param flavor the requested <code>DataFlavor</code> for the contents
*
* @return <code>true</code> if the current contents of this clipboard
* can be provided in the specified <code>DataFlavor</code>;
* <code>false</code> otherwise
*
* @throws NullPointerException if <code>flavor</code> is <code>null</code>
* @param flavor the requested {@code DataFlavor} for the contents
* @return {@code true} if the current contents of this clipboard can be
* provided in the specified {@code DataFlavor}; {@code false}
* otherwise
* @throws NullPointerException if {@code flavor} is {@code null}
* @throws IllegalStateException if this clipboard is currently unavailable
*
* @since 1.5
*/
public boolean isDataFlavorAvailable(DataFlavor flavor) {
@ -205,25 +194,20 @@ public class Clipboard {
}
/**
* Returns an object representing the current contents of this clipboard
* in the specified <code>DataFlavor</code>.
* The class of the object returned is defined by the representation
* class of <code>flavor</code>.
* Returns an object representing the current contents of this clipboard in
* the specified {@code DataFlavor}. The class of the object returned is
* defined by the representation class of {@code flavor}.
*
* @param flavor the requested <code>DataFlavor</code> for the contents
*
* @return an object representing the current contents of this clipboard
* in the specified <code>DataFlavor</code>
*
* @throws NullPointerException if <code>flavor</code> is <code>null</code>
* @param flavor the requested {@code DataFlavor} for the contents
* @return an object representing the current contents of this clipboard in
* the specified {@code DataFlavor}
* @throws NullPointerException if {@code flavor} is {@code null}
* @throws IllegalStateException if this clipboard is currently unavailable
* @throws UnsupportedFlavorException if the requested <code>DataFlavor</code>
* is not available
* @throws IOException if the data in the requested <code>DataFlavor</code>
* can not be retrieved
*
* @throws UnsupportedFlavorException if the requested {@code DataFlavor} is
* not available
* @throws IOException if the data in the requested {@code DataFlavor} can
* not be retrieved
* @see DataFlavor#getRepresentationClass
*
* @since 1.5
*/
public Object getData(DataFlavor flavor)
@ -239,15 +223,12 @@ public class Clipboard {
return cntnts.getTransferData(flavor);
}
/**
* Registers the specified <code>FlavorListener</code> to receive
* <code>FlavorEvent</code>s from this clipboard.
* If <code>listener</code> is <code>null</code>, no exception
* is thrown and no action is performed.
*
* @param listener the listener to be added
* Registers the specified {@code FlavorListener} to receive
* {@code FlavorEvent}s from this clipboard. If {@code listener} is
* {@code null}, no exception is thrown and no action is performed.
*
* @param listener the listener to be added
* @see #removeFlavorListener
* @see #getFlavorListeners
* @see FlavorListener
@ -268,16 +249,14 @@ public class Clipboard {
}
/**
* Removes the specified <code>FlavorListener</code> so that it no longer
* receives <code>FlavorEvent</code>s from this <code>Clipboard</code>.
* This method performs no function, nor does it throw an exception, if
* the listener specified by the argument was not previously added to this
* <code>Clipboard</code>.
* If <code>listener</code> is <code>null</code>, no exception
* is thrown and no action is performed.
*
* @param listener the listener to be removed
* Removes the specified {@code FlavorListener} so that it no longer
* receives {@code FlavorEvent}s from this {@code Clipboard}. This method
* performs no function, nor does it throw an exception, if the listener
* specified by the argument was not previously added to this
* {@code Clipboard}. If {@code listener} is {@code null}, no exception is
* thrown and no action is performed.
*
* @param listener the listener to be removed
* @see #addFlavorListener
* @see #getFlavorListeners
* @see FlavorListener
@ -292,11 +271,11 @@ public class Clipboard {
}
/**
* Returns an array of all the <code>FlavorListener</code>s currently
* registered on this <code>Clipboard</code>.
* Returns an array of all the {@code FlavorListener}s currently registered
* on this {@code Clipboard}.
*
* @return all of this clipboard's <code>FlavorListener</code>s or an empty
* array if no listeners are currently registered
* @return all of this clipboard's {@code FlavorListener}s or an empty array
* if no listeners are currently registered
* @see #addFlavorListener
* @see #removeFlavorListener
* @see FlavorListener
@ -309,9 +288,9 @@ public class Clipboard {
}
/**
* Checks change of the <code>DataFlavor</code>s and, if necessary,
* notifies all listeners that have registered interest for notification
* on <code>FlavorEvent</code>s.
* Checks change of the {@code DataFlavor}s and, if necessary, notifies all
* listeners that have registered interest for notification on
* {@code FlavorEvent}s.
*
* @since 1.5
*/
@ -331,12 +310,11 @@ public class Clipboard {
}
/**
* Returns a set of <code>DataFlavor</code>s currently available
* on this clipboard.
*
* @return a set of <code>DataFlavor</code>s currently available
* on this clipboard
* Returns a set of {@code DataFlavor}s currently available on this
* clipboard.
*
* @return a set of {@code DataFlavor}s currently available on this
* clipboard
* @since 1.5
*/
private Set<DataFlavor> getAvailableDataFlavorSet() {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, 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
@ -26,32 +26,28 @@
package java.awt.datatransfer;
/**
* Defines the interface for classes that will provide data to
* a clipboard. An instance of this interface becomes the owner
* of the contents of a clipboard (clipboard owner) if it is
* passed as an argument to
* {@link java.awt.datatransfer.Clipboard#setContents} method of
* the clipboard and this method returns successfully.
* The instance remains the clipboard owner until another application
* or another object within this application asserts ownership
* of this clipboard.
* Defines the interface for classes that will provide data to a clipboard. An
* instance of this interface becomes the owner of the contents of a clipboard
* (clipboard owner) if it is passed as an argument to
* {@link Clipboard#setContents} method of the clipboard and this method returns
* successfully. The instance remains the clipboard owner until another
* application or another object within this application asserts ownership of
* this clipboard.
*
* @see java.awt.datatransfer.Clipboard
*
* @author Amy Fowler
* @author Amy Fowler
* @see Clipboard
* @since 1.1
*/
public interface ClipboardOwner {
/**
* Notifies this object that it is no longer the clipboard owner.
* This method will be called when another application or another
* object within this application asserts ownership of the clipboard.
* Notifies this object that it is no longer the clipboard owner. This
* method will be called when another application or another object within
* this application asserts ownership of the clipboard.
*
* @param clipboard the clipboard that is no longer owned
* @param contents the contents which this owner had placed on the clipboard
* @param clipboard the clipboard that is no longer owned
* @param contents the contents which this owner had placed on the
* {@code clipboard}
*/
public void lostOwnership(Clipboard clipboard, Transferable contents);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, 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
@ -22,29 +22,27 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt.datatransfer;
import java.util.EventObject;
/**
* <code>FlavorEvent</code> is used to notify interested parties
* that available {@link DataFlavor}s have changed in the
* {@link Clipboard} (the event source).
*
* @see FlavorListener
* {@code FlavorEvent} is used to notify interested parties that available
* {@link DataFlavor}s have changed in the {@link Clipboard} (the event source).
*
* @author Alexander Gerasimov
* @see FlavorListener
* @since 1.5
*/
public class FlavorEvent extends EventObject {
private static final long serialVersionUID = -5842664112252414548L;
/**
* Constructs a <code>FlavorEvent</code> object.
*
* @param source the <code>Clipboard</code> that is the source of the event
* Constructs a {@code FlavorEvent} object.
*
* @param source the {@code Clipboard} that is the source of the event
* @throws IllegalArgumentException if the {@code source} is {@code null}
*/
public FlavorEvent(Clipboard source) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, 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
@ -22,11 +22,11 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt.datatransfer;
import java.util.EventListener;
/**
* Defines an object which listens for {@link FlavorEvent}s.
*
@ -34,22 +34,21 @@ import java.util.EventListener;
* @since 1.5
*/
public interface FlavorListener extends EventListener {
/**
* Invoked when the target {@link Clipboard} of the listener
* has changed its available {@link DataFlavor}s.
* Invoked when the target {@link Clipboard} of the listener has changed its
* available {@link DataFlavor}s.
* <p>
* Some notifications may be redundant &#8212; they are not
* caused by a change of the set of DataFlavors available
* on the clipboard.
* For example, if the clipboard subsystem supposes that
* the system clipboard's contents has been changed but it
* can't ascertain whether its DataFlavors have been changed
* because of some exceptional condition when accessing the
* clipboard, the notification is sent to ensure from omitting
* a significant notification. Ordinarily, those redundant
* notifications should be occasional.
* Some notifications may be redundant &#8212; they are not caused by a
* change of the set of DataFlavors available on the clipboard. For example,
* if the clipboard subsystem supposes that the system clipboard's contents
* has been changed but it can't ascertain whether its DataFlavors have been
* changed because of some exceptional condition when accessing the
* clipboard, the notification is sent to ensure from omitting a significant
* notification. Ordinarily, those redundant notifications should be
* occasional.
*
* @param e a <code>FlavorEvent</code> object
* @param e a {@code FlavorEvent} object
*/
void flavorsChanged(FlavorEvent e);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -27,49 +27,45 @@ package java.awt.datatransfer;
import java.util.Map;
/**
* A two-way Map between "natives" (Strings), which correspond to platform-
* specific data formats, and "flavors" (DataFlavors), which correspond to
* platform-independent MIME types. FlavorMaps need not be symmetric, but
* A two-way Map between "natives" (Strings), which correspond to
* platform-specific data formats, and "flavors" (DataFlavors), which correspond
* to platform-independent MIME types. FlavorMaps need not be symmetric, but
* typically are.
*
*
* @since 1.2
*/
public interface FlavorMap {
/**
* Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to
* their corresponding <code>String</code> native. The returned
* <code>Map</code> is a modifiable copy of this <code>FlavorMap</code>'s
* internal data. Client code is free to modify the <code>Map</code>
* without affecting this object.
* Returns a {@code Map} of the specified {@code DataFlavor}s to their
* corresponding {@code String} native. The returned {@code Map} is a
* modifiable copy of this {@code FlavorMap}'s internal data. Client code is
* free to modify the {@code Map} without affecting this object.
*
* @param flavors an array of <code>DataFlavor</code>s which will be the
* key set of the returned <code>Map</code>. If <code>null</code> is
* specified, a mapping of all <code>DataFlavor</code>s currently
* known to this <code>FlavorMap</code> to their corresponding
* <code>String</code> natives will be returned.
* @return a <code>java.util.Map</code> of <code>DataFlavor</code>s to
* <code>String</code> natives
* @param flavors an array of {@code DataFlavor}s which will be the key set
* of the returned {@code Map}. If {@code null} is specified, a
* mapping of all {@code DataFlavor}s currently known to this
* {@code FlavorMap} to their corresponding {@code String} natives
* will be returned.
* @return a {@code java.util.Map} of {@code DataFlavor}s to {@code String}
* natives
*/
Map<DataFlavor,String> getNativesForFlavors(DataFlavor[] flavors);
Map<DataFlavor, String> getNativesForFlavors(DataFlavor[] flavors);
/**
* Returns a <code>Map</code> of the specified <code>String</code> natives
* to their corresponding <code>DataFlavor</code>. The returned
* <code>Map</code> is a modifiable copy of this <code>FlavorMap</code>'s
* internal data. Client code is free to modify the <code>Map</code>
* without affecting this object.
* Returns a {@code Map} of the specified {@code String} natives to their
* corresponding {@code DataFlavor}. The returned {@code Map} is a
* modifiable copy of this {@code FlavorMap}'s internal data. Client code is
* free to modify the {@code Map} without affecting this object.
*
* @param natives an array of <code>String</code>s which will be the
* key set of the returned <code>Map</code>. If <code>null</code> is
* specified, a mapping of all <code>String</code> natives currently
* known to this <code>FlavorMap</code> to their corresponding
* <code>DataFlavor</code>s will be returned.
* @return a <code>java.util.Map</code> of <code>String</code> natives to
* <code>DataFlavor</code>s
* @param natives an array of {@code String}s which will be the key set of
* the returned {@code Map}. If {@code null} is specified, a mapping
* of all {@code String} natives currently known to this
* {@code FlavorMap} to their corresponding {@code DataFlavor}s will
* be returned.
* @return a {@code java.util.Map} of {@code String} natives to
* {@code DataFlavor}s
*/
Map<String,DataFlavor> getFlavorsForNatives(String[] natives);
Map<String, DataFlavor> getFlavorsForNatives(String[] natives);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2017, 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
@ -27,56 +27,52 @@ package java.awt.datatransfer;
import java.util.List;
/**
* A FlavorMap which relaxes the traditional 1-to-1 restriction of a Map. A
* flavor is permitted to map to any number of natives, and likewise a native
* is permitted to map to any number of flavors. FlavorTables need not be
* flavor is permitted to map to any number of natives, and likewise a native is
* permitted to map to any number of flavors. FlavorTables need not be
* symmetric, but typically are.
*
* @author David Mendenhall
*
* @since 1.4
*/
public interface FlavorTable extends FlavorMap {
/**
* Returns a <code>List</code> of <code>String</code> natives to which the
* specified <code>DataFlavor</code> corresponds. The <code>List</code>
* will be sorted from best native to worst. That is, the first native will
* best reflect data in the specified flavor to the underlying native
* platform. The returned <code>List</code> is a modifiable copy of this
* <code>FlavorTable</code>'s internal data. Client code is free to modify
* the <code>List</code> without affecting this object.
* Returns a {@code List} of {@code String} natives to which the specified
* {@code DataFlavor} corresponds. The {@code List} will be sorted from best
* native to worst. That is, the first native will best reflect data in the
* specified flavor to the underlying native platform. The returned
* {@code List} is a modifiable copy of this {@code FlavorTable}'s internal
* data. Client code is free to modify the {@code List} without affecting
* this object.
*
* @param flav the <code>DataFlavor</code> whose corresponding natives
* should be returned. If <code>null</code> is specified, all
* natives currently known to this <code>FlavorTable</code> are
* returned in a non-deterministic order.
* @return a <code>java.util.List</code> of <code>java.lang.String</code>
* objects which are platform-specific representations of platform-
* specific data formats
* @param flav the {@code DataFlavor} whose corresponding natives should be
* returned. If {@code null} is specified, all natives currently
* known to this {@code FlavorTable} are returned in a
* non-deterministic order.
* @return a {@code java.util.List} of {@code java.lang.String} objects
* which are platform-specific representations of platform-specific
* data formats
*/
List<String> getNativesForFlavor(DataFlavor flav);
/**
* Returns a <code>List</code> of <code>DataFlavor</code>s to which the
* specified <code>String</code> corresponds. The <code>List</code> will be
* sorted from best <code>DataFlavor</code> to worst. That is, the first
* <code>DataFlavor</code> will best reflect data in the specified
* native to a Java application. The returned <code>List</code> is a
* modifiable copy of this <code>FlavorTable</code>'s internal data.
* Client code is free to modify the <code>List</code> without affecting
* this object.
* Returns a {@code List} of {@code DataFlavor}s to which the specified
* {@code String} corresponds. The {@code List} will be sorted from best
* {@code DataFlavor} to worst. That is, the first {@code DataFlavor} will
* best reflect data in the specified native to a Java application. The
* returned {@code List} is a modifiable copy of this {@code FlavorTable}'s
* internal data. Client code is free to modify the {@code List} without
* affecting this object.
*
* @param nat the native whose corresponding <code>DataFlavor</code>s
* should be returned. If <code>null</code> is specified, all
* <code>DataFlavor</code>s currently known to this
* <code>FlavorTable</code> are returned in a non-deterministic
* order.
* @return a <code>java.util.List</code> of <code>DataFlavor</code>
* objects into which platform-specific data in the specified,
* platform-specific native can be translated
* @param nat the native whose corresponding {@code DataFlavor}s should be
* returned. If {@code null} is specified, all {@code DataFlavor}s
* currently known to this {@code FlavorTable} are returned in a
* non-deterministic order.
* @return a {@code java.util.List} of {@code DataFlavor} objects into which
* platform-specific data in the specified, platform-specific native
* can be translated
*/
List<DataFlavor> getFlavorsForNative(String nat);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -26,20 +26,18 @@
package java.awt.datatransfer;
import java.io.Externalizable;
import java.io.ObjectOutput;
import java.io.ObjectInput;
import java.io.IOException;
import java.util.Enumeration;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Locale;
/**
* A Multipurpose Internet Mail Extension (MIME) type, as defined
* in RFC 2045 and 2046.
*
* THIS IS *NOT* - REPEAT *NOT* - A PUBLIC CLASS! DataFlavor IS
* THE PUBLIC INTERFACE, AND THIS IS PROVIDED AS A ***PRIVATE***
* (THAT IS AS IN *NOT* PUBLIC) HELPER CLASS!
* A Multipurpose Internet Mail Extension (MIME) type, as defined in RFC 2045
* and 2046.
* <p>
* THIS IS *NOT* - REPEAT *NOT* - A PUBLIC CLASS! DataFlavor IS THE PUBLIC
* INTERFACE, AND THIS IS PROVIDED AS A ***PRIVATE*** (THAT IS AS IN *NOT*
* PUBLIC) HELPER CLASS!
*/
class MimeType implements Externalizable, Cloneable {
@ -50,45 +48,45 @@ class MimeType implements Externalizable, Cloneable {
static final long serialVersionUID = -6568722458793895906L;
/**
* Constructor for externalization; this constructor should not be
* called directly by an application, since the result will be an
* uninitialized, immutable <code>MimeType</code> object.
* Constructor for externalization; this constructor should not be called
* directly by an application, since the result will be an uninitialized,
* immutable {@code MimeType} object.
*/
public MimeType() {
}
/**
* Builds a <code>MimeType</code> from a <code>String</code>.
* Builds a {@code MimeType} from a {@code String}.
*
* @param rawdata text used to initialize the <code>MimeType</code>
* @throws NullPointerException if <code>rawdata</code> is null
* @param rawdata text used to initialize the {@code MimeType}
* @throws NullPointerException if {@code rawdata} is {@code null}
*/
public MimeType(String rawdata) throws MimeTypeParseException {
parse(rawdata);
}
/**
* Builds a <code>MimeType</code> with the given primary and sub
* type but has an empty parameter list.
* Builds a {@code MimeType} with the given primary and sub type but has an
* empty parameter list.
*
* @param primary the primary type of this <code>MimeType</code>
* @param sub the subtype of this <code>MimeType</code>
* @throws NullPointerException if either <code>primary</code> or
* <code>sub</code> is null
* @param primary the primary type of this {@code MimeType}
* @param sub the subtype of this {@code MimeType}
* @throws NullPointerException if either {@code primary} or {@code sub} is
* {@code null}
*/
public MimeType(String primary, String sub) throws MimeTypeParseException {
this(primary, sub, new MimeTypeParameterList());
}
/**
* Builds a <code>MimeType</code> with a pre-defined
* and valid (or empty) parameter list.
* Builds a {@code MimeType} with a pre-defined and valid (or empty)
* parameter list.
*
* @param primary the primary type of this <code>MimeType</code>
* @param sub the subtype of this <code>MimeType</code>
* @param mtpl the requested parameter list
* @throws NullPointerException if either <code>primary</code>,
* <code>sub</code> or <code>mtpl</code> is null
* @param primary the primary type of this {@code MimeType}
* @param sub the subtype of this {@code MimeType}
* @param mtpl the requested parameter list
* @throws NullPointerException if either {@code primary}, {@code sub} or
* {@code mtpl} is {@code null}
*/
public MimeType(String primary, String sub, MimeTypeParameterList mtpl) throws
MimeTypeParseException {
@ -121,13 +119,12 @@ MimeTypeParseException {
} // hashCode()
/**
* <code>MimeType</code>s are equal if their primary types,
* subtypes, and parameters are all equal. No default values
* are taken into account.
* @param thatObject the object to be evaluated as a
* <code>MimeType</code>
* @return <code>true</code> if <code>thatObject</code> is
* a <code>MimeType</code>; otherwise returns <code>false</code>
* {@code MimeType}s are equal if their primary types, subtypes, and
* parameters are all equal. No default values are taken into account.
*
* @param thatObject the object to be evaluated as a {@code MimeType}
* @return {@code true} if {@code thatObject} is a {@code MimeType};
* otherwise returns {@code false}
*/
public boolean equals(Object thatObject) {
if (!(thatObject instanceof MimeType)) {
@ -144,7 +141,7 @@ MimeTypeParseException {
/**
* A routine for parsing the MIME type out of a String.
*
* @throws NullPointerException if <code>rawdata</code> is null
* @throws NullPointerException if {@code rawdata} is {@code null}
*/
private void parse(String rawdata) throws MimeTypeParseException {
int slashIndex = rawdata.indexOf('/');
@ -213,8 +210,8 @@ MimeTypeParameterList(rawdata.substring(semIndex));
}
/**
* Retrieve the value associated with the given name, or null if there
* is no current association.
* Retrieve the value associated with the given name, or {@code null} if
* there is no current association.
*/
public String getParameter(String name) {
return parameters.get(name);
@ -247,23 +244,21 @@ MimeTypeParameterList(rawdata.substring(semIndex));
}
/**
* Return a String representation of this object
* without the parameter list.
* Return a String representation of this object without the parameter list.
*/
public String getBaseType() {
return primaryType + "/" + subType;
}
/**
* Returns <code>true</code> if the primary type and the
* subtype of this object are the same as the specified
* <code>type</code>; otherwise returns <code>false</code>.
* Returns {@code true} if the primary type and the subtype of this object
* are the same as the specified {@code type}; otherwise returns
* {@code false}.
*
* @param type the type to compare to <code>this</code>'s type
* @return <code>true</code> if the primary type and the
* subtype of this object are the same as the
* specified <code>type</code>; otherwise returns
* <code>false</code>
* @param type the type to compare to {@code this}'s type
* @return {@code true} if the primary type and the subtype of this object
* are the same as the specified {@code type}; otherwise returns
* {@code false}
*/
public boolean match(MimeType type) {
if (type == null)
@ -275,17 +270,15 @@ MimeTypeParameterList(rawdata.substring(semIndex));
}
/**
* Returns <code>true</code> if the primary type and the
* subtype of this object are the same as the content type
* described in <code>rawdata</code>; otherwise returns
* <code>false</code>.
* Returns {@code true} if the primary type and the subtype of this object
* are the same as the content type described in {@code rawdata}; otherwise
* returns {@code false}.
*
* @param rawdata the raw data to be examined
* @return <code>true</code> if the primary type and the
* subtype of this object are the same as the content type
* described in <code>rawdata</code>; otherwise returns
* <code>false</code>; if <code>rawdata</code> is
* <code>null</code>, returns <code>false</code>
* @param rawdata the raw data to be examined
* @return {@code true} if the primary type and the subtype of this object
* are the same as the content type described in {@code rawdata};
* otherwise returns {@code false}; if {@code rawdata} is
* {@code null}, returns {@code false}
*/
public boolean match(String rawdata) throws MimeTypeParseException {
if (rawdata == null)
@ -294,11 +287,11 @@ MimeTypeParameterList(rawdata.substring(semIndex));
}
/**
* The object implements the writeExternal method to save its contents
* by calling the methods of DataOutput for its primitive values or
* calling the writeObject method of ObjectOutput for objects, strings
* and arrays.
* @exception IOException Includes any I/O exceptions that may occur
* The object implements the writeExternal method to save its contents by
* calling the methods of DataOutput for its primitive values or calling the
* writeObject method of ObjectOutput for objects, strings and arrays.
*
* @throws IOException Includes any I/O exceptions that may occur
*/
public void writeExternal(ObjectOutput out) throws IOException {
String s = toString(); // contains ASCII chars only
@ -314,13 +307,14 @@ MimeTypeParameterList(rawdata.substring(semIndex));
}
/**
* The object implements the readExternal method to restore its
* contents by calling the methods of DataInput for primitive
* types and readObject for objects, strings and arrays. The
* readExternal method must read the values in the same sequence
* and with the same types as were written by writeExternal.
* @exception ClassNotFoundException If the class for an object being
* restored cannot be found.
* The object implements the readExternal method to restore its contents by
* calling the methods of DataInput for primitive types and readObject for
* objects, strings and arrays. The readExternal method must read the values
* in the same sequence and with the same types as were written by
* writeExternal.
*
* @throws ClassNotFoundException If the class for an object being restored
* cannot be found
*/
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
@ -339,9 +333,9 @@ ClassNotFoundException {
/**
* Returns a clone of this object.
*
* @return a clone of this object
*/
public Object clone() {
MimeType newObj = null;
try {
@ -368,7 +362,7 @@ ClassNotFoundException {
/**
* Determines whether or not a given string is a legal token.
*
* @throws NullPointerException if <code>s</code> is null
* @throws NullPointerException if {@code s} is {@code null}
*/
private boolean isValidToken(String s) {
int len = s.length();
@ -388,7 +382,5 @@ ClassNotFoundException {
/**
* A string that holds all the special chars.
*/
private static final String TSPECIALS = "()<>@,;:\\\"/[]?=";
} // class MimeType

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -31,10 +31,9 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* An object that encapsulates the parameter list of a MimeType
* as defined in RFC 2045 and 2046.
* An object that encapsulates the parameter list of a MimeType as defined in
* RFC 2045 and 2046.
*
* @author jeff.dunn@eng.sun.com
*/
@ -71,9 +70,9 @@ class MimeTypeParameterList implements Cloneable {
} // hashCode()
/**
* Two parameter lists are considered equal if they have exactly
* the same set of parameter names and associated values. The
* order of the parameters is not considered.
* Two parameter lists are considered equal if they have exactly the same
* set of parameter names and associated values. The order of the parameters
* is not considered.
*/
public boolean equals(Object thatObject) {
//System.out.println("MimeTypeParameterList.equals("+this+","+thatObject+")");
@ -246,16 +245,16 @@ class MimeTypeParameterList implements Cloneable {
}
/**
* Retrieve the value associated with the given name, or null if there
* is no current association.
* Retrieve the value associated with the given name, or {@code null} if
* there is no current association.
*/
public String get(String name) {
return parameters.get(name.trim().toLowerCase());
}
/**
* Set the value to be associated with the given name, replacing
* any previous association.
* Set the value to be associated with the given name, replacing any
* previous association.
*/
public void set(String name, String value) {
parameters.put(name.trim().toLowerCase(), value);
@ -294,18 +293,20 @@ class MimeTypeParameterList implements Cloneable {
}
/**
* Returns a clone of this object.
*
* @return a clone of this object
*/
@SuppressWarnings("unchecked") // Cast from clone
public Object clone() {
MimeTypeParameterList newObj = null;
try {
newObj = (MimeTypeParameterList)super.clone();
} catch (CloneNotSupportedException cannotHappen) {
}
newObj.parameters = (Hashtable<String, String>)parameters.clone();
return newObj;
}
public Object clone() {
MimeTypeParameterList newObj = null;
try {
newObj = (MimeTypeParameterList)super.clone();
} catch (CloneNotSupportedException cannotHappen) {
}
newObj.parameters = (Hashtable<String, String>)parameters.clone();
return newObj;
}
private Hashtable<String, String> parameters;
@ -319,8 +320,8 @@ class MimeTypeParameterList implements Cloneable {
}
/**
* return the index of the first non white space character in
* rawdata at or after index i.
* Returns the index of the first non white space character in
* {@code rawdata} at or after index {@code i}.
*/
private static int skipWhiteSpace(String rawdata, int i) {
int length = rawdata.length();
@ -374,7 +375,8 @@ class MimeTypeParameterList implements Cloneable {
}
/**
* A routine that knows how to strip the quotes and escape sequences from the given value.
* A routine that knows how to strip the quotes and escape sequences from
* the given value.
*/
private static String unquote(String value) {
int valueLength = value.length();
@ -400,5 +402,4 @@ class MimeTypeParameterList implements Cloneable {
* A string that holds all the special chars.
*/
private static final String TSPECIALS = "()<>@,;:\\\"/[]?=";
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -25,12 +25,11 @@
package java.awt.datatransfer;
/**
* A class to encapsulate MimeType parsing related exceptions
* A class to encapsulate MimeType parsing related exceptions.
*
* @serial exclude
* @since 1.3
* @serial exclude
*/
public class MimeTypeParseException extends Exception {
@ -47,7 +46,7 @@ public class MimeTypeParseException extends Exception {
/**
* Constructs a MimeTypeParseException with the specified detail message.
*
* @param s the detail message.
* @param s the detail message
*/
public MimeTypeParseException(String s) {
super(s);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, 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
@ -25,23 +25,21 @@
package java.awt.datatransfer;
import java.io.*;
import java.io.IOException;
import java.io.StringReader;
/**
* A <code>Transferable</code> which implements the capability required
* to transfer a <code>String</code>.
*
* This <code>Transferable</code> properly supports
* <code>DataFlavor.stringFlavor</code>
* and all equivalent flavors. Support for
* <code>DataFlavor.plainTextFlavor</code>
* and all equivalent flavors is <b>deprecated</b>. No other
* <code>DataFlavor</code>s are supported.
* A {@code Transferable} which implements the capability required to transfer a
* {@code String}.
* <p>
* This {@code Transferable} properly supports {@code DataFlavor.stringFlavor}
* and all equivalent flavors. Support for {@code DataFlavor.plainTextFlavor}
* and all equivalent flavors is <b>deprecated</b>. No other {@code DataFlavor}s
* are supported.
*
* @see DataFlavor#stringFlavor
* @see DataFlavor#plainTextFlavor
* @since 1.1
* @see java.awt.datatransfer.DataFlavor#stringFlavor
* @see java.awt.datatransfer.DataFlavor#plainTextFlavor
*/
public class StringSelection implements Transferable, ClipboardOwner {
@ -57,23 +55,23 @@ public class StringSelection implements Transferable, ClipboardOwner {
private String data;
/**
* Creates a <code>Transferable</code> capable of transferring
* the specified <code>String</code>.
* @param data the string to be transferred
* Creates a {@code Transferable} capable of transferring the specified
* {@code String}.
*
* @param data the string to be transferred
*/
public StringSelection(String data) {
this.data = data;
}
/**
* Returns an array of flavors in which this <code>Transferable</code>
* can provide the data. <code>DataFlavor.stringFlavor</code>
* is properly supported.
* Support for <code>DataFlavor.plainTextFlavor</code> is
* <b>deprecated</b>.
* Returns an array of flavors in which this {@code Transferable} can
* provide the data. {@code DataFlavor.stringFlavor} is properly supported.
* Support for {@code DataFlavor.plainTextFlavor} is <b>deprecated</b>.
*
* @return an array of length two, whose elements are <code>DataFlavor.
* stringFlavor</code> and <code>DataFlavor.plainTextFlavor</code>
* @return an array of length two, whose elements are
* {@code DataFlavor.stringFlavor} and
* {@code DataFlavor.plainTextFlavor}
*/
public DataFlavor[] getTransferDataFlavors() {
// returning flavors itself would allow client code to modify
@ -83,14 +81,14 @@ public class StringSelection implements Transferable, ClipboardOwner {
/**
* Returns whether the requested flavor is supported by this
* <code>Transferable</code>.
* {@code Transferable}.
*
* @param flavor the requested flavor for the data
* @return true if <code>flavor</code> is equal to
* <code>DataFlavor.stringFlavor</code> or
* <code>DataFlavor.plainTextFlavor</code>; false if <code>flavor</code>
* is not one of the above flavors
* @throws NullPointerException if flavor is <code>null</code>
* @param flavor the requested flavor for the data
* @return {@code true} if {@code flavor} is equal to
* {@code DataFlavor.stringFlavor} or
* {@code DataFlavor.plainTextFlavor}; {@code false} if
* {@code flavor} is not one of the above flavors
* @throws NullPointerException if {@code flavor} is {@code null}
*/
public boolean isDataFlavorSupported(DataFlavor flavor) {
// JCK Test StringSelection0003: if 'flavor' is null, throw NPE
@ -103,27 +101,27 @@ public class StringSelection implements Transferable, ClipboardOwner {
}
/**
* Returns the <code>Transferable</code>'s data in the requested
* <code>DataFlavor</code> if possible. If the desired flavor is
* <code>DataFlavor.stringFlavor</code>, or an equivalent flavor,
* the <code>String</code> representing the selection is
* returned. If the desired flavor is
* <code>DataFlavor.plainTextFlavor</code>,
* or an equivalent flavor, a <code>Reader</code> is returned.
* Returns the {@code Transferable}'s data in the requested
* {@code DataFlavor} if possible. If the desired flavor is
* {@code DataFlavor.stringFlavor}, or an equivalent flavor, the
* {@code String} representing the selection is returned. If the desired
* flavor is {@code DataFlavor.plainTextFlavor}, or an equivalent flavor, a
* {@code Reader} is returned.
* <br>
* <b>Note:</b> The behavior of this method for
* <code>DataFlavor.plainTextFlavor</code>
* and equivalent <code>DataFlavor</code>s is inconsistent with the
* definition of <code>DataFlavor.plainTextFlavor</code>.
* {@code DataFlavor.plainTextFlavor}
* and equivalent {@code DataFlavor}s is inconsistent with the definition of
* {@code DataFlavor.plainTextFlavor}.
*
* @param flavor the requested flavor for the data
* @param flavor the requested flavor for the data
* @return the data in the requested flavor, as outlined above
* @throws UnsupportedFlavorException if the requested data flavor is
* not equivalent to either <code>DataFlavor.stringFlavor</code>
* or <code>DataFlavor.plainTextFlavor</code>
* @throws UnsupportedFlavorException if the requested data flavor is not
* equivalent to either {@code DataFlavor.stringFlavor} or
* {@code DataFlavor.plainTextFlavor}
* @throws IOException if an IOException occurs while retrieving the data.
* By default, StringSelection never throws this exception, but a
* subclass may.
* @throws NullPointerException if flavor is <code>null</code>
* @throws NullPointerException if {@code flavor} is {@code null}
* @see java.io.Reader
*/
public Object getTransferData(DataFlavor flavor)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -25,9 +25,6 @@
package java.awt.datatransfer;
import sun.datatransfer.DataFlavorUtil;
import sun.datatransfer.DesktopDatatransferService;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@ -45,11 +42,14 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import sun.datatransfer.DataFlavorUtil;
import sun.datatransfer.DesktopDatatransferService;
/**
* The SystemFlavorMap is a configurable map between "natives" (Strings), which
* correspond to platform-specific data formats, and "flavors" (DataFlavors),
* which correspond to platform-independent MIME types. This mapping is used
* by the data transfer subsystem to transfer data between Java and native
* which correspond to platform-independent MIME types. This mapping is used by
* the data transfer subsystem to transfer data between Java and native
* applications, and between Java applications in separate VMs.
*
* @since 1.2
@ -57,8 +57,7 @@ import java.util.Set;
public final class SystemFlavorMap implements FlavorMap, FlavorTable {
/**
* Constant prefix used to tag Java types converted to native platform
* type.
* Constant prefix used to tag Java types converted to native platform type.
*/
private static String JavaMIME = "JAVA_DATAFLAVOR:";
@ -93,14 +92,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
/**
* Maps native Strings to Lists of DataFlavors (or base type Strings for
* text DataFlavors).
* Do not use the field directly, use getNativeToFlavor() instead.
* <p>
* Do not use the field directly, use {@link #getNativeToFlavor} instead.
*/
private final Map<String, LinkedHashSet<DataFlavor>> nativeToFlavor = new HashMap<>();
/**
* Accessor to nativeToFlavor map. Since we use lazy initialization we must
* Accessor to nativeToFlavor map. Since we use lazy initialization we must
* use this accessor instead of direct access to the field which may not be
* initialized yet. This method will initialize the field if needed.
* initialized yet. This method will initialize the field if needed.
*
* @return nativeToFlavor
*/
@ -114,14 +114,15 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
/**
* Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
* native Strings.
* Do not use the field directly, use getFlavorToNative() instead.
* <p>
* Do not use the field directly, use {@link #getFlavorToNative} instead.
*/
private final Map<DataFlavor, LinkedHashSet<String>> flavorToNative = new HashMap<>();
/**
* Accessor to flavorToNative map. Since we use lazy initialization we must
* Accessor to flavorToNative map. Since we use lazy initialization we must
* use this accessor instead of direct access to the field which may not be
* initialized yet. This method will initialize the field if needed.
* initialized yet. This method will initialize the field if needed.
*
* @return flavorToNative
*/
@ -133,9 +134,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Maps a text DataFlavor primary mime-type to the native. Used only to store
* standard mappings registered in the flavormap.properties
* Do not use this field directly, use getTextTypeToNative() instead.
* Maps a text DataFlavor primary mime-type to the native. Used only to
* store standard mappings registered in the {@code flavormap.properties}.
* <p>
* Do not use this field directly, use {@link #getTextTypeToNative} instead.
*/
private Map<String, LinkedHashSet<String>> textTypeToNative = new HashMap<>();
@ -145,9 +147,9 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
private boolean isMapInitialized = false;
/**
* An accessor to textTypeToNative map. Since we use lazy initialization we
* must use this accessor instead of direct access to the field which may not
* be initialized yet. This method will initialize the field if needed.
* An accessor to textTypeToNative map. Since we use lazy initialization we
* must use this accessor instead of direct access to the field which may
* not be initialized yet. This method will initialize the field if needed.
*
* @return textTypeToNative
*/
@ -175,8 +177,8 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
/**
* Dynamic mapping generation used for text mappings should not be applied
* to the DataFlavors and String natives for which the mappings have been
* explicitly specified with setFlavorsForNative() or
* setNativesForFlavor(). This keeps all such keys.
* explicitly specified with {@link #setFlavorsForNative} or
* {@link #setNativesForFlavor}. This keeps all such keys.
*/
private Set<Object> disabledMappingGenerationKeys = new HashSet<>();
@ -193,8 +195,8 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Initializes a SystemFlavorMap by reading flavormap.properties
* For thread-safety must be called under lock on this.
* Initializes a SystemFlavorMap by reading {@code flavormap.properties}.
* For thread-safety must be called under lock on {@code this}.
*/
private void initSystemFlavorMap() {
if (isMapInitialized) {
@ -366,10 +368,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Semantically equivalent to 'nativeToFlavor.get(nat)'. This method
* handles the case where 'nat' is not found in 'nativeToFlavor'. In that
* case, a new DataFlavor is synthesized, stored, and returned, if and
* only if the specified native is encoded as a Java MIME type.
* Semantically equivalent to 'nativeToFlavor.get(nat)'. This method handles
* the case where 'nat' is not found in 'nativeToFlavor'. In that case, a
* new DataFlavor is synthesized, stored, and returned, if and only if the
* specified native is encoded as a Java MIME type.
*/
private LinkedHashSet<DataFlavor> nativeToFlavorLookup(String nat) {
LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(nat);
@ -480,27 +482,25 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Returns a <code>List</code> of <code>String</code> natives to which the
* specified <code>DataFlavor</code> can be translated by the data transfer
* subsystem. The <code>List</code> will be sorted from best native to
* worst. That is, the first native will best reflect data in the specified
* flavor to the underlying native platform.
* Returns a {@code List} of {@code String} natives to which the specified
* {@code DataFlavor} can be translated by the data transfer subsystem. The
* {@code List} will be sorted from best native to worst. That is, the first
* native will best reflect data in the specified flavor to the underlying
* native platform.
* <p>
* If the specified <code>DataFlavor</code> is previously unknown to the
* data transfer subsystem and the data transfer subsystem is unable to
* translate this <code>DataFlavor</code> to any existing native, then
* invoking this method will establish a
* mapping in both directions between the specified <code>DataFlavor</code>
* and an encoded version of its MIME type as its native.
*
* @param flav the <code>DataFlavor</code> whose corresponding natives
* should be returned. If <code>null</code> is specified, all
* natives currently known to the data transfer subsystem are
* returned in a non-deterministic order.
* @return a <code>java.util.List</code> of <code>java.lang.String</code>
* objects which are platform-specific representations of platform-
* specific data formats
* If the specified {@code DataFlavor} is previously unknown to the data
* transfer subsystem and the data transfer subsystem is unable to translate
* this {@code DataFlavor} to any existing native, then invoking this method
* will establish a mapping in both directions between the specified
* {@code DataFlavor} and an encoded version of its MIME type as its native.
*
* @param flav the {@code DataFlavor} whose corresponding natives should be
* returned. If {@code null} is specified, all natives currently
* known to the data transfer subsystem are returned in a
* non-deterministic order.
* @return a {@code java.util.List} of {@code java.lang.String} objects
* which are platform-specific representations of platform-specific
* data formats
* @see #encodeDataFlavor
* @since 1.4
*/
@ -566,33 +566,30 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Returns a <code>List</code> of <code>DataFlavor</code>s to which the
* specified <code>String</code> native can be translated by the data
* transfer subsystem. The <code>List</code> will be sorted from best
* <code>DataFlavor</code> to worst. That is, the first
* <code>DataFlavor</code> will best reflect data in the specified
* native to a Java application.
* Returns a {@code List} of {@code DataFlavor}s to which the specified
* {@code String} native can be translated by the data transfer subsystem.
* The {@code List} will be sorted from best {@code DataFlavor} to worst.
* That is, the first {@code DataFlavor} will best reflect data in the
* specified native to a Java application.
* <p>
* If the specified native is previously unknown to the data transfer
* subsystem, and that native has been properly encoded, then invoking this
* method will establish a mapping in both directions between the specified
* native and a <code>DataFlavor</code> whose MIME type is a decoded
* version of the native.
* native and a {@code DataFlavor} whose MIME type is a decoded version of
* the native.
* <p>
* If the specified native is not a properly encoded native and the
* mappings for this native have not been altered with
* <code>setFlavorsForNative</code>, then the contents of the
* <code>List</code> is platform dependent, but <code>null</code>
* cannot be returned.
*
* @param nat the native whose corresponding <code>DataFlavor</code>s
* should be returned. If <code>null</code> is specified, all
* <code>DataFlavor</code>s currently known to the data transfer
* subsystem are returned in a non-deterministic order.
* @return a <code>java.util.List</code> of <code>DataFlavor</code>
* objects into which platform-specific data in the specified,
* platform-specific native can be translated
* If the specified native is not a properly encoded native and the mappings
* for this native have not been altered with {@code setFlavorsForNative},
* then the contents of the {@code List} is platform dependent, but
* {@code null} cannot be returned.
*
* @param nat the native whose corresponding {@code DataFlavor}s should be
* returned. If {@code null} is specified, all {@code DataFlavor}s
* currently known to the data transfer subsystem are returned in a
* non-deterministic order.
* @return a {@code java.util.List} of {@code DataFlavor} objects into which
* platform-specific data in the specified, platform-specific native
* can be translated
* @see #encodeJavaMIMEType
* @since 1.4
*/
@ -741,24 +738,23 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to
* their most preferred <code>String</code> native. Each native value will
* be the same as the first native in the List returned by
* <code>getNativesForFlavor</code> for the specified flavor.
* Returns a {@code Map} of the specified {@code DataFlavor}s to their most
* preferred {@code String} native. Each native value will be the same as
* the first native in the List returned by {@code getNativesForFlavor} for
* the specified flavor.
* <p>
* If a specified <code>DataFlavor</code> is previously unknown to the
* data transfer subsystem, then invoking this method will establish a
* mapping in both directions between the specified <code>DataFlavor</code>
* and an encoded version of its MIME type as its native.
*
* @param flavors an array of <code>DataFlavor</code>s which will be the
* key set of the returned <code>Map</code>. If <code>null</code> is
* specified, a mapping of all <code>DataFlavor</code>s known to the
* data transfer subsystem to their most preferred
* <code>String</code> natives will be returned.
* @return a <code>java.util.Map</code> of <code>DataFlavor</code>s to
* <code>String</code> natives
* If a specified {@code DataFlavor} is previously unknown to the data
* transfer subsystem, then invoking this method will establish a mapping in
* both directions between the specified {@code DataFlavor} and an encoded
* version of its MIME type as its native.
*
* @param flavors an array of {@code DataFlavor}s which will be the key set
* of the returned {@code Map}. If {@code null} is specified, a
* mapping of all {@code DataFlavor}s known to the data transfer
* subsystem to their most preferred {@code String} natives will be
* returned.
* @return a {@code java.util.Map} of {@code DataFlavor}s to {@code String}
* natives
* @see #getNativesForFlavor
* @see #encodeDataFlavor
*/
@ -785,26 +781,23 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Returns a <code>Map</code> of the specified <code>String</code> natives
* to their most preferred <code>DataFlavor</code>. Each
* <code>DataFlavor</code> value will be the same as the first
* <code>DataFlavor</code> in the List returned by
* <code>getFlavorsForNative</code> for the specified native.
* Returns a {@code Map} of the specified {@code String} natives to their
* most preferred {@code DataFlavor}. Each {@code DataFlavor} value will be
* the same as the first {@code DataFlavor} in the List returned by
* {@code getFlavorsForNative} for the specified native.
* <p>
* If a specified native is previously unknown to the data transfer
* subsystem, and that native has been properly encoded, then invoking this
* method will establish a mapping in both directions between the specified
* native and a <code>DataFlavor</code> whose MIME type is a decoded
* version of the native.
*
* @param natives an array of <code>String</code>s which will be the
* key set of the returned <code>Map</code>. If <code>null</code> is
* specified, a mapping of all supported <code>String</code> natives
* to their most preferred <code>DataFlavor</code>s will be
* returned.
* @return a <code>java.util.Map</code> of <code>String</code> natives to
* <code>DataFlavor</code>s
* native and a {@code DataFlavor} whose MIME type is a decoded version of
* the native.
*
* @param natives an array of {@code String}s which will be the key set of
* the returned {@code Map}. If {@code null} is specified, a mapping
* of all supported {@code String} natives to their most preferred
* {@code DataFlavor}s will be returned.
* @return a {@code java.util.Map} of {@code String} natives to
* {@code DataFlavor}s
* @see #getFlavorsForNative
* @see #encodeJavaMIMEType
*/
@ -828,22 +821,19 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Adds a mapping from the specified <code>DataFlavor</code> (and all
* <code>DataFlavor</code>s equal to the specified <code>DataFlavor</code>)
* to the specified <code>String</code> native.
* Unlike <code>getNativesForFlavor</code>, the mapping will only be
* established in one direction, and the native will not be encoded. To
* establish a two-way mapping, call
* <code>addFlavorForUnencodedNative</code> as well. The new mapping will
* be of lower priority than any existing mapping.
* This method has no effect if a mapping from the specified or equal
* <code>DataFlavor</code> to the specified <code>String</code> native
* already exists.
*
* @param flav the <code>DataFlavor</code> key for the mapping
* @param nat the <code>String</code> native value for the mapping
* @throws NullPointerException if flav or nat is <code>null</code>
* Adds a mapping from the specified {@code DataFlavor} (and all
* {@code DataFlavor}s equal to the specified {@code DataFlavor}) to the
* specified {@code String} native. Unlike {@code getNativesForFlavor}, the
* mapping will only be established in one direction, and the native will
* not be encoded. To establish a two-way mapping, call
* {@code addFlavorForUnencodedNative} as well. The new mapping will be of
* lower priority than any existing mapping. This method has no effect if a
* mapping from the specified or equal {@code DataFlavor} to the specified
* {@code String} native already exists.
*
* @param flav the {@code DataFlavor} key for the mapping
* @param nat the {@code String} native value for the mapping
* @throws NullPointerException if flav or nat is {@code null}
* @see #addFlavorForUnencodedNative
* @since 1.4
*/
@ -862,30 +852,27 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Discards the current mappings for the specified <code>DataFlavor</code>
* and all <code>DataFlavor</code>s equal to the specified
* <code>DataFlavor</code>, and creates new mappings to the
* specified <code>String</code> natives.
* Unlike <code>getNativesForFlavor</code>, the mappings will only be
* established in one direction, and the natives will not be encoded. To
* establish two-way mappings, call <code>setFlavorsForNative</code>
* as well. The first native in the array will represent the highest
* priority mapping. Subsequent natives will represent mappings of
* decreasing priority.
* Discards the current mappings for the specified {@code DataFlavor} and
* all {@code DataFlavor}s equal to the specified {@code DataFlavor}, and
* creates new mappings to the specified {@code String} natives. Unlike
* {@code getNativesForFlavor}, the mappings will only be established in one
* direction, and the natives will not be encoded. To establish two-way
* mappings, call {@code setFlavorsForNative} as well. The first native in
* the array will represent the highest priority mapping. Subsequent natives
* will represent mappings of decreasing priority.
* <p>
* If the array contains several elements that reference equal
* <code>String</code> natives, this method will establish new mappings
* for the first of those elements and ignore the rest of them.
* {@code String} natives, this method will establish new mappings for the
* first of those elements and ignore the rest of them.
* <p>
* It is recommended that client code not reset mappings established by the
* data transfer subsystem. This method should only be used for
* application-level mappings.
*
* @param flav the <code>DataFlavor</code> key for the mappings
* @param natives the <code>String</code> native values for the mappings
* @throws NullPointerException if flav or natives is <code>null</code>
* or if natives contains <code>null</code> elements
*
* @param flav the {@code DataFlavor} key for the mappings
* @param natives the {@code String} native values for the mappings
* @throws NullPointerException if flav or natives is {@code null} or if
* natives contains {@code null} elements
* @see #setFlavorsForNative
* @since 1.4
*/
@ -903,20 +890,19 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Adds a mapping from a single <code>String</code> native to a single
* <code>DataFlavor</code>. Unlike <code>getFlavorsForNative</code>, the
* mapping will only be established in one direction, and the native will
* not be encoded. To establish a two-way mapping, call
* <code>addUnencodedNativeForFlavor</code> as well. The new mapping will
* be of lower priority than any existing mapping.
* This method has no effect if a mapping from the specified
* <code>String</code> native to the specified or equal
* <code>DataFlavor</code> already exists.
*
* @param nat the <code>String</code> native key for the mapping
* @param flav the <code>DataFlavor</code> value for the mapping
* @throws NullPointerException if nat or flav is <code>null</code>
* Adds a mapping from a single {@code String} native to a single
* {@code DataFlavor}. Unlike {@code getFlavorsForNative}, the mapping will
* only be established in one direction, and the native will not be encoded.
* To establish a two-way mapping, call {@code addUnencodedNativeForFlavor}
* as well. The new mapping will be of lower priority than any existing
* mapping. This method has no effect if a mapping from the specified
* {@code String} native to the specified or equal {@code DataFlavor}
* already exists.
*
* @param nat the {@code String} native key for the mapping
* @param flav the {@code DataFlavor} value for the mapping
* @throws NullPointerException if {@code nat} or {@code flav} is
* {@code null}
* @see #addUnencodedNativeForFlavor
* @since 1.4
*/
@ -935,29 +921,27 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Discards the current mappings for the specified <code>String</code>
* native, and creates new mappings to the specified
* <code>DataFlavor</code>s. Unlike <code>getFlavorsForNative</code>, the
* mappings will only be established in one direction, and the natives need
* not be encoded. To establish two-way mappings, call
* <code>setNativesForFlavor</code> as well. The first
* <code>DataFlavor</code> in the array will represent the highest priority
* mapping. Subsequent <code>DataFlavor</code>s will represent mappings of
* Discards the current mappings for the specified {@code String} native,
* and creates new mappings to the specified {@code DataFlavor}s. Unlike
* {@code getFlavorsForNative}, the mappings will only be established in one
* direction, and the natives need not be encoded. To establish two-way
* mappings, call {@code setNativesForFlavor} as well. The first
* {@code DataFlavor} in the array will represent the highest priority
* mapping. Subsequent {@code DataFlavor}s will represent mappings of
* decreasing priority.
* <p>
* If the array contains several elements that reference equal
* <code>DataFlavor</code>s, this method will establish new mappings
* for the first of those elements and ignore the rest of them.
* {@code DataFlavor}s, this method will establish new mappings for the
* first of those elements and ignore the rest of them.
* <p>
* It is recommended that client code not reset mappings established by the
* data transfer subsystem. This method should only be used for
* application-level mappings.
*
* @param nat the <code>String</code> native key for the mappings
* @param flavors the <code>DataFlavor</code> values for the mappings
* @throws NullPointerException if nat or flavors is <code>null</code>
* or if flavors contains <code>null</code> elements
*
* @param nat the {@code String} native key for the mappings
* @param flavors the {@code DataFlavor} values for the mappings
* @throws NullPointerException if {@code nat} or {@code flavors} is
* {@code null} or if {@code flavors} contains {@code null} elements
* @see #setNativesForFlavor
* @since 1.4
*/
@ -975,23 +959,22 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Encodes a MIME type for use as a <code>String</code> native. The format
* of an encoded representation of a MIME type is implementation-dependent.
* The only restrictions are:
* Encodes a MIME type for use as a {@code String} native. The format of an
* encoded representation of a MIME type is implementation-dependent. The
* only restrictions are:
* <ul>
* <li>The encoded representation is <code>null</code> if and only if the
* MIME type <code>String</code> is <code>null</code>.</li>
* <li>The encoded representations for two non-<code>null</code> MIME type
* <code>String</code>s are equal if and only if these <code>String</code>s
* are equal according to <code>String.equals(Object)</code>.</li>
* <li>The encoded representation is {@code null} if and only if the MIME
* type {@code String} is {@code null}</li>
* <li>The encoded representations for two non-{@code null} MIME type
* {@code String}s are equal if and only if these {@code String}s are
* equal according to {@code String.equals(Object)}</li>
* </ul>
* <p>
* The reference implementation of this method returns the specified MIME
* type <code>String</code> prefixed with <code>JAVA_DATAFLAVOR:</code>.
* type {@code String} prefixed with {@code JAVA_DATAFLAVOR:}.
*
* @param mimeType the MIME type to encode
* @return the encoded <code>String</code>, or <code>null</code> if
* mimeType is <code>null</code>
* @param mimeType the MIME type to encode
* @return the encoded {@code String}, or {@code null} if {@code mimeType}
* is {@code null}
*/
public static String encodeJavaMIMEType(String mimeType) {
return (mimeType != null)
@ -1000,27 +983,26 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Encodes a <code>DataFlavor</code> for use as a <code>String</code>
* native. The format of an encoded <code>DataFlavor</code> is
* implementation-dependent. The only restrictions are:
* Encodes a {@code DataFlavor} for use as a {@code String} native. The
* format of an encoded {@code DataFlavor} is implementation-dependent. The
* only restrictions are:
* <ul>
* <li>The encoded representation is <code>null</code> if and only if the
* specified <code>DataFlavor</code> is <code>null</code> or its MIME type
* <code>String</code> is <code>null</code>.</li>
* <li>The encoded representations for two non-<code>null</code>
* <code>DataFlavor</code>s with non-<code>null</code> MIME type
* <code>String</code>s are equal if and only if the MIME type
* <code>String</code>s of these <code>DataFlavor</code>s are equal
* according to <code>String.equals(Object)</code>.</li>
* <li>The encoded representation is {@code null} if and only if the
* specified {@code DataFlavor} is {@code null} or its MIME type
* {@code String} is {@code null}</li>
* <li>The encoded representations for two non-{@code null}
* {@code DataFlavor}s with non-{@code null} MIME type {@code String}s
* are equal if and only if the MIME type {@code String}s of these
* {@code DataFlavor}s are equal according to
* {@code String.equals(Object)}</li>
* </ul>
* <p>
* The reference implementation of this method returns the MIME type
* <code>String</code> of the specified <code>DataFlavor</code> prefixed
* with <code>JAVA_DATAFLAVOR:</code>.
* {@code String} of the specified {@code DataFlavor} prefixed with
* {@code JAVA_DATAFLAVOR:}.
*
* @param flav the <code>DataFlavor</code> to encode
* @return the encoded <code>String</code>, or <code>null</code> if
* flav is <code>null</code> or has a <code>null</code> MIME type
* @param flav the {@code DataFlavor} to encode
* @return the encoded {@code String}, or {@code null} if {@code flav} is
* {@code null} or has a {@code null} MIME type
*/
public static String encodeDataFlavor(DataFlavor flav) {
return (flav != null)
@ -1029,23 +1011,23 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Returns whether the specified <code>String</code> is an encoded Java
* MIME type.
* Returns whether the specified {@code String} is an encoded Java MIME
* type.
*
* @param str the <code>String</code> to test
* @return <code>true</code> if the <code>String</code> is encoded;
* <code>false</code> otherwise
* @param str the {@code String} to test
* @return {@code true} if the {@code String} is encoded; {@code false}
* otherwise
*/
public static boolean isJavaMIMEType(String str) {
return (str != null && str.startsWith(JavaMIME, 0));
}
/**
* Decodes a <code>String</code> native for use as a Java MIME type.
* Decodes a {@code String} native for use as a Java MIME type.
*
* @param nat the <code>String</code> to decode
* @return the decoded Java MIME type, or <code>null</code> if nat is not
* an encoded <code>String</code> native
* @param nat the {@code String} to decode
* @return the decoded Java MIME type, or {@code null} if {@code nat} is not
* an encoded {@code String} native
*/
public static String decodeJavaMIMEType(String nat) {
return (isJavaMIMEType(nat))
@ -1054,14 +1036,13 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
}
/**
* Decodes a <code>String</code> native for use as a
* <code>DataFlavor</code>.
* Decodes a {@code String} native for use as a {@code DataFlavor}.
*
* @param nat the <code>String</code> to decode
* @return the decoded <code>DataFlavor</code>, or <code>null</code> if
* nat is not an encoded <code>String</code> native
* @throws ClassNotFoundException if the class of the data flavor
* is not loaded
* @param nat the {@code String} to decode
* @return the decoded {@code DataFlavor}, or {@code null} if {@code nat} is
* not an encoded {@code String} native
* @throws ClassNotFoundException if the class of the data flavor is not
* loaded
*/
public static DataFlavor decodeDataFlavor(String nat)
throws ClassNotFoundException

Some files were not shown because too many files have changed in this diff Show More