Merge
This commit is contained in:
commit
dbf777504b
@ -405,3 +405,5 @@ c476ca73750698fa5654e101af699ee45db38e2a jdk-9+158
|
||||
cac788454598b95d8b0153c021a7fae3cd7e6fda jdk-9+160
|
||||
09b92d3067a38ee07bc14efa336b14790c93f7e7 jdk-9+161
|
||||
f6bf027e88e9a4dd19f721001a7af00157af42c4 jdk-9+162
|
||||
50171f8c47961710cbf87aead6f03fa431d8d240 jdk-9+163
|
||||
6dea581453d7c0e767e3169cfec8b423a381e71d jdk-9+164
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2014, 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,7 +31,7 @@ include MakeBase.gmk
|
||||
include ModuleTools.gmk
|
||||
|
||||
GENGRAPHS_DIR := $(IMAGES_OUTPUTDIR)/gengraphs
|
||||
SPEC_DOTFILES_DIR := $(IMAGES_OUTPUTDIR)/spec-dotfiles
|
||||
SPEC_DOTFILES_DIR := $(GENGRAPHS_DIR)/spec-dotfiles
|
||||
TOOLS_MODULE_SRCDIR := $(JDK_TOPDIR)/make/src/classes/build/tools/jigsaw
|
||||
|
||||
$(GENGRAPHS_DIR)/jdk.dot: $(BUILD_JIGSAW_TOOLS)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2013, 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
|
||||
@ -23,8 +23,9 @@
|
||||
# questions.
|
||||
#
|
||||
|
||||
include $(SPEC)
|
||||
include MakeBase.gmk
|
||||
ifndef _MODULE_TOOLS_GMK
|
||||
_MODULE_TOOLS_GMK := 1
|
||||
|
||||
include JavaCompilation.gmk
|
||||
|
||||
TOOLS_CLASSES_DIR := $(BUILDTOOLS_OUTPUTDIR)/tools_jigsaw_classes
|
||||
@ -32,7 +33,7 @@ TOOLS_CLASSES_DIR := $(BUILDTOOLS_OUTPUTDIR)/tools_jigsaw_classes
|
||||
# To avoid reevaluating the compilation setup for the tools each time this file
|
||||
# is included, the actual compilation is handled by CompileModuleTools.gmk. The
|
||||
# following trick is used to be able to declare a dependency on the built tools.
|
||||
BUILD_TOOLS_JDK := $(call SetupJavaCompilationCompileTarget, \
|
||||
BUILD_JIGSAW_TOOLS := $(call SetupJavaCompilationCompileTarget, \
|
||||
BUILD_JIGSAW_TOOLS, $(TOOLS_CLASSES_DIR))
|
||||
|
||||
TOOL_GENGRAPHS := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
|
||||
@ -47,3 +48,5 @@ TOOL_ADD_PACKAGES_ATTRIBUTE := $(BUILD_JAVA) $(JAVA_FLAGS_SMALL) \
|
||||
-cp $(TOOLS_CLASSES_DIR) \
|
||||
--add-exports java.base/jdk.internal.module=ALL-UNNAMED \
|
||||
build.tools.jigsaw.AddPackagesAttribute
|
||||
|
||||
endif # _MODULE_TOOLS_GMK
|
||||
|
@ -21,4 +21,4 @@
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
tzdata2017a
|
||||
tzdata2017b
|
||||
|
@ -443,18 +443,25 @@ Link Africa/Nairobi Indian/Mayotte
|
||||
# See Africa/Johannesburg.
|
||||
|
||||
# Liberia
|
||||
# From Paul Eggert (2006-03-22):
|
||||
# In 1972 Liberia was the last country to switch
|
||||
# from a UTC offset that was not a multiple of 15 or 20 minutes.
|
||||
# Howse reports that it was in honor of their president's birthday.
|
||||
# Shank & Pottenger report the date as May 1, whereas Howse reports Jan;
|
||||
# go with Shanks & Pottenger.
|
||||
# For Liberia before 1972, Shanks & Pottenger report -0:44, whereas Howse and
|
||||
# Whitman each report -0:44:30; go with the more precise figure.
|
||||
#
|
||||
# From Paul Eggert (2017-03-02):
|
||||
#
|
||||
# The Nautical Almanac for the Year 1970, p 264, is the source for -0:44:30.
|
||||
#
|
||||
# In 1972 Liberia was the last country to switch from a UTC offset
|
||||
# that was not a multiple of 15 or 20 minutes. The 1972 change was on
|
||||
# 1972-01-07, according to an entry dated 1972-01-04 on p 330 of:
|
||||
# Presidential Papers: First year of the administration of
|
||||
# President William R. Tolbert, Jr., July 23, 1971-July 31, 1972.
|
||||
# Monrovia: Executive Mansion.
|
||||
#
|
||||
# Use the abbreviation "MMT" before 1972, as the more-accurate numeric
|
||||
# abbreviation "-004430" would be one byte over the POSIX limit.
|
||||
#
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Africa/Monrovia -0:43:08 - LMT 1882
|
||||
-0:43:08 - MMT 1919 Mar # Monrovia Mean Time
|
||||
-0:44:30 - -004430 1972 May
|
||||
-0:44:30 - MMT 1972 Jan 7 # approximately MMT
|
||||
0:00 - GMT
|
||||
|
||||
###############################################################################
|
||||
|
@ -32,8 +32,8 @@
|
||||
# All text uses UTF-8 encoding. The columns of the table are as follows:
|
||||
#
|
||||
# 1. ISO 3166-1 alpha-2 country code, current as of
|
||||
# ISO 3166-1 Newsletter VI-16 (2013-07-11). See: Updates on ISO 3166
|
||||
# http://www.iso.org/iso/home/standards/country_codes/updates_on_iso_3166.htm
|
||||
# ISO 3166-1 N905 (2016-11-15). See: Updates on ISO 3166-1
|
||||
# http://isotc.iso.org/livelink/livelink/Open/16944257
|
||||
# 2. The usual English name for the coded region,
|
||||
# chosen so that alphabetic sorting of subsets produces helpful lists.
|
||||
# This is not the same as the English name in the ISO 3166 tables.
|
||||
|
@ -3162,6 +3162,12 @@ Zone America/Guatemala -6:02:04 - LMT 1918 Oct 5
|
||||
# http://www.vantbefinfo.com/changement-dheure-pas-pour-haiti/
|
||||
# http://news.anmwe.com/haiti-lheure-nationale-ne-sera-ni-avancee-ni-reculee-cette-annee/
|
||||
|
||||
# From Steffen Thorsen (2017-03-12):
|
||||
# We have received 4 mails from different people telling that Haiti
|
||||
# has started DST again today, and this source seems to confirm that,
|
||||
# I have not been able to find a more authoritative source:
|
||||
# https://www.haitilibre.com/en/news-20319-haiti-notices-time-change-in-haiti.html
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule Haiti 1983 only - May 8 0:00 1:00 D
|
||||
Rule Haiti 1984 1987 - Apr lastSun 0:00 1:00 D
|
||||
@ -3174,6 +3180,8 @@ Rule Haiti 2005 2006 - Apr Sun>=1 0:00 1:00 D
|
||||
Rule Haiti 2005 2006 - Oct lastSun 0:00 0 S
|
||||
Rule Haiti 2012 2015 - Mar Sun>=8 2:00 1:00 D
|
||||
Rule Haiti 2012 2015 - Nov Sun>=1 2:00 0 S
|
||||
Rule Haiti 2017 max - Mar Sun>=8 2:00 1:00 D
|
||||
Rule Haiti 2017 max - Nov Sun>=1 2:00 0 S
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone America/Port-au-Prince -4:49:20 - LMT 1890
|
||||
-4:49 - PPMT 1917 Jan 24 12:00 # P-a-P MT
|
||||
|
@ -273,12 +273,12 @@ SUNWprivate_1.1 {
|
||||
Java_jdk_internal_misc_VM_getRuntimeArguments;
|
||||
Java_jdk_internal_misc_VM_initialize;
|
||||
|
||||
Java_java_lang_reflect_Module_defineModule0;
|
||||
Java_java_lang_reflect_Module_addReads0;
|
||||
Java_java_lang_reflect_Module_addExports0;
|
||||
Java_java_lang_reflect_Module_addExportsToAll0;
|
||||
Java_java_lang_reflect_Module_addExportsToAllUnnamed0;
|
||||
Java_java_lang_reflect_Module_addPackage0;
|
||||
Java_java_lang_Module_defineModule0;
|
||||
Java_java_lang_Module_addReads0;
|
||||
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;
|
||||
|
@ -26,7 +26,6 @@
|
||||
package build.tools.jigsaw;
|
||||
|
||||
import com.sun.tools.jdeps.ModuleDotGraph;
|
||||
import com.sun.tools.jdeps.ModuleDotGraph.DotGraphBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.module.Configuration;
|
||||
@ -36,10 +35,15 @@ import java.lang.module.ModuleReference;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Generate the DOT file for a module graph for each module in the JDK
|
||||
@ -50,13 +54,19 @@ public class GenGraphs {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Path dir = null;
|
||||
boolean spec = false;
|
||||
Properties props = null;
|
||||
for (int i=0; i < args.length; i++) {
|
||||
String arg = args[i];
|
||||
if (arg.equals("--spec")) {
|
||||
spec = true;
|
||||
} else if (arg.equals("--dot-attributes")) {
|
||||
if (i++ == args.length) {
|
||||
throw new IllegalArgumentException("Missing argument: --dot-attributes option");
|
||||
}
|
||||
props = new Properties();
|
||||
props.load(Files.newInputStream(Paths.get(args[i])));
|
||||
} else if (arg.equals("--output")) {
|
||||
i++;
|
||||
dir = i < args.length ? Paths.get(args[i]) : null;
|
||||
dir = ++i < args.length ? Paths.get(args[i]) : null;
|
||||
} else if (arg.startsWith("-")) {
|
||||
throw new IllegalArgumentException("Invalid option: " + arg);
|
||||
}
|
||||
@ -67,11 +77,14 @@ public class GenGraphs {
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// setup and configure the dot graph attributes
|
||||
initDotGraphAttributes();
|
||||
Files.createDirectories(dir);
|
||||
|
||||
GenGraphs genGraphs = new GenGraphs(dir, spec);
|
||||
ModuleGraphAttributes attributes;
|
||||
if (props != null) {
|
||||
attributes = new ModuleGraphAttributes(props);
|
||||
} else {
|
||||
attributes = new ModuleGraphAttributes();
|
||||
}
|
||||
GenGraphs genGraphs = new GenGraphs(dir, spec, attributes);
|
||||
|
||||
// print dot file for each module
|
||||
Map<String, Configuration> configurations = new HashMap<>();
|
||||
@ -99,49 +112,149 @@ public class GenGraphs {
|
||||
genGraphs.genDotFiles(configurations);
|
||||
}
|
||||
|
||||
static void initDotGraphAttributes() {
|
||||
int h = 1000;
|
||||
DotGraphBuilder.weight("java.se", "java.sql.rowset", h * 10);
|
||||
DotGraphBuilder.weight("java.sql.rowset", "java.sql", h * 10);
|
||||
DotGraphBuilder.weight("java.sql", "java.xml", h * 10);
|
||||
DotGraphBuilder.weight("java.xml", "java.base", h * 10);
|
||||
/**
|
||||
* Custom dot file attributes.
|
||||
*/
|
||||
static class ModuleGraphAttributes implements ModuleDotGraph.Attributes {
|
||||
static Map<String, String> DEFAULT_ATTRIBUTES = Map.of(
|
||||
"ranksep", "0.6",
|
||||
"fontsize", "12",
|
||||
"fontcolor", BLACK,
|
||||
"fontname", "DejaVuSans",
|
||||
"arrowsize", "1",
|
||||
"arrowwidth", "2",
|
||||
"arrowcolor", DARK_GRAY,
|
||||
// custom
|
||||
"requiresMandatedColor", LIGHT_GRAY,
|
||||
"javaSubgraphColor", ORANGE,
|
||||
"jdkSubgraphColor", BLUE
|
||||
);
|
||||
|
||||
DotGraphBuilder.sameRankNodes(Set.of("java.logging", "java.scripting", "java.xml"));
|
||||
DotGraphBuilder.sameRankNodes(Set.of("java.sql"));
|
||||
DotGraphBuilder.sameRankNodes(Set.of("java.compiler", "java.instrument"));
|
||||
DotGraphBuilder.sameRankNodes(Set.of("java.desktop", "java.management"));
|
||||
DotGraphBuilder.sameRankNodes(Set.of("java.corba", "java.xml.ws"));
|
||||
DotGraphBuilder.sameRankNodes(Set.of("java.xml.bind", "java.xml.ws.annotation"));
|
||||
DotGraphBuilder.setRankSep(0.7);
|
||||
DotGraphBuilder.setFontSize(12);
|
||||
DotGraphBuilder.setArrowSize(1);
|
||||
DotGraphBuilder.setArrowWidth(2);
|
||||
final Map<String, Integer> weights = new HashMap<>();
|
||||
final List<Set<String>> ranks = new ArrayList<>();
|
||||
final Map<String, String> attrs;
|
||||
ModuleGraphAttributes(Map<String, String> attrs) {
|
||||
int h = 1000;
|
||||
weight("java.se", "java.sql.rowset", h * 10);
|
||||
weight("java.sql.rowset", "java.sql", h * 10);
|
||||
weight("java.sql", "java.xml", h * 10);
|
||||
weight("java.xml", "java.base", h * 10);
|
||||
|
||||
ranks.add(Set.of("java.logging", "java.scripting", "java.xml"));
|
||||
ranks.add(Set.of("java.sql"));
|
||||
ranks.add(Set.of("java.compiler", "java.instrument"));
|
||||
ranks.add(Set.of("java.desktop", "java.management"));
|
||||
ranks.add(Set.of("java.corba", "java.xml.ws"));
|
||||
ranks.add(Set.of("java.xml.bind", "java.xml.ws.annotation"));
|
||||
|
||||
this.attrs = attrs;
|
||||
}
|
||||
|
||||
ModuleGraphAttributes() {
|
||||
this(DEFAULT_ATTRIBUTES);
|
||||
}
|
||||
ModuleGraphAttributes(Properties props) {
|
||||
this(toAttributes(props));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double rankSep() {
|
||||
return Double.valueOf(attrs.get("ranksep"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fontSize() {
|
||||
return Integer.valueOf(attrs.get("fontsize"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fontName() {
|
||||
return attrs.get("fontname");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fontColor() {
|
||||
return attrs.get("fontcolor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int arrowSize() {
|
||||
return Integer.valueOf(attrs.get("arrowsize"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int arrowWidth() {
|
||||
return Integer.valueOf(attrs.get("arrowwidth"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String arrowColor() {
|
||||
return attrs.get("arrowcolor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Set<String>> ranks() {
|
||||
return ranks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String requiresMandatedColor() {
|
||||
return attrs.get("requiresMandatedColor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String javaSubgraphColor() {
|
||||
return attrs.get("javaSubgraphColor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String jdkSubgraphColor() {
|
||||
return attrs.get("jdkSubgraphColor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int weightOf(String s, String t) {
|
||||
int w = weights.getOrDefault(s + ":" + t, 1);
|
||||
if (w != 1)
|
||||
return w;
|
||||
if (s.startsWith("java.") && t.startsWith("java."))
|
||||
return 10;
|
||||
return 1;
|
||||
}
|
||||
|
||||
public void weight(String s, String t, int w) {
|
||||
weights.put(s + ":" + t, w);
|
||||
}
|
||||
|
||||
static Map<String, String> toAttributes(Properties props) {
|
||||
return DEFAULT_ATTRIBUTES.keySet().stream()
|
||||
.collect(Collectors.toMap(Function.identity(),
|
||||
k -> props.getProperty(k, DEFAULT_ATTRIBUTES.get(k))));
|
||||
}
|
||||
}
|
||||
|
||||
private final Path dir;
|
||||
private final boolean spec;
|
||||
GenGraphs(Path dir, boolean spec) {
|
||||
private final ModuleGraphAttributes attributes;
|
||||
GenGraphs(Path dir, boolean spec, ModuleGraphAttributes attributes) {
|
||||
this.dir = dir;
|
||||
this.spec = spec;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
void genDotFiles(Map<String, Configuration> configurations) throws IOException {
|
||||
ModuleDotGraph dotGraph = new ModuleDotGraph(configurations, spec);
|
||||
dotGraph.genDotFiles(dir);
|
||||
dotGraph.genDotFiles(dir, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true for any name if generating graph for non-spec;
|
||||
* otherwise, returns true except "jdk" and name with "jdk.internal." prefix
|
||||
*/
|
||||
boolean accept(String name, ModuleDescriptor descriptor) {
|
||||
if (!spec) return true;
|
||||
|
||||
if (name.equals("jdk"))
|
||||
return false;
|
||||
|
||||
if (name.equals("java.se") || name.equals("java.se.ee"))
|
||||
if (!spec)
|
||||
return true;
|
||||
|
||||
// only the module that has exported API
|
||||
return descriptor.exports().stream()
|
||||
.filter(e -> !e.isQualified())
|
||||
.findAny().isPresent();
|
||||
return !name.equals("jdk") && !name.startsWith("jdk.internal.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,2 @@
|
||||
arrowcolor=#999999
|
||||
requiresMandatedColor=#999999
|
96
jdk/make/src/classes/build/tools/taglet/ModuleGraph.java
Normal file
96
jdk/make/src/classes/build/tools/taglet/ModuleGraph.java
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.taglet;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.lang.model.element.Element;
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet;
|
||||
import static jdk.javadoc.doclet.Taglet.Location.*;
|
||||
|
||||
/**
|
||||
* A block tag to optionally insert a reference to a module graph.
|
||||
*/
|
||||
public class ModuleGraph implements Taglet {
|
||||
private static final boolean enableModuleGraph =
|
||||
Boolean.getBoolean("enableModuleGraph");
|
||||
|
||||
/** Returns the set of locations in which a taglet may be used. */
|
||||
@Override
|
||||
public Set<Location> getAllowedLocations() {
|
||||
return EnumSet.of(MODULE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInlineTag() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "moduleGraph";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(List<? extends DocTree> tags, Element element) {
|
||||
if (!enableModuleGraph) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String moduleName = element.getSimpleName().toString();
|
||||
String imageFile = moduleName + "-graph.png";
|
||||
int thumbnailHeight = -1;
|
||||
String hoverImage = "";
|
||||
if (!moduleName.equals("java.base")) {
|
||||
thumbnailHeight = 100; // also appears in the stylesheet
|
||||
hoverImage = "<span>"
|
||||
+ getImage(moduleName, imageFile, -1, true)
|
||||
+ "</span>";
|
||||
}
|
||||
return "<dt>"
|
||||
+ "<span class=\"simpleTagLabel\">Module Graph:</span>\n"
|
||||
+ "</dt>"
|
||||
+ "<dd>"
|
||||
+ "<a class=moduleGraph href=\"" + imageFile + "\">"
|
||||
+ getImage(moduleName, imageFile, thumbnailHeight, false)
|
||||
+ hoverImage
|
||||
+ "</a>"
|
||||
+ "</dd>";
|
||||
}
|
||||
|
||||
private static final String VERTICAL_ALIGN = "vertical-align:top";
|
||||
private static final String BORDER = "border: solid lightgray 1px;";
|
||||
|
||||
private String getImage(String moduleName, String file, int height, boolean useBorder) {
|
||||
return String.format("<img style=\"%s\" alt=\"Module graph for %s\" src=\"%s\"%s>",
|
||||
useBorder ? BORDER + " " + VERTICAL_ALIGN : VERTICAL_ALIGN,
|
||||
moduleName,
|
||||
file,
|
||||
(height <= 0 ? "" : " height=\"" + height + "\""));
|
||||
}
|
||||
}
|
@ -50,10 +50,11 @@ class DefaultInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose a default interface. This method returns an interface that is
|
||||
* both "up" and supports multicast. This method choses an interface in
|
||||
* Choose a default interface. This method returns the first interface that
|
||||
* is both "up" and supports multicast. This method chooses an interface in
|
||||
* order of preference:
|
||||
* 1. neither loopback nor point to point
|
||||
* ( prefer interfaces with dual IP support )
|
||||
* 2. point to point
|
||||
* 3. loopback
|
||||
*
|
||||
@ -66,32 +67,56 @@ class DefaultInterface {
|
||||
try {
|
||||
nifs = NetworkInterface.getNetworkInterfaces();
|
||||
} catch (IOException ignore) {
|
||||
// unable to enumate network interfaces
|
||||
// unable to enumerate network interfaces
|
||||
return null;
|
||||
}
|
||||
|
||||
NetworkInterface preferred = null;
|
||||
NetworkInterface ppp = null;
|
||||
NetworkInterface loopback = null;
|
||||
|
||||
while (nifs.hasMoreElements()) {
|
||||
NetworkInterface ni = nifs.nextElement();
|
||||
try {
|
||||
if (ni.isUp() && ni.supportsMulticast()) {
|
||||
boolean isLoopback = ni.isLoopback();
|
||||
boolean isPPP = ni.isPointToPoint();
|
||||
if (!isLoopback && !isPPP) {
|
||||
// found an interface that is not the loopback or a
|
||||
// point-to-point interface
|
||||
if (!ni.isUp() || !ni.supportsMulticast())
|
||||
continue;
|
||||
|
||||
boolean ip4 = false, ip6 = false;
|
||||
Enumeration<InetAddress> addrs = ni.getInetAddresses();
|
||||
while (addrs.hasMoreElements()) {
|
||||
InetAddress addr = addrs.nextElement();
|
||||
if (!addr.isAnyLocalAddress()) {
|
||||
if (addr instanceof Inet4Address) {
|
||||
ip4 = true;
|
||||
} else if (addr instanceof Inet6Address) {
|
||||
ip6 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isLoopback = ni.isLoopback();
|
||||
boolean isPPP = ni.isPointToPoint();
|
||||
if (!isLoopback && !isPPP) {
|
||||
// found an interface that is not the loopback or a
|
||||
// point-to-point interface
|
||||
if (preferred == null) {
|
||||
preferred = ni;
|
||||
} else if (ip4 && ip6){
|
||||
return ni;
|
||||
}
|
||||
if (ppp == null && isPPP)
|
||||
ppp = ni;
|
||||
if (loopback == null && isLoopback)
|
||||
loopback = ni;
|
||||
}
|
||||
if (ppp == null && isPPP)
|
||||
ppp = ni;
|
||||
if (loopback == null && isLoopback)
|
||||
loopback = ni;
|
||||
|
||||
} catch (IOException skip) { }
|
||||
}
|
||||
|
||||
return (ppp != null) ? ppp : loopback;
|
||||
if (preferred != null) {
|
||||
return preferred;
|
||||
} else {
|
||||
return (ppp != null) ? ppp : loopback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
@ -149,6 +149,7 @@ final class DESKey implements SecretKey {
|
||||
* Ensures that the bytes of this key are
|
||||
* set to zero when there are no more references to it.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (this.key != null) {
|
||||
|
@ -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
|
||||
@ -150,6 +150,7 @@ final class DESedeKey implements SecretKey {
|
||||
* Ensures that the bytes of this key are
|
||||
* set to zero when there are no more references to it.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (this.key != null) {
|
||||
|
@ -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
|
||||
@ -145,6 +145,7 @@ final class PBEKey implements SecretKey {
|
||||
* Ensures that the password bytes of this key are
|
||||
* set to zero when there are no more references to it.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (this.key != null) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2016, 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
|
||||
@ -267,6 +267,7 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
|
||||
* Ensures that the password bytes of this key are
|
||||
* erased when there are no more references to it.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (this.passwd != null) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, 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
|
||||
@ -297,14 +297,15 @@ public class BufferedReader extends Reader {
|
||||
|
||||
/**
|
||||
* Reads a line of text. A line is considered to be terminated by any one
|
||||
* of a line feed ('\n'), a carriage return ('\r'), or a carriage return
|
||||
* followed immediately by a linefeed.
|
||||
* of a line feed ('\n'), a carriage return ('\r'), a carriage return
|
||||
* followed immediately by a line feed, or by reaching the end-of-file
|
||||
* (EOF).
|
||||
*
|
||||
* @param ignoreLF If true, the next '\n' will be skipped
|
||||
*
|
||||
* @return A String containing the contents of the line, not including
|
||||
* any line-termination characters, or null if the end of the
|
||||
* stream has been reached
|
||||
* stream has been reached without reading any characters
|
||||
*
|
||||
* @see java.io.LineNumberReader#readLine()
|
||||
*
|
||||
@ -375,12 +376,13 @@ public class BufferedReader extends Reader {
|
||||
|
||||
/**
|
||||
* Reads a line of text. A line is considered to be terminated by any one
|
||||
* of a line feed ('\n'), a carriage return ('\r'), or a carriage return
|
||||
* followed immediately by a linefeed.
|
||||
* of a line feed ('\n'), a carriage return ('\r'), a carriage return
|
||||
* followed immediately by a line feed, or by reaching the end-of-file
|
||||
* (EOF).
|
||||
*
|
||||
* @return A String containing the contents of the line, not including
|
||||
* any line-termination characters, or null if the end of the
|
||||
* stream has been reached
|
||||
* stream has been reached without reading any characters
|
||||
*
|
||||
* @exception IOException If an I/O error occurs
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 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
|
||||
@ -413,9 +413,19 @@ class FileInputStream extends InputStream
|
||||
* Ensures that the <code>close</code> method of this file input stream is
|
||||
* called when there are no more references to it.
|
||||
*
|
||||
* @deprecated The {@code finalize} method has been deprecated.
|
||||
* Subclasses that override {@code finalize} in order to perform cleanup
|
||||
* should be modified to use alternative cleanup mechanisms and
|
||||
* to remove the overriding {@code finalize} method.
|
||||
* When overriding the {@code finalize} method, its implementation must explicitly
|
||||
* ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
|
||||
* See the specification for {@link Object#finalize()} for further
|
||||
* information about migration options.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
* @see java.io.FileInputStream#close()
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
protected void finalize() throws IOException {
|
||||
if ((fd != null) && (fd != FileDescriptor.in)) {
|
||||
/* if fd is shared, the references in FileDescriptor
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 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
|
||||
@ -427,9 +427,18 @@ class FileOutputStream extends OutputStream
|
||||
* <code>close</code> method of this file output stream is
|
||||
* called when there are no more references to this stream.
|
||||
*
|
||||
* @deprecated The {@code finalize} method has been deprecated.
|
||||
* Subclasses that override {@code finalize} in order to perform cleanup
|
||||
* should be modified to use alternative cleanup mechanisms and
|
||||
* to remove the overriding {@code finalize} method.
|
||||
* When overriding the {@code finalize} method, its implementation must explicitly
|
||||
* ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
|
||||
* See the specification for {@link Object#finalize()} for further
|
||||
* information about migration options.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
* @see java.io.FileInputStream#close()
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
protected void finalize() throws IOException {
|
||||
if (fd != null) {
|
||||
if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
|
||||
|
@ -322,7 +322,7 @@ public interface ObjectInputFilter {
|
||||
* Other patterns match or reject class or package name
|
||||
* as returned from {@link Class#getName() Class.getName()} and
|
||||
* if an optional module name is present
|
||||
* {@link java.lang.reflect.Module#getName() class.getModule().getName()}.
|
||||
* {@link Module#getName() class.getModule().getName()}.
|
||||
* Note that for arrays the element type is used in the pattern,
|
||||
* not the array type.
|
||||
* <ul>
|
||||
|
@ -43,7 +43,6 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Module;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
@ -2561,21 +2560,16 @@ public final class Class<T> implements java.io.Serializable,
|
||||
public InputStream getResourceAsStream(String name) {
|
||||
name = resolveName(name);
|
||||
|
||||
Module module = getModule();
|
||||
if (module.isNamed()) {
|
||||
if (Resources.canEncapsulate(name)) {
|
||||
Module caller = Reflection.getCallerClass().getModule();
|
||||
if (caller != module) {
|
||||
Set<String> packages = module.getDescriptor().packages();
|
||||
String pn = Resources.toPackageName(name);
|
||||
if (packages.contains(pn) && !module.isOpen(pn, caller)) {
|
||||
// resource is in package not open to caller
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Module thisModule = getModule();
|
||||
if (thisModule.isNamed()) {
|
||||
// check if resource can be located by caller
|
||||
if (Resources.canEncapsulate(name)
|
||||
&& !isOpenToCaller(name, Reflection.getCallerClass())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String mn = module.getName();
|
||||
// resource not encapsulated or in package open to caller
|
||||
String mn = thisModule.getName();
|
||||
ClassLoader cl = getClassLoader0();
|
||||
try {
|
||||
|
||||
@ -2663,20 +2657,16 @@ public final class Class<T> implements java.io.Serializable,
|
||||
public URL getResource(String name) {
|
||||
name = resolveName(name);
|
||||
|
||||
Module module = getModule();
|
||||
if (module.isNamed()) {
|
||||
if (Resources.canEncapsulate(name)) {
|
||||
Module caller = Reflection.getCallerClass().getModule();
|
||||
if (caller != module) {
|
||||
Set<String> packages = module.getDescriptor().packages();
|
||||
String pn = Resources.toPackageName(name);
|
||||
if (packages.contains(pn) && !module.isOpen(pn, caller)) {
|
||||
// resource is in package not open to caller
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Module thisModule = getModule();
|
||||
if (thisModule.isNamed()) {
|
||||
// check if resource can be located by caller
|
||||
if (Resources.canEncapsulate(name)
|
||||
&& !isOpenToCaller(name, Reflection.getCallerClass())) {
|
||||
return null;
|
||||
}
|
||||
String mn = getModule().getName();
|
||||
|
||||
// resource not encapsulated or in package open to caller
|
||||
String mn = thisModule.getName();
|
||||
ClassLoader cl = getClassLoader0();
|
||||
try {
|
||||
if (cl == null) {
|
||||
@ -2698,10 +2688,36 @@ public final class Class<T> implements java.io.Serializable,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a resource with the given name can be located by the
|
||||
* given caller. All resources in a module can be located by code in
|
||||
* the module. For other callers, then the package needs to be open to
|
||||
* the caller.
|
||||
*/
|
||||
private boolean isOpenToCaller(String name, Class<?> caller) {
|
||||
// assert getModule().isNamed();
|
||||
Module thisModule = getModule();
|
||||
Module callerModule = (caller != null) ? caller.getModule() : null;
|
||||
if (callerModule != thisModule) {
|
||||
String pn = Resources.toPackageName(name);
|
||||
if (thisModule.getDescriptor().packages().contains(pn)) {
|
||||
if (callerModule == null && !thisModule.isOpen(pn)) {
|
||||
// no caller, package not open
|
||||
return false;
|
||||
}
|
||||
if (!thisModule.isOpen(pn, callerModule)) {
|
||||
// package not open to caller
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** protection domain returned when the internal domain is null */
|
||||
private static java.security.ProtectionDomain allPermDomain;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the {@code ProtectionDomain} of this class. If there is a
|
||||
* security manager installed, this method first calls the security
|
||||
|
@ -31,7 +31,6 @@ import java.io.UncheckedIOException;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.AccessControlContext;
|
||||
@ -352,9 +351,7 @@ public abstract class ClassLoader {
|
||||
private ClassLoader(Void unused, String name, ClassLoader parent) {
|
||||
this.name = name;
|
||||
this.parent = parent;
|
||||
this.unnamedModule
|
||||
= SharedSecrets.getJavaLangReflectModuleAccess()
|
||||
.defineUnnamedModule(this);
|
||||
this.unnamedModule = new Module(this);
|
||||
if (ParallelLoaders.isRegistered(this.getClass())) {
|
||||
parallelLockMap = new ConcurrentHashMap<>();
|
||||
package2certs = new ConcurrentHashMap<>();
|
||||
@ -2348,6 +2345,7 @@ public abstract class ClassLoader {
|
||||
this.isBuiltin = isBuiltin;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() {
|
||||
synchronized (loadedLibraryNames) {
|
||||
if (fromClass.getClassLoader() != null && loaded) {
|
||||
|
@ -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
|
||||
@ -124,7 +124,7 @@ public interface Comparable<T> {
|
||||
* {@code sgn(}<i>expression</i>{@code )} designates the mathematical
|
||||
* <i>signum</i> function, which is defined to return one of {@code -1},
|
||||
* {@code 0}, or {@code 1} according to whether the value of
|
||||
* <i>expression</i> is negative, zero or positive.
|
||||
* <i>expression</i> is negative, zero, or positive, respectively.
|
||||
*
|
||||
* @param o the object to be compared.
|
||||
* @return a negative integer, zero, or a positive integer as this object
|
||||
|
@ -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
|
||||
@ -243,6 +243,7 @@ public abstract class Enum<E extends Enum<E>>
|
||||
/**
|
||||
* enum classes cannot have finalize methods.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected final void finalize() { }
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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
|
||||
@ -23,13 +23,12 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
package java.lang;
|
||||
|
||||
/**
|
||||
* Thrown when creating a Layer fails.
|
||||
*
|
||||
* @see Layer
|
||||
* Thrown when creating a {@linkplain ModuleLayer module layer} fails.
|
||||
*
|
||||
* @see ModuleLayer
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
*/
|
@ -23,7 +23,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
package java.lang;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -35,6 +35,7 @@ import java.lang.module.ModuleDescriptor.Exports;
|
||||
import java.lang.module.ModuleDescriptor.Opens;
|
||||
import java.lang.module.ModuleDescriptor.Version;
|
||||
import java.lang.module.ResolvedModule;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
@ -49,12 +50,12 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.loader.BuiltinClassLoader;
|
||||
import jdk.internal.loader.BootLoader;
|
||||
import jdk.internal.misc.JavaLangAccess;
|
||||
import jdk.internal.misc.JavaLangReflectModuleAccess;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.module.ServicesCatalog;
|
||||
import jdk.internal.module.Resources;
|
||||
@ -73,7 +74,7 @@ import sun.security.util.SecurityConstants;
|
||||
*
|
||||
* <p> Named modules have a {@link #getName() name} and are constructed by the
|
||||
* Java Virtual Machine when a graph of modules is defined to the Java virtual
|
||||
* machine to create a module {@link Layer Layer}. </p>
|
||||
* machine to create a {@linkplain ModuleLayer module layer}. </p>
|
||||
*
|
||||
* <p> An unnamed module does not have a name. There is an unnamed module for
|
||||
* each {@link ClassLoader ClassLoader}, obtained by invoking its {@link
|
||||
@ -92,13 +93,13 @@ import sun.security.util.SecurityConstants;
|
||||
*
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
* @see java.lang.Class#getModule
|
||||
* @see Class#getModule()
|
||||
*/
|
||||
|
||||
public final class Module implements AnnotatedElement {
|
||||
|
||||
// the layer that contains this module, can be null
|
||||
private final Layer layer;
|
||||
private final ModuleLayer layer;
|
||||
|
||||
// module name and loader, these fields are read by VM
|
||||
private final String name;
|
||||
@ -113,10 +114,10 @@ public final class Module implements AnnotatedElement {
|
||||
* VM but will not read any other modules, will not have any exports setup
|
||||
* and will not be registered in the service catalog.
|
||||
*/
|
||||
private Module(Layer layer,
|
||||
ClassLoader loader,
|
||||
ModuleDescriptor descriptor,
|
||||
URI uri)
|
||||
Module(ModuleLayer layer,
|
||||
ClassLoader loader,
|
||||
ModuleDescriptor descriptor,
|
||||
URI uri)
|
||||
{
|
||||
this.layer = layer;
|
||||
this.name = descriptor.name();
|
||||
@ -139,7 +140,7 @@ public final class Module implements AnnotatedElement {
|
||||
*
|
||||
* @see ClassLoader#getUnnamedModule
|
||||
*/
|
||||
private Module(ClassLoader loader) {
|
||||
Module(ClassLoader loader) {
|
||||
this.layer = null;
|
||||
this.name = null;
|
||||
this.loader = loader;
|
||||
@ -217,29 +218,28 @@ public final class Module implements AnnotatedElement {
|
||||
* Returns the layer that contains this module or {@code null} if this
|
||||
* module is not in a layer.
|
||||
*
|
||||
* A module {@code Layer} contains named modules and therefore this
|
||||
* method always returns {@code null} when invoked on an unnamed module.
|
||||
* A module layer contains named modules and therefore this method always
|
||||
* returns {@code null} when invoked on an unnamed module.
|
||||
*
|
||||
* <p> <a href="Proxy.html#dynamicmodule">Dynamic modules</a> are named
|
||||
* modules that are generated at runtime. A dynamic module may or may
|
||||
* not be in a module Layer. </p>
|
||||
* <p> <a href="reflect/Proxy.html#dynamicmodule">Dynamic modules</a> are
|
||||
* named modules that are generated at runtime. A dynamic module may or may
|
||||
* not be in a module layer. </p>
|
||||
*
|
||||
* @return The layer that contains this module
|
||||
* @return The module layer that contains this module
|
||||
*
|
||||
* @see Proxy
|
||||
* @see java.lang.reflect.Proxy
|
||||
*/
|
||||
public Layer getLayer() {
|
||||
public ModuleLayer getLayer() {
|
||||
if (isNamed()) {
|
||||
Layer layer = this.layer;
|
||||
ModuleLayer layer = this.layer;
|
||||
if (layer != null)
|
||||
return layer;
|
||||
|
||||
// special-case java.base as it is created before the boot Layer
|
||||
// special-case java.base as it is created before the boot layer
|
||||
if (loader == null && name.equals("java.base")) {
|
||||
return SharedSecrets.getJavaLangAccess().getBootLayer();
|
||||
return ModuleLayer.boot();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -338,7 +338,7 @@ public final class Module implements AnnotatedElement {
|
||||
public Module addReads(Module other) {
|
||||
Objects.requireNonNull(other);
|
||||
if (this.isNamed()) {
|
||||
Module caller = Reflection.getCallerClass().getModule();
|
||||
Module caller = getCallerModule(Reflection.getCallerClass());
|
||||
if (caller != this) {
|
||||
throw new IllegalCallerException(caller + " != " + this);
|
||||
}
|
||||
@ -350,12 +350,21 @@ public final class Module implements AnnotatedElement {
|
||||
/**
|
||||
* Updates this module to read another module.
|
||||
*
|
||||
* @apiNote This method is for Proxy use and white-box testing.
|
||||
* @apiNote Used by the --add-reads command line option.
|
||||
*/
|
||||
void implAddReads(Module other) {
|
||||
implAddReads(other, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this module to read all unnamed modules.
|
||||
*
|
||||
* @apiNote Used by the --add-reads command line option.
|
||||
*/
|
||||
void implAddReadsAllUnnamed() {
|
||||
implAddReads(Module.ALL_UNNAMED_MODULE, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this module to read another module without notifying the VM.
|
||||
*
|
||||
@ -371,6 +380,7 @@ public final class Module implements AnnotatedElement {
|
||||
* If {@code syncVM} is {@code true} then the VM is notified.
|
||||
*/
|
||||
private void implAddReads(Module other, boolean syncVM) {
|
||||
Objects.requireNonNull(other);
|
||||
if (!canRead(other)) {
|
||||
// update VM first, just in case it fails
|
||||
if (syncVM) {
|
||||
@ -659,7 +669,7 @@ public final class Module implements AnnotatedElement {
|
||||
Objects.requireNonNull(other);
|
||||
|
||||
if (isNamed()) {
|
||||
Module caller = Reflection.getCallerClass().getModule();
|
||||
Module caller = getCallerModule(Reflection.getCallerClass());
|
||||
if (caller != this) {
|
||||
throw new IllegalCallerException(caller + " != " + this);
|
||||
}
|
||||
@ -706,8 +716,8 @@ public final class Module implements AnnotatedElement {
|
||||
Objects.requireNonNull(other);
|
||||
|
||||
if (isNamed()) {
|
||||
Module caller = Reflection.getCallerClass().getModule();
|
||||
if (caller != this && !isOpen(pn, caller))
|
||||
Module caller = getCallerModule(Reflection.getCallerClass());
|
||||
if (caller != this && (caller == null || !isOpen(pn, caller)))
|
||||
throw new IllegalCallerException(pn + " is not open to " + caller);
|
||||
implAddExportsOrOpens(pn, other, /*open*/true, /*syncVM*/true);
|
||||
}
|
||||
@ -717,36 +727,80 @@ public final class Module implements AnnotatedElement {
|
||||
|
||||
|
||||
/**
|
||||
* Updates the exports so that package {@code pn} is exported to module
|
||||
* {@code other} but without notifying the VM.
|
||||
* Updates this module to export a package unconditionally.
|
||||
*
|
||||
* @apiNote This method is for VM white-box testing.
|
||||
* @apiNote This method is for JDK tests only.
|
||||
*/
|
||||
void implAddExportsNoSync(String pn, Module other) {
|
||||
if (other == null)
|
||||
other = EVERYONE_MODULE;
|
||||
implAddExportsOrOpens(pn.replace('/', '.'), other, false, false);
|
||||
void implAddExports(String pn) {
|
||||
implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the exports so that package {@code pn} is exported to module
|
||||
* {@code other}.
|
||||
* Updates this module to export a package to another module.
|
||||
*
|
||||
* @apiNote This method is for white-box testing.
|
||||
* @apiNote Used by Instrumentation::redefineModule and --add-exports
|
||||
*/
|
||||
void implAddExports(String pn, Module other) {
|
||||
implAddExportsOrOpens(pn, other, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the module to open package {@code pn} to module {@code other}.
|
||||
* Updates this module to export a package to all unnamed modules.
|
||||
*
|
||||
* @apiNote This method is for white-box tests and jtreg
|
||||
* @apiNote Used by the --add-exports command line option.
|
||||
*/
|
||||
void implAddExportsToAllUnnamed(String pn) {
|
||||
implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this export to export a package unconditionally without
|
||||
* notifying the VM.
|
||||
*
|
||||
* @apiNote This method is for VM white-box testing.
|
||||
*/
|
||||
void implAddExportsNoSync(String pn) {
|
||||
implAddExportsOrOpens(pn.replace('/', '.'), Module.EVERYONE_MODULE, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a module to export a package to another module without
|
||||
* notifying the VM.
|
||||
*
|
||||
* @apiNote This method is for VM white-box testing.
|
||||
*/
|
||||
void implAddExportsNoSync(String pn, Module other) {
|
||||
implAddExportsOrOpens(pn.replace('/', '.'), other, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this module to open a package unconditionally.
|
||||
*
|
||||
* @apiNote This method is for JDK tests only.
|
||||
*/
|
||||
void implAddOpens(String pn) {
|
||||
implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this module to open a package to another module.
|
||||
*
|
||||
* @apiNote Used by Instrumentation::redefineModule and --add-opens
|
||||
*/
|
||||
void implAddOpens(String pn, Module other) {
|
||||
implAddExportsOrOpens(pn, other, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this module to export a package to all unnamed modules.
|
||||
*
|
||||
* @apiNote Used by the --add-opens command line option.
|
||||
*/
|
||||
void implAddOpensToAllUnnamed(String pn) {
|
||||
implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates a module to export or open a module to another module.
|
||||
*
|
||||
@ -831,7 +885,7 @@ public final class Module implements AnnotatedElement {
|
||||
Objects.requireNonNull(service);
|
||||
|
||||
if (isNamed() && !descriptor.isAutomatic()) {
|
||||
Module caller = Reflection.getCallerClass().getModule();
|
||||
Module caller = getCallerModule(Reflection.getCallerClass());
|
||||
if (caller != this) {
|
||||
throw new IllegalCallerException(caller + " != " + this);
|
||||
}
|
||||
@ -899,33 +953,28 @@ public final class Module implements AnnotatedElement {
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of the package names of the packages in this module.
|
||||
* Returns the set of package names for the packages in this module.
|
||||
*
|
||||
* <p> For named modules, the returned array contains an element for each
|
||||
* <p> For named modules, the returned set contains an element for each
|
||||
* package in the module. </p>
|
||||
*
|
||||
* <p> For unnamed modules, this method is the equivalent to invoking the
|
||||
* {@link ClassLoader#getDefinedPackages() getDefinedPackages} method of
|
||||
* this module's class loader and returning the array of package names. </p>
|
||||
* this module's class loader and returning the set of package names. </p>
|
||||
*
|
||||
* <p> A package name appears at most once in the returned array. </p>
|
||||
*
|
||||
* @apiNote This method returns an array rather than a {@code Set} for
|
||||
* consistency with other {@code java.lang.reflect} types.
|
||||
*
|
||||
* @return an array of the package names of the packages in this module
|
||||
* @return the set of the package names of the packages in this module
|
||||
*/
|
||||
public String[] getPackages() {
|
||||
public Set<String> getPackages() {
|
||||
if (isNamed()) {
|
||||
|
||||
Set<String> packages = descriptor.packages();
|
||||
Map<String, Boolean> extraPackages = this.extraPackages;
|
||||
if (extraPackages == null) {
|
||||
return packages.toArray(new String[0]);
|
||||
return packages;
|
||||
} else {
|
||||
return Stream.concat(packages.stream(),
|
||||
extraPackages.keySet().stream())
|
||||
.toArray(String[]::new);
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -936,7 +985,7 @@ public final class Module implements AnnotatedElement {
|
||||
} else {
|
||||
packages = SharedSecrets.getJavaLangAccess().packages(loader);
|
||||
}
|
||||
return packages.map(Package::getName).toArray(String[]::new);
|
||||
return packages.map(Package::getName).collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1013,12 +1062,12 @@ public final class Module implements AnnotatedElement {
|
||||
*/
|
||||
static Map<String, Module> defineModules(Configuration cf,
|
||||
Function<String, ClassLoader> clf,
|
||||
Layer layer)
|
||||
ModuleLayer layer)
|
||||
{
|
||||
Map<String, Module> nameToModule = new HashMap<>();
|
||||
Map<String, ClassLoader> moduleToLoader = new HashMap<>();
|
||||
|
||||
boolean isBootLayer = (Layer.boot() == null);
|
||||
boolean isBootLayer = (ModuleLayer.boot() == null);
|
||||
Set<ClassLoader> loaders = new HashSet<>();
|
||||
|
||||
// map each module to a class loader
|
||||
@ -1074,7 +1123,7 @@ public final class Module implements AnnotatedElement {
|
||||
assert m2 != null;
|
||||
} else {
|
||||
// parent layer
|
||||
for (Layer parent: layer.parents()) {
|
||||
for (ModuleLayer parent: layer.parents()) {
|
||||
m2 = findModule(parent, other);
|
||||
if (m2 != null)
|
||||
break;
|
||||
@ -1133,7 +1182,8 @@ public final class Module implements AnnotatedElement {
|
||||
* Find the runtime Module corresponding to the given ResolvedModule
|
||||
* in the given parent layer (or its parents).
|
||||
*/
|
||||
private static Module findModule(Layer parent, ResolvedModule resolvedModule) {
|
||||
private static Module findModule(ModuleLayer parent,
|
||||
ResolvedModule resolvedModule) {
|
||||
Configuration cf = resolvedModule.configuration();
|
||||
String dn = resolvedModule.name();
|
||||
return parent.layers()
|
||||
@ -1156,7 +1206,7 @@ public final class Module implements AnnotatedElement {
|
||||
private static void initExportsAndOpens(Module m,
|
||||
Map<String, Module> nameToSource,
|
||||
Map<String, Module> nameToModule,
|
||||
List<Layer> parents) {
|
||||
List<ModuleLayer> parents) {
|
||||
// The VM doesn't special case open or automatic modules so need to
|
||||
// export all packages
|
||||
ModuleDescriptor descriptor = m.getDescriptor();
|
||||
@ -1246,12 +1296,12 @@ public final class Module implements AnnotatedElement {
|
||||
private static Module findModule(String target,
|
||||
Map<String, Module> nameToSource,
|
||||
Map<String, Module> nameToModule,
|
||||
List<Layer> parents) {
|
||||
List<ModuleLayer> parents) {
|
||||
Module m = nameToSource.get(target);
|
||||
if (m == null) {
|
||||
m = nameToModule.get(target);
|
||||
if (m == null) {
|
||||
for (Layer parent : parents) {
|
||||
for (ModuleLayer parent : parents) {
|
||||
m = parent.findModule(target).orElse(null);
|
||||
if (m != null) break;
|
||||
}
|
||||
@ -1445,14 +1495,18 @@ public final class Module implements AnnotatedElement {
|
||||
}
|
||||
|
||||
if (isNamed() && Resources.canEncapsulate(name)) {
|
||||
Module caller = Reflection.getCallerClass().getModule();
|
||||
Module caller = getCallerModule(Reflection.getCallerClass());
|
||||
if (caller != this && caller != Object.class.getModule()) {
|
||||
// ignore packages added for proxies via addPackage
|
||||
Set<String> packages = getDescriptor().packages();
|
||||
String pn = Resources.toPackageName(name);
|
||||
if (packages.contains(pn) && !isOpen(pn, caller)) {
|
||||
// resource is in package not open to caller
|
||||
return null;
|
||||
if (getPackages().contains(pn)) {
|
||||
if (caller == null && !isOpen(pn)) {
|
||||
// no caller, package not open
|
||||
return null;
|
||||
}
|
||||
if (!isOpen(pn, caller)) {
|
||||
// package not open to caller
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1497,6 +1551,14 @@ public final class Module implements AnnotatedElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the module that a given caller class is a member of. Returns
|
||||
* {@code null} if the caller is {@code null}.
|
||||
*/
|
||||
private Module getCallerModule(Class<?> caller) {
|
||||
return (caller != null) ? caller.getModule() : null;
|
||||
}
|
||||
|
||||
|
||||
// -- native methods --
|
||||
|
||||
@ -1521,71 +1583,4 @@ public final class Module implements AnnotatedElement {
|
||||
|
||||
// JVM_AddModulePackage
|
||||
private static native void addPackage0(Module m, String pn);
|
||||
|
||||
/**
|
||||
* Register shared secret to provide access to package-private methods
|
||||
*/
|
||||
static {
|
||||
SharedSecrets.setJavaLangReflectModuleAccess(
|
||||
new JavaLangReflectModuleAccess() {
|
||||
@Override
|
||||
public Module defineUnnamedModule(ClassLoader loader) {
|
||||
return new Module(loader);
|
||||
}
|
||||
@Override
|
||||
public Module defineModule(ClassLoader loader,
|
||||
ModuleDescriptor descriptor,
|
||||
URI uri) {
|
||||
return new Module(null, loader, descriptor, uri);
|
||||
}
|
||||
@Override
|
||||
public void addReads(Module m1, Module m2) {
|
||||
m1.implAddReads(m2, true);
|
||||
}
|
||||
@Override
|
||||
public void addReadsAllUnnamed(Module m) {
|
||||
m.implAddReads(Module.ALL_UNNAMED_MODULE);
|
||||
}
|
||||
@Override
|
||||
public void addExports(Module m, String pn) {
|
||||
m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, false, true);
|
||||
}
|
||||
@Override
|
||||
public void addExports(Module m, String pn, Module other) {
|
||||
m.implAddExportsOrOpens(pn, other, false, true);
|
||||
}
|
||||
@Override
|
||||
public void addExportsToAllUnnamed(Module m, String pn) {
|
||||
m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, false, true);
|
||||
}
|
||||
@Override
|
||||
public void addOpens(Module m, String pn) {
|
||||
m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, true, true);
|
||||
}
|
||||
@Override
|
||||
public void addOpens(Module m, String pn, Module other) {
|
||||
m.implAddExportsOrOpens(pn, other, true, true);
|
||||
}
|
||||
@Override
|
||||
public void addOpensToAllUnnamed(Module m, String pn) {
|
||||
m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true);
|
||||
}
|
||||
@Override
|
||||
public void addUses(Module m, Class<?> service) {
|
||||
m.implAddUses(service);
|
||||
}
|
||||
@Override
|
||||
public ServicesCatalog getServicesCatalog(Layer layer) {
|
||||
return layer.getServicesCatalog();
|
||||
}
|
||||
@Override
|
||||
public Stream<Layer> layers(Layer layer) {
|
||||
return layer.layers();
|
||||
}
|
||||
@Override
|
||||
public Stream<Layer> layers(ClassLoader loader) {
|
||||
return Layer.layers(loader);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.reflect;
|
||||
package java.lang;
|
||||
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
@ -47,8 +47,6 @@ import java.util.stream.Stream;
|
||||
import jdk.internal.loader.ClassLoaderValue;
|
||||
import jdk.internal.loader.Loader;
|
||||
import jdk.internal.loader.LoaderPool;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.module.Modules;
|
||||
import jdk.internal.module.ServicesCatalog;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
@ -70,15 +68,16 @@ import sun.security.util.SecurityConstants;
|
||||
*
|
||||
* <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and
|
||||
* {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods
|
||||
* provide convenient ways to create a {@code Layer} where all modules are
|
||||
* provide convenient ways to create a module layer where all modules are
|
||||
* mapped to a single class loader or where each module is mapped to its own
|
||||
* class loader. The {@link #defineModules defineModules} method is for more
|
||||
* advanced cases where modules are mapped to custom class loaders by means of
|
||||
* a function specified to the method. Each of these methods has an instance
|
||||
* and static variant. The instance methods create a layer with the receiver
|
||||
* as the parent layer. The static methods are for more advanced cases where
|
||||
* there can be more than one parent layer or where a {@link Layer.Controller
|
||||
* Controller} is needed to control modules in the layer. </p>
|
||||
* there can be more than one parent layer or where a {@link
|
||||
* ModuleLayer.Controller Controller} is needed to control modules in the layer
|
||||
* </p>
|
||||
*
|
||||
* <p> A Java virtual machine has at least one non-empty layer, the {@link
|
||||
* #boot() boot} layer, that is created when the Java virtual machine is
|
||||
@ -131,13 +130,13 @@ import sun.security.util.SecurityConstants;
|
||||
* <pre>{@code
|
||||
* ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
|
||||
*
|
||||
* Layer parent = Layer.boot();
|
||||
* ModuleLayer parent = ModuleLayer.boot();
|
||||
*
|
||||
* Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));
|
||||
*
|
||||
* ClassLoader scl = ClassLoader.getSystemClassLoader();
|
||||
*
|
||||
* Layer layer = parent.defineModulesWithOneLoader(cf, scl);
|
||||
* ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);
|
||||
*
|
||||
* Class<?> c = layer.findLoader("myapp").loadClass("app.Main");
|
||||
* }</pre>
|
||||
@ -147,27 +146,27 @@ import sun.security.util.SecurityConstants;
|
||||
* @see Module#getLayer()
|
||||
*/
|
||||
|
||||
public final class Layer {
|
||||
public final class ModuleLayer {
|
||||
|
||||
// the empty Layer
|
||||
private static final Layer EMPTY_LAYER
|
||||
= new Layer(Configuration.empty(), List.of(), null);
|
||||
// the empty layer
|
||||
private static final ModuleLayer EMPTY_LAYER
|
||||
= new ModuleLayer(Configuration.empty(), List.of(), null);
|
||||
|
||||
// the configuration from which this Layer was created
|
||||
// the configuration from which this ;ayer was created
|
||||
private final Configuration cf;
|
||||
|
||||
// parent layers, empty in the case of the empty layer
|
||||
private final List<Layer> parents;
|
||||
private final List<ModuleLayer> parents;
|
||||
|
||||
// maps module name to jlr.Module
|
||||
private final Map<String, Module> nameToModule;
|
||||
|
||||
/**
|
||||
* Creates a new Layer from the modules in the given configuration.
|
||||
* Creates a new module layer from the modules in the given configuration.
|
||||
*/
|
||||
private Layer(Configuration cf,
|
||||
List<Layer> parents,
|
||||
Function<String, ClassLoader> clf)
|
||||
private ModuleLayer(Configuration cf,
|
||||
List<ModuleLayer> parents,
|
||||
Function<String, ClassLoader> clf)
|
||||
{
|
||||
this.cf = cf;
|
||||
this.parents = parents; // no need to do defensive copy
|
||||
@ -182,9 +181,9 @@ public final class Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls a layer. The static methods defined by {@link Layer} to create
|
||||
* module layers return a {@code Controller} that can be used to control
|
||||
* modules in the layer.
|
||||
* Controls a module layer. The static methods defined by {@link ModuleLayer}
|
||||
* to create module layers return a {@code Controller} that can be used to
|
||||
* control modules in the layer.
|
||||
*
|
||||
* <p> Unless otherwise specified, passing a {@code null} argument to a
|
||||
* method in this class causes a {@link NullPointerException
|
||||
@ -197,18 +196,18 @@ public final class Layer {
|
||||
* @spec JPMS
|
||||
*/
|
||||
public static final class Controller {
|
||||
private final Layer layer;
|
||||
private final ModuleLayer layer;
|
||||
|
||||
Controller(Layer layer) {
|
||||
Controller(ModuleLayer layer) {
|
||||
this.layer = layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the layer that this object controls.
|
||||
*
|
||||
* @return the layer
|
||||
* @return the module layer
|
||||
*/
|
||||
public Layer layer() {
|
||||
public ModuleLayer layer() {
|
||||
return layer;
|
||||
}
|
||||
|
||||
@ -235,14 +234,13 @@ public final class Layer {
|
||||
* @return This controller
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If {@code source} is not in the layer
|
||||
* If {@code source} is not in the module layer
|
||||
*
|
||||
* @see Module#addReads
|
||||
*/
|
||||
public Controller addReads(Module source, Module target) {
|
||||
ensureInLayer(source);
|
||||
Objects.requireNonNull(target);
|
||||
Modules.addReads(source, target);
|
||||
source.implAddReads(target);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -261,23 +259,21 @@ public final class Layer {
|
||||
* @return This controller
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If {@code source} is not in the layer or the package is not
|
||||
* in the source module
|
||||
* If {@code source} is not in the module layer or the package
|
||||
* is not in the source module
|
||||
*
|
||||
* @see Module#addOpens
|
||||
*/
|
||||
public Controller addOpens(Module source, String pn, Module target) {
|
||||
ensureInLayer(source);
|
||||
Objects.requireNonNull(pn);
|
||||
Objects.requireNonNull(target);
|
||||
Modules.addOpens(source, pn, target);
|
||||
source.implAddOpens(pn, target);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new layer, with this layer as its parent, by defining the
|
||||
* Creates a new module layer, with this layer as its parent, by defining the
|
||||
* modules in the given {@code Configuration} to the Java virtual machine.
|
||||
* This method creates one class loader and defines all modules to that
|
||||
* class loader. The {@link ClassLoader#getParent() parent} of each class
|
||||
@ -288,7 +284,7 @@ public final class Layer {
|
||||
* parent. In other words, if this layer is {@code thisLayer} then this
|
||||
* method is equivalent to invoking:
|
||||
* <pre> {@code
|
||||
* Layer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
|
||||
* ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
|
||||
* }</pre>
|
||||
*
|
||||
* @param cf
|
||||
@ -312,14 +308,14 @@ public final class Layer {
|
||||
*
|
||||
* @see #findLoader
|
||||
*/
|
||||
public Layer defineModulesWithOneLoader(Configuration cf,
|
||||
ClassLoader parentLoader) {
|
||||
public ModuleLayer defineModulesWithOneLoader(Configuration cf,
|
||||
ClassLoader parentLoader) {
|
||||
return defineModulesWithOneLoader(cf, List.of(this), parentLoader).layer();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new layer, with this layer as its parent, by defining the
|
||||
* Creates a new module layer, with this layer as its parent, by defining the
|
||||
* modules in the given {@code Configuration} to the Java virtual machine.
|
||||
* Each module is defined to its own {@link ClassLoader} created by this
|
||||
* method. The {@link ClassLoader#getParent() parent} of each class loader
|
||||
@ -330,7 +326,7 @@ public final class Layer {
|
||||
* parent. In other words, if this layer is {@code thisLayer} then this
|
||||
* method is equivalent to invoking:
|
||||
* <pre> {@code
|
||||
* Layer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
|
||||
* ModuleLayer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
|
||||
* }</pre>
|
||||
*
|
||||
* @param cf
|
||||
@ -354,14 +350,14 @@ public final class Layer {
|
||||
*
|
||||
* @see #findLoader
|
||||
*/
|
||||
public Layer defineModulesWithManyLoaders(Configuration cf,
|
||||
ClassLoader parentLoader) {
|
||||
public ModuleLayer defineModulesWithManyLoaders(Configuration cf,
|
||||
ClassLoader parentLoader) {
|
||||
return defineModulesWithManyLoaders(cf, List.of(this), parentLoader).layer();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new layer, with this layer as its parent, by defining the
|
||||
* Creates a new module layer, with this layer as its parent, by defining the
|
||||
* modules in the given {@code Configuration} to the Java virtual machine.
|
||||
* Each module is mapped, by name, to its class loader by means of the
|
||||
* given function. This method works exactly as specified by the static
|
||||
@ -370,7 +366,7 @@ public final class Layer {
|
||||
* this layer is {@code thisLayer} then this method is equivalent to
|
||||
* invoking:
|
||||
* <pre> {@code
|
||||
* Layer.defineModules(cf, List.of(thisLayer), clf).layer();
|
||||
* ModuleLayer.defineModules(cf, List.of(thisLayer), clf).layer();
|
||||
* }</pre>
|
||||
*
|
||||
* @param cf
|
||||
@ -390,13 +386,13 @@ public final class Layer {
|
||||
* If {@code RuntimePermission("getClassLoader")} is denied by
|
||||
* the security manager
|
||||
*/
|
||||
public Layer defineModules(Configuration cf,
|
||||
Function<String, ClassLoader> clf) {
|
||||
public ModuleLayer defineModules(Configuration cf,
|
||||
Function<String, ClassLoader> clf) {
|
||||
return defineModules(cf, List.of(this), clf).layer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new layer by defining the modules in the given {@code
|
||||
* Creates a new module layer by defining the modules in the given {@code
|
||||
* Configuration} to the Java virtual machine. This method creates one
|
||||
* class loader and defines all modules to that class loader.
|
||||
*
|
||||
@ -458,10 +454,10 @@ public final class Layer {
|
||||
* @see #findLoader
|
||||
*/
|
||||
public static Controller defineModulesWithOneLoader(Configuration cf,
|
||||
List<Layer> parentLayers,
|
||||
List<ModuleLayer> parentLayers,
|
||||
ClassLoader parentLoader)
|
||||
{
|
||||
List<Layer> parents = new ArrayList<>(parentLayers);
|
||||
List<ModuleLayer> parents = new ArrayList<>(parentLayers);
|
||||
checkConfiguration(cf, parents);
|
||||
|
||||
checkCreateClassLoaderPermission();
|
||||
@ -470,7 +466,7 @@ public final class Layer {
|
||||
try {
|
||||
Loader loader = new Loader(cf.modules(), parentLoader);
|
||||
loader.initRemotePackageMap(cf, parents);
|
||||
Layer layer = new Layer(cf, parents, mn -> loader);
|
||||
ModuleLayer layer = new ModuleLayer(cf, parents, mn -> loader);
|
||||
return new Controller(layer);
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
throw new LayerInstantiationException(e.getMessage());
|
||||
@ -478,7 +474,7 @@ public final class Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new layer by defining the modules in the given {@code
|
||||
* Creates a new module layer by defining the modules in the given {@code
|
||||
* Configuration} to the Java virtual machine. Each module is defined to
|
||||
* its own {@link ClassLoader} created by this method. The {@link
|
||||
* ClassLoader#getParent() parent} of each class loader is the given parent
|
||||
@ -528,10 +524,10 @@ public final class Layer {
|
||||
* @see #findLoader
|
||||
*/
|
||||
public static Controller defineModulesWithManyLoaders(Configuration cf,
|
||||
List<Layer> parentLayers,
|
||||
List<ModuleLayer> parentLayers,
|
||||
ClassLoader parentLoader)
|
||||
{
|
||||
List<Layer> parents = new ArrayList<>(parentLayers);
|
||||
List<ModuleLayer> parents = new ArrayList<>(parentLayers);
|
||||
checkConfiguration(cf, parents);
|
||||
|
||||
checkCreateClassLoaderPermission();
|
||||
@ -539,7 +535,7 @@ public final class Layer {
|
||||
|
||||
LoaderPool pool = new LoaderPool(cf, parents, parentLoader);
|
||||
try {
|
||||
Layer layer = new Layer(cf, parents, pool::loaderFor);
|
||||
ModuleLayer layer = new ModuleLayer(cf, parents, pool::loaderFor);
|
||||
return new Controller(layer);
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
throw new LayerInstantiationException(e.getMessage());
|
||||
@ -547,7 +543,7 @@ public final class Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new layer by defining the modules in the given {@code
|
||||
* Creates a new module layer by defining the modules in the given {@code
|
||||
* Configuration} to the Java virtual machine. The given function maps each
|
||||
* module in the configuration, by name, to a class loader. Creating the
|
||||
* layer informs the Java virtual machine about the classes that may be
|
||||
@ -562,7 +558,7 @@ public final class Layer {
|
||||
* ready to load from these modules before there are any attempts to load
|
||||
* classes or resources. </p>
|
||||
*
|
||||
* <p> Creating a {@code Layer} can fail for the following reasons: </p>
|
||||
* <p> Creating a layer can fail for the following reasons: </p>
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
@ -589,7 +585,7 @@ public final class Layer {
|
||||
* or runtime exception then it is propagated to the caller of this method.
|
||||
* </p>
|
||||
*
|
||||
* @apiNote It is implementation specific as to whether creating a Layer
|
||||
* @apiNote It is implementation specific as to whether creating a layer
|
||||
* with this method is an atomic operation or not. Consequentially it is
|
||||
* possible for this method to fail with some modules, but not all, defined
|
||||
* to the Java virtual machine.
|
||||
@ -613,10 +609,10 @@ public final class Layer {
|
||||
* the security manager
|
||||
*/
|
||||
public static Controller defineModules(Configuration cf,
|
||||
List<Layer> parentLayers,
|
||||
List<ModuleLayer> parentLayers,
|
||||
Function<String, ClassLoader> clf)
|
||||
{
|
||||
List<Layer> parents = new ArrayList<>(parentLayers);
|
||||
List<ModuleLayer> parents = new ArrayList<>(parentLayers);
|
||||
checkConfiguration(cf, parents);
|
||||
Objects.requireNonNull(clf);
|
||||
|
||||
@ -628,7 +624,7 @@ public final class Layer {
|
||||
}
|
||||
|
||||
try {
|
||||
Layer layer = new Layer(cf, parents, clf);
|
||||
ModuleLayer layer = new ModuleLayer(cf, parents, clf);
|
||||
return new Controller(layer);
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
throw new LayerInstantiationException(e.getMessage());
|
||||
@ -641,7 +637,7 @@ public final class Layer {
|
||||
* the parent layers.
|
||||
*/
|
||||
private static void checkConfiguration(Configuration cf,
|
||||
List<Layer> parentLayers)
|
||||
List<ModuleLayer> parentLayers)
|
||||
{
|
||||
Objects.requireNonNull(cf);
|
||||
|
||||
@ -650,7 +646,7 @@ public final class Layer {
|
||||
throw new IllegalArgumentException("wrong number of parents");
|
||||
|
||||
int index = 0;
|
||||
for (Layer parent : parentLayers) {
|
||||
for (ModuleLayer parent : parentLayers) {
|
||||
if (parent.configuration() != parentConfigurations.get(index)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Parent of configuration != configuration of this Layer");
|
||||
@ -727,7 +723,7 @@ public final class Layer {
|
||||
*
|
||||
* @return The list of this layer's parents
|
||||
*/
|
||||
public List<Layer> parents() {
|
||||
public List<ModuleLayer> parents() {
|
||||
return parents;
|
||||
}
|
||||
|
||||
@ -739,24 +735,24 @@ public final class Layer {
|
||||
* @implNote For now, the assumption is that the number of elements will
|
||||
* be very low and so this method does not use a specialized spliterator.
|
||||
*/
|
||||
Stream<Layer> layers() {
|
||||
List<Layer> allLayers = this.allLayers;
|
||||
Stream<ModuleLayer> layers() {
|
||||
List<ModuleLayer> allLayers = this.allLayers;
|
||||
if (allLayers != null)
|
||||
return allLayers.stream();
|
||||
|
||||
allLayers = new ArrayList<>();
|
||||
Set<Layer> visited = new HashSet<>();
|
||||
Deque<Layer> stack = new ArrayDeque<>();
|
||||
Set<ModuleLayer> visited = new HashSet<>();
|
||||
Deque<ModuleLayer> stack = new ArrayDeque<>();
|
||||
visited.add(this);
|
||||
stack.push(this);
|
||||
|
||||
while (!stack.isEmpty()) {
|
||||
Layer layer = stack.pop();
|
||||
ModuleLayer layer = stack.pop();
|
||||
allLayers.add(layer);
|
||||
|
||||
// push in reverse order
|
||||
for (int i = layer.parents.size() - 1; i >= 0; i--) {
|
||||
Layer parent = layer.parents.get(i);
|
||||
ModuleLayer parent = layer.parents.get(i);
|
||||
if (!visited.contains(parent)) {
|
||||
visited.add(parent);
|
||||
stack.push(parent);
|
||||
@ -768,7 +764,7 @@ public final class Layer {
|
||||
return allLayers.stream();
|
||||
}
|
||||
|
||||
private volatile List<Layer> allLayers;
|
||||
private volatile List<ModuleLayer> allLayers;
|
||||
|
||||
/**
|
||||
* Returns the set of the modules in this layer.
|
||||
@ -856,9 +852,9 @@ public final class Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing this layer.
|
||||
* Returns a string describing this module layer.
|
||||
*
|
||||
* @return A possibly empty string describing this layer
|
||||
* @return A possibly empty string describing this module layer
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
@ -873,7 +869,7 @@ public final class Layer {
|
||||
*
|
||||
* @return The empty layer
|
||||
*/
|
||||
public static Layer empty() {
|
||||
public static ModuleLayer empty() {
|
||||
return EMPTY_LAYER;
|
||||
}
|
||||
|
||||
@ -887,11 +883,10 @@ public final class Layer {
|
||||
*
|
||||
* @return The boot layer
|
||||
*/
|
||||
public static Layer boot() {
|
||||
return SharedSecrets.getJavaLangAccess().getBootLayer();
|
||||
public static ModuleLayer boot() {
|
||||
return System.bootLayer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the ServicesCatalog for this Layer, creating it if not
|
||||
* already created.
|
||||
@ -922,10 +917,10 @@ public final class Layer {
|
||||
*/
|
||||
void bindToLoader(ClassLoader loader) {
|
||||
// CLV.computeIfAbsent(loader, (cl, clv) -> new CopyOnWriteArrayList<>())
|
||||
List<Layer> list = CLV.get(loader);
|
||||
List<ModuleLayer> list = CLV.get(loader);
|
||||
if (list == null) {
|
||||
list = new CopyOnWriteArrayList<>();
|
||||
List<Layer> previous = CLV.putIfAbsent(loader, list);
|
||||
List<ModuleLayer> previous = CLV.putIfAbsent(loader, list);
|
||||
if (previous != null) list = previous;
|
||||
}
|
||||
list.add(this);
|
||||
@ -935,8 +930,8 @@ public final class Layer {
|
||||
* Returns a stream of the layers that have at least one module defined to
|
||||
* the given class loader.
|
||||
*/
|
||||
static Stream<Layer> layers(ClassLoader loader) {
|
||||
List<Layer> list = CLV.get(loader);
|
||||
static Stream<ModuleLayer> layers(ClassLoader loader) {
|
||||
List<ModuleLayer> list = CLV.get(loader);
|
||||
if (list != null) {
|
||||
return list.stream();
|
||||
} else {
|
||||
@ -945,5 +940,5 @@ public final class Layer {
|
||||
}
|
||||
|
||||
// the list of layers with modules defined to a class loader
|
||||
private static final ClassLoaderValue<List<Layer>> CLV = new ClassLoaderValue<>();
|
||||
private static final ClassLoaderValue<List<ModuleLayer>> CLV = new ClassLoaderValue<>();
|
||||
}
|
@ -26,7 +26,6 @@ package java.lang;
|
||||
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 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
|
||||
@ -561,10 +561,53 @@ public class Object {
|
||||
* the finalization of this object to be halted, but is otherwise
|
||||
* ignored.
|
||||
*
|
||||
* @apiNote
|
||||
* Classes that embed non-heap resources have many options
|
||||
* for cleanup of those resources. The class must ensure that the
|
||||
* lifetime of each instance is longer than that of any resource it embeds.
|
||||
* {@link java.lang.ref.Reference#reachabilityFence} can be used to ensure that
|
||||
* objects remain reachable while resources embedded in the object are in use.
|
||||
* <p>
|
||||
* A subclass should avoid overriding the {@code finalize} method
|
||||
* unless the subclass embeds non-heap resources that must be cleaned up
|
||||
* before the instance is collected.
|
||||
* Finalizer invocations are not automatically chained, unlike constructors.
|
||||
* If a subclass overrides {@code finalize} it must invoke the superclass
|
||||
* finalizer explicitly.
|
||||
* To guard against exceptions prematurely terminating the finalize chain,
|
||||
* the subclass should use a {@code try-finally} block to ensure
|
||||
* {@code super.finalize()} is always invoked. For example,
|
||||
* <pre>{@code @Override
|
||||
* protected void finalize() throws Throwable {
|
||||
* try {
|
||||
* ... // cleanup subclass state
|
||||
* } finally {
|
||||
* super.finalize();
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @deprecated The finalization mechanism is inherently problematic.
|
||||
* Finalization can lead to performance issues, deadlocks, and hangs.
|
||||
* Errors in finalizers can lead to resource leaks; there is no way to cancel
|
||||
* finalization if it is no longer necessary; and no ordering is specified
|
||||
* among calls to {@code finalize} methods of different objects.
|
||||
* Furthermore, there are no guarantees regarding the timing of finalization.
|
||||
* The {@code finalize} method might be called on a finalizable object
|
||||
* only after an indefinite delay, if at all.
|
||||
*
|
||||
* Classes whose instances hold non-heap resources should provide a method
|
||||
* to enable explicit release of those resources, and they should also
|
||||
* implement {@link AutoCloseable} if appropriate.
|
||||
* The {@link java.lang.ref.Cleaner} and {@link java.lang.ref.PhantomReference}
|
||||
* provide more flexible and efficient ways to release resources when an object
|
||||
* becomes unreachable.
|
||||
*
|
||||
* @throws Throwable the {@code Exception} raised by this method
|
||||
* @see java.lang.ref.WeakReference
|
||||
* @see java.lang.ref.PhantomReference
|
||||
* @jls 12.6 Finalization of Class Instances
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
protected void finalize() throws Throwable { }
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ package java.lang;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
@ -29,9 +29,7 @@ import java.lang.RuntimePermission;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleDescriptor.Exports;
|
||||
import java.lang.module.ModuleDescriptor.Opens;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Module;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.File;
|
||||
import java.io.FilePermission;
|
||||
@ -1441,7 +1439,7 @@ class SecurityManager {
|
||||
|
||||
static {
|
||||
// Get the modules in the boot layer
|
||||
Stream<Module> bootLayerModules = Layer.boot().modules().stream();
|
||||
Stream<Module> bootLayerModules = ModuleLayer.boot().modules().stream();
|
||||
|
||||
// Filter out the modules loaded by the boot or platform loader
|
||||
PrivilegedAction<Set<Module>> pa = () ->
|
||||
|
@ -33,8 +33,6 @@ import jdk.internal.module.ModuleReferenceImpl;
|
||||
import java.lang.module.ModuleDescriptor.Version;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.lang.module.ResolvedModule;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.Module;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@ -191,7 +189,7 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
* if the module name is not available.
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
* @see java.lang.reflect.Module#getName()
|
||||
* @see Module#getName()
|
||||
*/
|
||||
public String getModuleName() {
|
||||
return moduleName;
|
||||
@ -480,7 +478,7 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
if (!VM.isModuleSystemInited())
|
||||
return true;
|
||||
|
||||
return Layer.boot() == m.getLayer() && HashedModules.contains(m);
|
||||
return ModuleLayer.boot() == m.getLayer() && HashedModules.contains(m);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -492,7 +490,7 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
|
||||
static Set<String> hashedModules() {
|
||||
|
||||
Optional<ResolvedModule> resolvedModule = Layer.boot()
|
||||
Optional<ResolvedModule> resolvedModule = ModuleLayer.boot()
|
||||
.configuration()
|
||||
.findModule("java.base");
|
||||
assert resolvedModule.isPresent();
|
||||
|
@ -2672,7 +2672,6 @@ public final class String
|
||||
* point</a> is passed through uninterpreted.
|
||||
*
|
||||
* @return an IntStream of char values from this sequence
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public IntStream chars() {
|
||||
@ -2692,7 +2691,6 @@ public final class String
|
||||
* {@code int} values which are then passed to the stream.
|
||||
*
|
||||
* @return an IntStream of Unicode code points from this sequence
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public IntStream codePoints() {
|
||||
|
@ -35,33 +35,32 @@ import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Properties;
|
||||
import java.util.PropertyPermission;
|
||||
import java.util.Map;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.nio.channels.Channel;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.PropertyPermission;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.function.Supplier;
|
||||
import sun.nio.ch.Interruptible;
|
||||
import jdk.internal.module.ModuleBootstrap;
|
||||
import jdk.internal.module.ServicesCatalog;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import sun.security.util.SecurityConstants;
|
||||
import sun.reflect.annotation.AnnotationType;
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.misc.JavaLangAccess;;
|
||||
import jdk.internal.misc.SharedSecrets;;
|
||||
@ -69,8 +68,9 @@ import jdk.internal.misc.VM;
|
||||
import jdk.internal.logger.LoggerFinderLoader;
|
||||
import jdk.internal.logger.LazyLoggers;
|
||||
import jdk.internal.logger.LocalizedLoggerWrapper;
|
||||
|
||||
import jdk.internal.module.ModuleBootstrap;
|
||||
import sun.reflect.annotation.AnnotationType;
|
||||
import sun.nio.ch.Interruptible;
|
||||
import sun.security.util.SecurityConstants;
|
||||
|
||||
/**
|
||||
* The <code>System</code> class contains several useful class fields
|
||||
@ -1160,7 +1160,7 @@ public final class System {
|
||||
* @param msg the string message (or a key in the message catalog, if
|
||||
* this logger is a {@link
|
||||
* LoggerFinder#getLocalizedLogger(java.lang.String,
|
||||
* java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
|
||||
* java.util.ResourceBundle, java.lang.Module) localized logger});
|
||||
* can be {@code null}.
|
||||
*
|
||||
* @throws NullPointerException if {@code level} is {@code null}.
|
||||
@ -1228,7 +1228,7 @@ public final class System {
|
||||
* @param msg the string message (or a key in the message catalog, if
|
||||
* this logger is a {@link
|
||||
* LoggerFinder#getLocalizedLogger(java.lang.String,
|
||||
* java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
|
||||
* java.util.ResourceBundle, java.lang.Module) localized logger});
|
||||
* can be {@code null}.
|
||||
* @param thrown a {@code Throwable} associated with the log message;
|
||||
* can be {@code null}.
|
||||
@ -1277,7 +1277,7 @@ public final class System {
|
||||
* java.text.MessageFormat} format, (or a key in the message
|
||||
* catalog, if this logger is a {@link
|
||||
* LoggerFinder#getLocalizedLogger(java.lang.String,
|
||||
* java.util.ResourceBundle, java.lang.reflect.Module) localized logger});
|
||||
* java.util.ResourceBundle, java.lang.Module) localized logger});
|
||||
* can be {@code null}.
|
||||
* @param params an optional list of parameters to the message (may be
|
||||
* none).
|
||||
@ -1482,7 +1482,7 @@ public final class System {
|
||||
* message localization.
|
||||
*
|
||||
* @implSpec By default, this method calls {@link
|
||||
* #getLogger(java.lang.String, java.lang.reflect.Module)
|
||||
* #getLogger(java.lang.String, java.lang.Module)
|
||||
* this.getLogger(name, module)} to obtain a logger, then wraps that
|
||||
* logger in a {@link Logger} instance where all methods that do not
|
||||
* take a {@link ResourceBundle} as parameter are redirected to one
|
||||
@ -1566,12 +1566,20 @@ public final class System {
|
||||
* @implSpec
|
||||
* Instances returned by this method route messages to loggers
|
||||
* obtained by calling {@link LoggerFinder#getLogger(java.lang.String,
|
||||
* java.lang.reflect.Module) LoggerFinder.getLogger(name, module)}, where
|
||||
* java.lang.Module) LoggerFinder.getLogger(name, module)}, where
|
||||
* {@code module} is the caller's module.
|
||||
* In cases where {@code System.getLogger} is called from a context where
|
||||
* there is no caller frame on the stack (e.g when called directly
|
||||
* from a JNI attached thread), {@code IllegalCallerException} is thrown.
|
||||
* To obtain a logger in such a context, use an auxiliary class that will
|
||||
* implicitly be identified as the caller, or use the system {@link
|
||||
* LoggerFinder#getLoggerFinder() LoggerFinder} to obtain a logger instead.
|
||||
* Note that doing the latter may eagerly initialize the underlying
|
||||
* logging system.
|
||||
*
|
||||
* @apiNote
|
||||
* This method may defer calling the {@link
|
||||
* LoggerFinder#getLogger(java.lang.String, java.lang.reflect.Module)
|
||||
* LoggerFinder#getLogger(java.lang.String, java.lang.Module)
|
||||
* LoggerFinder.getLogger} method to create an actual logger supplied by
|
||||
* the logging backend, for instance, to allow loggers to be obtained during
|
||||
* the system initialization time.
|
||||
@ -1580,6 +1588,8 @@ public final class System {
|
||||
* @return an instance of {@link Logger} that can be used by the calling
|
||||
* class.
|
||||
* @throws NullPointerException if {@code name} is {@code null}.
|
||||
* @throws IllegalCallerException if there is no Java caller frame on the
|
||||
* stack.
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@ -1587,6 +1597,9 @@ public final class System {
|
||||
public static Logger getLogger(String name) {
|
||||
Objects.requireNonNull(name);
|
||||
final Class<?> caller = Reflection.getCallerClass();
|
||||
if (caller == null) {
|
||||
throw new IllegalCallerException("no caller frame");
|
||||
}
|
||||
return LazyLoggers.getLogger(name, caller.getModule());
|
||||
}
|
||||
|
||||
@ -1599,9 +1612,17 @@ public final class System {
|
||||
* @implSpec
|
||||
* The returned logger will perform message localization as specified
|
||||
* by {@link LoggerFinder#getLocalizedLogger(java.lang.String,
|
||||
* java.util.ResourceBundle, java.lang.reflect.Module)
|
||||
* LoggerFinder.getLocalizedLogger(name, bundle, module}, where
|
||||
* java.util.ResourceBundle, java.lang.Module)
|
||||
* LoggerFinder.getLocalizedLogger(name, bundle, module)}, where
|
||||
* {@code module} is the caller's module.
|
||||
* In cases where {@code System.getLogger} is called from a context where
|
||||
* there is no caller frame on the stack (e.g when called directly
|
||||
* from a JNI attached thread), {@code IllegalCallerException} is thrown.
|
||||
* To obtain a logger in such a context, use an auxiliary class that
|
||||
* will implicitly be identified as the caller, or use the system {@link
|
||||
* LoggerFinder#getLoggerFinder() LoggerFinder} to obtain a logger instead.
|
||||
* Note that doing the latter may eagerly initialize the underlying
|
||||
* logging system.
|
||||
*
|
||||
* @apiNote
|
||||
* This method is intended to be used after the system is fully initialized.
|
||||
@ -1620,6 +1641,8 @@ public final class System {
|
||||
* resource bundle for message localization.
|
||||
* @throws NullPointerException if {@code name} is {@code null} or
|
||||
* {@code bundle} is {@code null}.
|
||||
* @throws IllegalCallerException if there is no Java caller frame on the
|
||||
* stack.
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@ -1628,6 +1651,9 @@ public final class System {
|
||||
final ResourceBundle rb = Objects.requireNonNull(bundle);
|
||||
Objects.requireNonNull(name);
|
||||
final Class<?> caller = Reflection.getCallerClass();
|
||||
if (caller == null) {
|
||||
throw new IllegalCallerException("no caller frame");
|
||||
}
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
// We don't use LazyLoggers if a resource bundle is specified.
|
||||
// Bootstrap sensitive classes in the JDK do not use resource bundles
|
||||
@ -1951,7 +1977,7 @@ public final class System {
|
||||
}
|
||||
|
||||
// @see #initPhase2()
|
||||
private static Layer bootLayer;
|
||||
static ModuleLayer bootLayer;
|
||||
|
||||
/*
|
||||
* Invoked by VM. Phase 2 module system initialization.
|
||||
@ -2071,12 +2097,10 @@ public final class System {
|
||||
public Thread newThreadWithAcc(Runnable target, AccessControlContext acc) {
|
||||
return new Thread(target, acc);
|
||||
}
|
||||
@SuppressWarnings("deprecation")
|
||||
public void invokeFinalize(Object o) throws Throwable {
|
||||
o.finalize();
|
||||
}
|
||||
public Layer getBootLayer() {
|
||||
return bootLayer;
|
||||
}
|
||||
public ConcurrentHashMap<?, ?> createOrGetClassLoaderValueMap(ClassLoader cl) {
|
||||
return cl.createOrGetClassLoaderValueMap();
|
||||
}
|
||||
@ -2101,6 +2125,44 @@ public final class System {
|
||||
public void invalidatePackageAccessCache() {
|
||||
SecurityManager.invalidatePackageAccessCache();
|
||||
}
|
||||
public Module defineModule(ClassLoader loader,
|
||||
ModuleDescriptor descriptor,
|
||||
URI uri) {
|
||||
return new Module(null, loader, descriptor, uri);
|
||||
}
|
||||
public Module defineUnnamedModule(ClassLoader loader) {
|
||||
return new Module(loader);
|
||||
}
|
||||
public void addReads(Module m1, Module m2) {
|
||||
m1.implAddReads(m2);
|
||||
}
|
||||
public void addReadsAllUnnamed(Module m) {
|
||||
m.implAddReadsAllUnnamed();
|
||||
}
|
||||
public void addExports(Module m, String pn, Module other) {
|
||||
m.implAddExports(pn, other);
|
||||
}
|
||||
public void addExportsToAllUnnamed(Module m, String pn) {
|
||||
m.implAddExportsToAllUnnamed(pn);
|
||||
}
|
||||
public void addOpens(Module m, String pn, Module other) {
|
||||
m.implAddOpens(pn, other);
|
||||
}
|
||||
public void addOpensToAllUnnamed(Module m, String pn) {
|
||||
m.implAddOpensToAllUnnamed(pn);
|
||||
}
|
||||
public void addUses(Module m, Class<?> service) {
|
||||
m.implAddUses(service);
|
||||
}
|
||||
public ServicesCatalog getServicesCatalog(ModuleLayer layer) {
|
||||
return layer.getServicesCatalog();
|
||||
}
|
||||
public Stream<ModuleLayer> layers(ModuleLayer layer) {
|
||||
return layer.layers();
|
||||
}
|
||||
public Stream<ModuleLayer> layers(ClassLoader loader) {
|
||||
return ModuleLayer.layers(loader);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -927,7 +927,7 @@ class Thread implements Runnable {
|
||||
* for example), the <code>interrupt</code> method should be used to
|
||||
* interrupt the wait.
|
||||
* For more information, see
|
||||
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
|
||||
* <a href="{@docRoot}/java/lang/doc-files/threadPrimitiveDeprecation.html">Why
|
||||
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
||||
*/
|
||||
@Deprecated(since="1.2")
|
||||
@ -960,7 +960,7 @@ class Thread implements Runnable {
|
||||
* could be used to generate exceptions that the target thread was
|
||||
* not prepared to handle.
|
||||
* For more information, see
|
||||
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
|
||||
* <a href="{@docRoot}/java/lang/doc-files/threadPrimitiveDeprecation.html">Why
|
||||
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
||||
* This method is subject to removal in a future version of Java SE.
|
||||
*/
|
||||
@ -1082,7 +1082,7 @@ class Thread implements Runnable {
|
||||
* If another thread ever attempted to lock this resource, deadlock
|
||||
* would result. Such deadlocks typically manifest themselves as
|
||||
* "frozen" processes. For more information, see
|
||||
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">
|
||||
* <a href="{@docRoot}/java/lang/doc-files/threadPrimitiveDeprecation.html">
|
||||
* Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
||||
* This method is subject to removal in a future version of Java SE.
|
||||
* @throws NoSuchMethodError always
|
||||
@ -1122,7 +1122,7 @@ class Thread implements Runnable {
|
||||
* monitor prior to calling <code>resume</code>, deadlock results. Such
|
||||
* deadlocks typically manifest themselves as "frozen" processes.
|
||||
* For more information, see
|
||||
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
|
||||
* <a href="{@docRoot}/java/lang/doc-files/threadPrimitiveDeprecation.html">Why
|
||||
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
||||
*/
|
||||
@Deprecated(since="1.2")
|
||||
@ -1148,7 +1148,7 @@ class Thread implements Runnable {
|
||||
* @deprecated This method exists solely for use with {@link #suspend},
|
||||
* which has been deprecated because it is deadlock-prone.
|
||||
* For more information, see
|
||||
* <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
|
||||
* <a href="{@docRoot}/java/lang/doc-files/threadPrimitiveDeprecation.html">Why
|
||||
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
||||
*/
|
||||
@Deprecated(since="1.2")
|
||||
|
@ -22,7 +22,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package java.lang.reflect;
|
||||
package java.lang;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, 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
|
||||
@ -28,7 +28,7 @@ package java.lang.annotation;
|
||||
/**
|
||||
* The constants of this enumerated type provide a simple classification of the
|
||||
* syntactic locations where annotations may appear in a Java program. These
|
||||
* constants are used in {@link Target java.lang.annotation.Target}
|
||||
* constants are used in {@link java.lang.annotation.Target Target}
|
||||
* meta-annotations to specify where it is legal to write annotations of a
|
||||
* given type.
|
||||
*
|
||||
|
@ -0,0 +1,364 @@
|
||||
<!--
|
||||
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
|
||||
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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Java Thread Primitive Deprecation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
|
||||
</head>
|
||||
<body>
|
||||
<h2>Java Thread Primitive Deprecation</h2>
|
||||
<hr size="3" noshade="noshade" />
|
||||
<h3>Why is <code>Thread.stop</code> deprecated?</h3>
|
||||
<p>Because it is inherently unsafe. Stopping a thread causes it to
|
||||
unlock all the monitors that it has locked. (The monitors are
|
||||
unlocked as the <code>ThreadDeath</code> exception propagates up
|
||||
the stack.) If any of the objects previously protected by these
|
||||
monitors were in an inconsistent state, other threads may now view
|
||||
these objects in an inconsistent state. Such objects are said to be
|
||||
<i>damaged</i>. When threads operate on damaged objects, arbitrary
|
||||
behavior can result. This behavior may be subtle and difficult to
|
||||
detect, or it may be pronounced. Unlike other unchecked exceptions,
|
||||
<code>ThreadDeath</code> kills threads silently; thus, the user has
|
||||
no warning that his program may be corrupted. The corruption can
|
||||
manifest itself at any time after the actual damage occurs, even
|
||||
hours or days in the future.</p>
|
||||
<hr />
|
||||
<h3>Couldn't I just catch the <code>ThreadDeath</code> exception
|
||||
and fix the damaged object?</h3>
|
||||
<p>In theory, perhaps, but it would <em>vastly</em> complicate the
|
||||
task of writing correct multithreaded code. The task would be
|
||||
nearly insurmountable for two reasons:</p>
|
||||
<ol>
|
||||
<li>A thread can throw a <code>ThreadDeath</code> exception
|
||||
<i>almost anywhere</i>. All synchronized methods and blocks would
|
||||
have to be studied in great detail, with this in mind.</li>
|
||||
<li>A thread can throw a second <code>ThreadDeath</code> exception
|
||||
while cleaning up from the first (in the <code>catch</code> or
|
||||
<code>finally</code> clause). Cleanup would have to be repeated till
|
||||
it succeeded. The code to ensure this would be quite complex.</li>
|
||||
</ol>
|
||||
In sum, it just isn't practical.
|
||||
<hr />
|
||||
<h3>What about <code>Thread.stop(Throwable)</code>?</h3>
|
||||
<p>In addition to all of the problems noted above, this method may
|
||||
be used to generate exceptions that its target thread is unprepared
|
||||
to handle (including checked exceptions that the thread could not
|
||||
possibly throw, were it not for this method). For example, the
|
||||
following method is behaviorally identical to Java's
|
||||
<code>throw</code> operation, but circumvents the compiler's
|
||||
attempts to guarantee that the calling method has declared all of
|
||||
the checked exceptions that it may throw:</p>
|
||||
<pre>
|
||||
static void sneakyThrow(Throwable t) {
|
||||
Thread.currentThread().stop(t);
|
||||
}
|
||||
</pre>
|
||||
<hr />
|
||||
<h3>What should I use instead of <code>Thread.stop</code>?</h3>
|
||||
<p>Most uses of <code>stop</code> should be replaced by code that
|
||||
simply modifies some variable to indicate that the target thread
|
||||
should stop running. The target thread should check this variable
|
||||
regularly, and return from its run method in an orderly fashion if
|
||||
the variable indicates that it is to stop running. To ensure prompt
|
||||
communication of the stop-request, the variable must be
|
||||
<tt>volatile</tt> (or access to the variable must be
|
||||
synchronized).</p>
|
||||
<p>For example, suppose your applet contains the following
|
||||
<code>start</code>, <code>stop</code> and <code>run</code>
|
||||
methods:</p>
|
||||
<pre>
|
||||
private Thread blinker;
|
||||
|
||||
public void start() {
|
||||
blinker = new Thread(this);
|
||||
blinker.start();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
blinker.stop(); // UNSAFE!
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(interval);
|
||||
} catch (InterruptedException e){
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
You can avoid the use of <code>Thread.stop</code> by replacing the
|
||||
applet's <code>stop</code> and <code>run</code> methods with:
|
||||
<pre>
|
||||
private volatile Thread blinker;
|
||||
|
||||
public void stop() {
|
||||
blinker = null;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
Thread thisThread = Thread.currentThread();
|
||||
while (blinker == thisThread) {
|
||||
try {
|
||||
Thread.sleep(interval);
|
||||
} catch (InterruptedException e){
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
<hr />
|
||||
<h3>How do I stop a thread that waits for long periods (e.g., for
|
||||
input)?</h3>
|
||||
<p>That's what the <code>Thread.interrupt</code> method is for. The
|
||||
same "state based" signaling mechanism shown above can be used, but
|
||||
the state change (<code>blinker = null</code>, in the previous
|
||||
example) can be followed by a call to
|
||||
<code>Thread.interrupt</code>, to interrupt the wait:</p>
|
||||
<pre>
|
||||
public void stop() {
|
||||
Thread moribund = waiter;
|
||||
waiter = null;
|
||||
moribund.interrupt();
|
||||
}
|
||||
</pre>
|
||||
For this technique to work, it's critical that any method that
|
||||
catches an interrupt exception and is not prepared to deal with it
|
||||
immediately reasserts the exception. We say <em>reasserts</em>
|
||||
rather than <em>rethrows</em>, because it is not always possible to
|
||||
rethrow the exception. If the method that catches the
|
||||
<code>InterruptedException</code> is not declared to throw this
|
||||
(checked) exception, then it should "reinterrupt itself" with the
|
||||
following incantation:
|
||||
<pre>
|
||||
Thread.currentThread().interrupt();
|
||||
</pre>
|
||||
This ensures that the Thread will reraise the
|
||||
<code>InterruptedException</code> as soon as it is able.
|
||||
<hr />
|
||||
<h3>What if a thread doesn't respond to
|
||||
<code>Thread.interrupt</code>?</h3>
|
||||
<p>In some cases, you can use application specific tricks. For
|
||||
example, if a thread is waiting on a known socket, you can close
|
||||
the socket to cause the thread to return immediately.
|
||||
Unfortunately, there really isn't any technique that works in
|
||||
general. <em>It should be noted that in all situations where a
|
||||
waiting thread doesn't respond to <code>Thread.interrupt</code>, it
|
||||
wouldn't respond to <code>Thread.stop</code> either.</em> Such
|
||||
cases include deliberate denial-of-service attacks, and I/O
|
||||
operations for which thread.stop and thread.interrupt do not work
|
||||
properly.</p>
|
||||
<hr />
|
||||
<h3>Why are <code>Thread.suspend</code> and
|
||||
<code>Thread.resume</code> deprecated?</h3>
|
||||
<p><code>Thread.suspend</code> is inherently deadlock-prone. If the
|
||||
target thread holds a lock on the monitor protecting a critical
|
||||
system resource when it is suspended, no thread can access this
|
||||
resource until the target thread is resumed. If the thread that
|
||||
would resume the target thread attempts to lock this monitor prior
|
||||
to calling <code>resume</code>, deadlock results. Such deadlocks
|
||||
typically manifest themselves as "frozen" processes.</p>
|
||||
<hr />
|
||||
<h3>What should I use instead of <code>Thread.suspend</code> and
|
||||
<code>Thread.resume</code>?</h3>
|
||||
<p>As with <code>Thread.stop</code>, the prudent approach is to
|
||||
have the "target thread" poll a variable indicating the desired
|
||||
state of the thread (active or suspended). When the desired state
|
||||
is suspended, the thread waits using <code>Object.wait</code>. When
|
||||
the thread is resumed, the target thread is notified using
|
||||
<code>Object.notify</code>.</p>
|
||||
<p>For example, suppose your applet contains the following
|
||||
mousePressed event handler, which toggles the state of a thread
|
||||
called <code>blinker</code>:</p>
|
||||
<pre>
|
||||
private boolean threadSuspended;
|
||||
|
||||
Public void mousePressed(MouseEvent e) {
|
||||
e.consume();
|
||||
|
||||
if (threadSuspended)
|
||||
blinker.resume();
|
||||
else
|
||||
blinker.suspend(); // DEADLOCK-PRONE!
|
||||
|
||||
threadSuspended = !threadSuspended;
|
||||
}
|
||||
</pre>
|
||||
You can avoid the use of <code>Thread.suspend</code> and
|
||||
<code>Thread.resume</code> by replacing the event handler above
|
||||
with:
|
||||
<pre>
|
||||
public synchronized void mousePressed(MouseEvent e) {
|
||||
e.consume();
|
||||
|
||||
threadSuspended = !threadSuspended;
|
||||
|
||||
if (!threadSuspended)
|
||||
notify();
|
||||
}
|
||||
</pre>
|
||||
and adding the following code to the "run loop":
|
||||
<pre>
|
||||
synchronized(this) {
|
||||
while (threadSuspended)
|
||||
wait();
|
||||
}
|
||||
</pre>
|
||||
The <code>wait</code> method throws the
|
||||
<code>InterruptedException</code>, so it must be inside a <code>try
|
||||
... catch</code> clause. It's fine to put it in the same clause as
|
||||
the <code>sleep</code>. The check should follow (rather than
|
||||
precede) the <code>sleep</code> so the window is immediately
|
||||
repainted when the thread is "resumed." The resulting
|
||||
<code>run</code> method follows:
|
||||
<pre>
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(interval);
|
||||
|
||||
synchronized(this) {
|
||||
while (threadSuspended)
|
||||
wait();
|
||||
}
|
||||
} catch (InterruptedException e){
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
Note that the <code>notify</code> in the <code>mousePressed</code>
|
||||
method and the <code>wait</code> in the <code>run</code> method are
|
||||
inside <code>synchronized</code> blocks. This is required by the
|
||||
language, and ensures that <code>wait</code> and
|
||||
<code>notify</code> are properly serialized. In practical terms,
|
||||
this eliminates race conditions that could cause the "suspended"
|
||||
thread to miss a <code>notify</code> and remain suspended
|
||||
indefinitely.
|
||||
<p>While the cost of synchronization in Java is decreasing as the
|
||||
platform matures, it will never be free. A simple trick can be used
|
||||
to remove the synchronization that we've added to each iteration of
|
||||
the "run loop." The synchronized block that was added is replaced
|
||||
by a slightly more complex piece of code that enters a synchronized
|
||||
block only if the thread has actually been suspended:</p>
|
||||
<pre>
|
||||
if (threadSuspended) {
|
||||
synchronized(this) {
|
||||
while (threadSuspended)
|
||||
wait();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
<p>In the absence of explicit synchronization,
|
||||
<tt>threadSuspended</tt> must be made <tt>volatile</tt> to ensure
|
||||
prompt communication of the suspend-request.</p>
|
||||
The resulting <code>run</code> method is:
|
||||
<pre>
|
||||
private volatile boolean threadSuspended;
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(interval);
|
||||
|
||||
if (threadSuspended) {
|
||||
synchronized(this) {
|
||||
while (threadSuspended)
|
||||
wait();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e){
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
<hr size="3" noshade="noshade" />
|
||||
<h3>Can I combine the two techniques to produce a thread that may
|
||||
be safely "stopped" or "suspended"?</h3>
|
||||
Yes, it's reasonably straightforward. The one subtlety is that the
|
||||
target thread may already be suspended at the time that another
|
||||
thread tries to stop it. If the <tt>stop</tt> method merely sets
|
||||
the state variable (<tt>blinker</tt>) to null, the target thread
|
||||
will remain suspended (waiting on the monitor), rather than exiting
|
||||
gracefully as it should. If the applet is restarted, multiple
|
||||
threads could end up waiting on the monitor at the same time,
|
||||
resulting in erratic behavior.
|
||||
<p>To rectify this situation, the <tt>stop</tt> method must ensure
|
||||
that the target thread resumes immediately if it is suspended. Once
|
||||
the target thread resumes, it must recognize immediately that it
|
||||
has been stopped, and exit gracefully. Here's how the resulting
|
||||
<tt>run</tt> and <tt>stop</tt> methods look:</p>
|
||||
<pre>
|
||||
public void run() {
|
||||
Thread thisThread = Thread.currentThread();
|
||||
while (blinker == thisThread) {
|
||||
try {
|
||||
Thread.sleep(interval);
|
||||
|
||||
synchronized(this) {
|
||||
while (threadSuspended && blinker==thisThread)
|
||||
wait();
|
||||
}
|
||||
} catch (InterruptedException e){
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void stop() {
|
||||
blinker = null;
|
||||
notify();
|
||||
}
|
||||
</pre>
|
||||
If the <tt>stop</tt> method calls <tt>Thread.interrupt</tt>, as
|
||||
described above, it needn't call <tt>notify</tt> as well, but it
|
||||
still must be synchronized. This ensures that the target thread
|
||||
won't miss an interrupt due to a race condition.
|
||||
<hr />
|
||||
<h3>What about <code>Thread.destroy</code>?</h3>
|
||||
<code>Thread.destroy</code> was never implemented and has been
|
||||
deprecated. If it were implemented, it would be deadlock-prone in
|
||||
the manner of <code>Thread.suspend</code>. (In fact, it is roughly
|
||||
equivalent to <code>Thread.suspend</code> without the possibility
|
||||
of a subsequent <code>Thread.resume</code>.)
|
||||
<hr />
|
||||
<h3>Why is <code>Runtime.runFinalizersOnExit</code>
|
||||
deprecated?</h3>
|
||||
Because it is inherently unsafe. It may result in finalizers being
|
||||
called on live objects while other threads are concurrently
|
||||
manipulating those objects, resulting in erratic behavior or
|
||||
deadlock. While this problem could be prevented if the class whose
|
||||
objects are being finalized were coded to "defend against" this
|
||||
call, most programmers do <i>not</i> defend against it. They assume
|
||||
that an object is dead at the time that its finalizer is called.
|
||||
<p>Further, the call is not "thread-safe" in the sense that it sets
|
||||
a VM-global flag. This forces <i>every</i> class with a finalizer
|
||||
to defend against the finalization of live objects!</p>
|
||||
<p><!-- Body text ends here --></p>
|
||||
</body>
|
||||
</html>
|
@ -33,7 +33,6 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Module;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
@ -43,7 +43,6 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Module;
|
||||
import java.lang.reflect.ReflectPermission;
|
||||
import java.nio.ByteOrder;
|
||||
import java.security.AccessController;
|
||||
@ -668,11 +667,11 @@ public class MethodHandles {
|
||||
* The value is {@code 0x20}, which does not correspond meaningfully to
|
||||
* any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
|
||||
* A {@code Lookup} with this lookup mode assumes {@linkplain
|
||||
* java.lang.reflect.Module#canRead(java.lang.reflect.Module) readability}.
|
||||
* java.lang.Module#canRead(java.lang.Module) readability}.
|
||||
* In conjunction with the {@code PUBLIC} modifier bit, a {@code Lookup}
|
||||
* with this lookup mode can access all public members of public types
|
||||
* of all modules where the type is in a package that is {@link
|
||||
* java.lang.reflect.Module#isExported(String) exported unconditionally}.
|
||||
* java.lang.Module#isExported(String) exported unconditionally}.
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
* @see #publicLookup()
|
||||
|
@ -64,11 +64,11 @@ import java.util.stream.Stream;
|
||||
* with the receiver as the parent configuration. The static methods are for
|
||||
* more advanced cases where there can be more than one parent configuration. </p>
|
||||
*
|
||||
* <p> Each {@link java.lang.reflect.Layer layer} of modules in the Java virtual
|
||||
* <p> Each {@link java.lang.ModuleLayer layer} of modules in the Java virtual
|
||||
* machine is created from a configuration. The configuration for the {@link
|
||||
* java.lang.reflect.Layer#boot() boot} layer is obtained by invoking {@code
|
||||
* Layer.boot().configuration()}. The configuration for the boot layer will
|
||||
* often be the parent when creating new configurations. </p>
|
||||
* java.lang.ModuleLayer#boot() boot} layer is obtained by invoking {@code
|
||||
* ModuleLayer.boot().configuration()}. The configuration for the boot layer
|
||||
* will often be the parent when creating new configurations. </p>
|
||||
*
|
||||
* <h3> Example </h3>
|
||||
*
|
||||
@ -81,7 +81,7 @@ import java.util.stream.Stream;
|
||||
* <pre>{@code
|
||||
* ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
|
||||
*
|
||||
* Configuration parent = Layer.boot().configuration();
|
||||
* Configuration parent = ModuleLayer.boot().configuration();
|
||||
*
|
||||
* Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("myapp"));
|
||||
* cf.modules().forEach(m -> {
|
||||
@ -95,7 +95,7 @@ import java.util.stream.Stream;
|
||||
*
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
* @see java.lang.reflect.Layer
|
||||
* @see java.lang.ModuleLayer
|
||||
*/
|
||||
public final class Configuration {
|
||||
|
||||
|
@ -60,7 +60,7 @@ import jdk.internal.module.ModuleInfo;
|
||||
* <p> A module descriptor describes a named module and defines methods to
|
||||
* obtain each of its components. The module descriptor for a named module
|
||||
* in the Java virtual machine is obtained by invoking the {@link
|
||||
* java.lang.reflect.Module Module}'s {@link java.lang.reflect.Module#getDescriptor
|
||||
* java.lang.Module Module}'s {@link java.lang.Module#getDescriptor
|
||||
* getDescriptor} method. Module descriptors can also be created using the
|
||||
* {@link ModuleDescriptor.Builder} class or by reading the binary form of a
|
||||
* module declaration ({@code module-info.class}) using the {@link
|
||||
@ -85,7 +85,7 @@ import jdk.internal.module.ModuleInfo;
|
||||
* <p> {@code ModuleDescriptor} objects are immutable and safe for use by
|
||||
* multiple concurrent threads.</p>
|
||||
*
|
||||
* @see java.lang.reflect.Module
|
||||
* @see java.lang.Module
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
@ -2110,7 +2110,9 @@ public class ModuleDescriptor
|
||||
|
||||
/**
|
||||
* Sets the module main class. The package for the main class is added
|
||||
* to the module if not already added.
|
||||
* to the module if not already added. In other words, this method is
|
||||
* equivalent to first invoking this builder's {@link #packages(Set)
|
||||
* packages} method to add the package name of the main class.
|
||||
*
|
||||
* @param mc
|
||||
* The module main class
|
||||
@ -2134,8 +2136,8 @@ public class ModuleDescriptor
|
||||
throw new IllegalArgumentException(mc + ": unnamed package");
|
||||
}
|
||||
}
|
||||
mainClass = mc;
|
||||
packages.add(pn);
|
||||
mainClass = mc;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -228,14 +228,14 @@ public interface ModuleFinder {
|
||||
* directory is treated as an exploded module rather than a directory of
|
||||
* modules. </p>
|
||||
*
|
||||
* <p> The module finder returned by this method supports modules that are
|
||||
* packaged as JAR files. A JAR file with a {@code module-info.class} in
|
||||
* the top-level directory of the JAR file (or overridden by a versioned
|
||||
* entry in a {@link java.util.jar.JarFile#isMultiRelease() multi-release}
|
||||
* JAR file) is a modular JAR and is an <em>explicit module</em>.
|
||||
* A JAR file that does not have a {@code module-info.class} in the
|
||||
* top-level directory is created as an automatic module. The components
|
||||
* for the automatic module are derived as follows:
|
||||
* <p id="automatic-modules"> The module finder returned by this method
|
||||
* supports modules packaged as JAR files. A JAR file with a {@code
|
||||
* module-info.class} in its top-level directory, or in a versioned entry
|
||||
* in a {@linkplain java.util.jar.JarFile#isMultiRelease() multi-release}
|
||||
* JAR file, is a modular JAR file and thus defines an <em>explicit</em>
|
||||
* module. A JAR file that does not have a {@code module-info.class} in its
|
||||
* top-level directory defines an <em>automatic module</em>, as follows:
|
||||
* </p>
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
@ -254,16 +254,16 @@ public interface ModuleFinder {
|
||||
* ModuleDescriptor.Version} and ignored if it cannot be parsed as
|
||||
* a {@code Version}. </p></li>
|
||||
*
|
||||
* <li><p> For the module name, then any trailing digits and dots
|
||||
* are removed, all non-alphanumeric characters ({@code [^A-Za-z0-9]})
|
||||
* 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> 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-1.2.3-SNAPSHOT.jar} will derive a module name
|
||||
* {@code foo} and {@code 1.2.3-SNAPSHOT} as the version. </p></li>
|
||||
* 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>
|
||||
*
|
||||
@ -312,7 +312,9 @@ public interface ModuleFinder {
|
||||
*
|
||||
* <p> As with automatic modules, the contents of a packaged or exploded
|
||||
* module may need to be <em>scanned</em> in order to determine the packages
|
||||
* in the module. If a {@code .class} file (other than {@code
|
||||
* in the module. Whether {@linkplain java.nio.file.Files#isHidden(Path)
|
||||
* hidden files} are ignored or not is implementation specific and therefore
|
||||
* not specified. If a {@code .class} file (other than {@code
|
||||
* module-info.class}) is found in the top-level directory then it is
|
||||
* assumed to be a class in the unnamed package and so {@code FindException}
|
||||
* is thrown. </p>
|
||||
|
@ -28,7 +28,6 @@ package java.lang.module;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.module.ModuleDescriptor.Provides;
|
||||
import java.lang.module.ModuleDescriptor.Requires.Modifier;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -67,6 +66,9 @@ final class Resolver {
|
||||
// maps module name to module reference
|
||||
private final Map<String, ModuleReference> nameToReference = new HashMap<>();
|
||||
|
||||
// true if all automatic modules have been found
|
||||
private boolean haveAllAutomaticModules;
|
||||
|
||||
// module constraints on target platform
|
||||
private String osName;
|
||||
private String osArch;
|
||||
@ -171,6 +173,21 @@ final class Resolver {
|
||||
ModuleDescriptor descriptor = q.poll();
|
||||
assert nameToReference.containsKey(descriptor.name());
|
||||
|
||||
// if the module is an automatic module then all automatic
|
||||
// modules need to be resolved
|
||||
if (descriptor.isAutomatic() && !haveAllAutomaticModules) {
|
||||
addFoundAutomaticModules().forEach(mref -> {
|
||||
ModuleDescriptor other = mref.descriptor();
|
||||
q.offer(other);
|
||||
if (isTracing()) {
|
||||
trace("Automatic module %s located, required by %s",
|
||||
other.name(), descriptor.name());
|
||||
mref.location().ifPresent(uri -> trace(" (%s)", uri));
|
||||
}
|
||||
});
|
||||
haveAllAutomaticModules = true;
|
||||
}
|
||||
|
||||
// process dependences
|
||||
for (ModuleDescriptor.Requires requires : descriptor.requires()) {
|
||||
|
||||
@ -199,10 +216,15 @@ final class Resolver {
|
||||
if (!nameToReference.containsKey(dn)) {
|
||||
addFoundModule(mref);
|
||||
q.offer(mref.descriptor());
|
||||
resolved.add(mref.descriptor());
|
||||
|
||||
if (isTracing()) {
|
||||
trace("Module %s located, required by %s",
|
||||
String prefix;
|
||||
if (mref.descriptor().isAutomatic()) {
|
||||
prefix = "Automatic module";
|
||||
} else {
|
||||
prefix = "Module";
|
||||
}
|
||||
trace(prefix + " %s located, required by %s",
|
||||
dn, descriptor.name());
|
||||
mref.location().ifPresent(uri -> trace(" (%s)", uri));
|
||||
}
|
||||
@ -250,7 +272,7 @@ final class Resolver {
|
||||
|
||||
// the initial set of modules that may use services
|
||||
Set<ModuleDescriptor> initialConsumers;
|
||||
if (Layer.boot() == null) {
|
||||
if (ModuleLayer.boot() == null) {
|
||||
initialConsumers = new HashSet<>();
|
||||
} else {
|
||||
initialConsumers = parents.stream()
|
||||
@ -301,6 +323,21 @@ final class Resolver {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all automatic modules that have not already been found to the
|
||||
* nameToReference map.
|
||||
*/
|
||||
private Set<ModuleReference> addFoundAutomaticModules() {
|
||||
Set<ModuleReference> result = new HashSet<>();
|
||||
findAll().forEach(mref -> {
|
||||
String mn = mref.descriptor().name();
|
||||
if (mref.descriptor().isAutomatic() && !nameToReference.containsKey(mn)) {
|
||||
addFoundModule(mref);
|
||||
result.add(mref);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the module to the nameToReference map. Also check any constraints on
|
||||
@ -534,7 +571,7 @@ final class Resolver {
|
||||
// need "requires transitive" from the modules in parent configurations
|
||||
// as there may be selected modules that have a dependency on modules in
|
||||
// the parent configuration.
|
||||
if (Layer.boot() == null) {
|
||||
if (ModuleLayer.boot() == null) {
|
||||
g2 = new HashMap<>(capacity);
|
||||
} else {
|
||||
g2 = parents.stream()
|
||||
|
@ -70,7 +70,7 @@
|
||||
* } </pre>
|
||||
*
|
||||
* <p> If module {@code m1} is resolved with the configuration for the {@link
|
||||
* java.lang.reflect.Layer#boot() boot} layer as the parent then the resulting
|
||||
* 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
|
||||
@ -92,10 +92,10 @@
|
||||
*
|
||||
* <p> {@link java.lang.module.ModuleDescriptor#isAutomatic() Automatic} modules
|
||||
* receive special treatment during resolution. Each automatic module is resolved
|
||||
* so that it reads all other modules in the configuration and all parent
|
||||
* configurations. Each automatic module is also resolved as if it
|
||||
* "{@code requires transitive}" all other automatic modules in the configuration
|
||||
* (and all automatic modules in parent configurations). </p>
|
||||
* 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 name="servicebinding">Service binding</a></h2>
|
||||
*
|
||||
|
@ -174,7 +174,6 @@ public final class Constructor<T> extends Executable {
|
||||
* @throws SecurityException if the request is denied by the security manager
|
||||
* or this is a constructor for {@code java.lang.Class}
|
||||
*
|
||||
* @since 9
|
||||
* @spec JPMS
|
||||
*/
|
||||
@Override
|
||||
|
@ -227,11 +227,11 @@ import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
|
||||
* {@code Proxy.newProxyInstance} method should be used instead.
|
||||
*
|
||||
* <p>
|
||||
* A dynamic module can read the modules of all of the superinterfaces of a proxy class
|
||||
* and the modules of the types referenced by all public method signatures
|
||||
* A dynamic module can read the modules of all of the superinterfaces of a proxy
|
||||
* class and the modules of the types referenced by all public method signatures
|
||||
* of a proxy class. If a superinterface or a referenced type, say {@code T},
|
||||
* is in a non-exported package, the {@linkplain java.lang.reflect.Module module}
|
||||
* of {@code T} is updated to export the package of {@code T} to the dynamic module.
|
||||
* is in a non-exported package, the {@linkplain Module module} of {@code T} is
|
||||
* updated to export the package of {@code T} to the dynamic module.
|
||||
*
|
||||
* <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
|
||||
*
|
||||
|
@ -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
|
||||
@ -25,11 +25,10 @@
|
||||
|
||||
/**
|
||||
* Provides classes and interfaces for obtaining reflective information about
|
||||
* modules, classes and objects. Reflection allows programmatic access to
|
||||
* information about modules and to the fields, methods and constructors of
|
||||
* loaded classes, and the use of reflected fields, methods, and constructors
|
||||
* to operate on their underlying counterparts, within encapsulation and
|
||||
* security restrictions.
|
||||
* classes and objects. Reflection allows programmatic access to information
|
||||
* about the fields, methods and constructors of loaded classes, and the use
|
||||
* of reflected fields, methods, and constructors to operate on their underlying
|
||||
* counterparts, within encapsulation and security restrictions.
|
||||
*
|
||||
* <p>{@code AccessibleObject} allows suppression of access checks if
|
||||
* the necessary {@code ReflectPermission} is available.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2016, 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
|
||||
@ -275,6 +275,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
return (fd == null) ? true : false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() {
|
||||
close();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1995, 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
|
||||
@ -646,6 +646,7 @@ abstract class AbstractPlainSocketImpl extends SocketImpl
|
||||
/**
|
||||
* Cleans up if the user forgets to close it.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() throws IOException {
|
||||
close();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1995, 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
|
||||
@ -283,6 +283,7 @@ class SocketInputStream extends FileInputStream
|
||||
/**
|
||||
* Overrides finalize, the fd is closed by the Socket.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() {}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1995, 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
|
||||
@ -175,6 +175,7 @@ class SocketOutputStream extends FileOutputStream
|
||||
/**
|
||||
* Overrides finalize, the fd is closed by the Socket.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() {}
|
||||
|
||||
/**
|
||||
|
@ -213,7 +213,6 @@ public abstract class MappedByteBuffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public final MappedByteBuffer position(int newPosition) {
|
||||
@ -223,7 +222,6 @@ public abstract class MappedByteBuffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public final MappedByteBuffer limit(int newLimit) {
|
||||
@ -233,7 +231,6 @@ public abstract class MappedByteBuffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public final MappedByteBuffer mark() {
|
||||
@ -243,7 +240,6 @@ public abstract class MappedByteBuffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public final MappedByteBuffer reset() {
|
||||
@ -253,7 +249,6 @@ public abstract class MappedByteBuffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public final MappedByteBuffer clear() {
|
||||
@ -263,7 +258,6 @@ public abstract class MappedByteBuffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public final MappedByteBuffer flip() {
|
||||
@ -273,7 +267,6 @@ public abstract class MappedByteBuffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public final MappedByteBuffer rewind() {
|
||||
|
@ -1069,7 +1069,6 @@ public abstract class $Type$Buffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
@ -1083,7 +1082,6 @@ public abstract class $Type$Buffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
@ -1097,7 +1095,6 @@ public abstract class $Type$Buffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
@ -1111,7 +1108,6 @@ public abstract class $Type$Buffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
@ -1125,7 +1121,6 @@ public abstract class $Type$Buffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
@ -1139,7 +1134,6 @@ public abstract class $Type$Buffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
@ -1153,7 +1147,6 @@ public abstract class $Type$Buffer
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public
|
||||
|
@ -651,8 +651,6 @@ public class SecureRandom extends java.util.Random {
|
||||
* {@code SecureRandom}.
|
||||
*
|
||||
* @return the string representation
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -211,8 +211,6 @@ public abstract class SecureRandomSpi implements java.io.Serializable {
|
||||
* {@code SecureRandom}.
|
||||
*
|
||||
* @return the string representation
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -310,8 +310,8 @@ public interface Era extends TemporalAccessor, TemporalAdjuster {
|
||||
* The parameters control the style of the returned text and the locale.
|
||||
* <p>
|
||||
* If no textual mapping is found then the {@link #getValue() numeric value} is returned.
|
||||
* <p>
|
||||
* This default implementation is suitable for all implementations.
|
||||
*
|
||||
* @apiNote This default implementation is suitable for most implementations.
|
||||
*
|
||||
* @param style the style of the text required, not null
|
||||
* @param locale the locale to use, not null
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -240,19 +240,10 @@ public final class JapaneseEra
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the textual representation of this era.
|
||||
* <p>
|
||||
* This returns the textual name used to identify the era,
|
||||
* suitable for presentation to the user.
|
||||
* The parameters control the style of the returned text and the locale.
|
||||
* <p>
|
||||
* If no textual mapping is found then the {@link #getValue() numeric value}
|
||||
* is returned.
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param style the style of the text required, not null
|
||||
* @param locale the locale to use, not null
|
||||
* @return the text value of the era, not null
|
||||
* @since 9
|
||||
* @param style {@inheritDoc}
|
||||
* @param locale {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getDisplayName(TextStyle style, Locale locale) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -112,12 +112,6 @@ public interface Comparator<T> {
|
||||
* zero, or a positive integer as the first argument is less than, equal
|
||||
* to, or greater than the second.<p>
|
||||
*
|
||||
* In the foregoing description, the notation
|
||||
* {@code sgn(}<i>expression</i>{@code )} designates the mathematical
|
||||
* <i>signum</i> function, which is defined to return one of {@code -1},
|
||||
* {@code 0}, or {@code 1} according to whether the value of
|
||||
* <i>expression</i> is negative, zero or positive.<p>
|
||||
*
|
||||
* The implementor must ensure that {@code sgn(compare(x, y)) ==
|
||||
* -sgn(compare(y, x))} for all {@code x} and {@code y}. (This
|
||||
* implies that {@code compare(x, y)} must throw an exception if and only
|
||||
@ -135,7 +129,13 @@ public interface Comparator<T> {
|
||||
* {@code (compare(x, y)==0) == (x.equals(y))}. Generally speaking,
|
||||
* any comparator that violates this condition should clearly indicate
|
||||
* this fact. The recommended language is "Note: this comparator
|
||||
* imposes orderings that are inconsistent with equals."
|
||||
* imposes orderings that are inconsistent with equals."<p>
|
||||
*
|
||||
* In the foregoing description, the notation
|
||||
* {@code sgn(}<i>expression</i>{@code )} designates the mathematical
|
||||
* <i>signum</i> function, which is defined to return one of {@code -1},
|
||||
* {@code 0}, or {@code 1} according to whether the value of
|
||||
* <i>expression</i> is negative, zero, or positive, respectively.
|
||||
*
|
||||
* @param o1 the first object to be compared.
|
||||
* @param o2 the second object to be compared.
|
||||
|
@ -109,7 +109,8 @@ public interface Iterator<E> {
|
||||
* Exceptions thrown by the action are relayed to the caller.
|
||||
* <p>
|
||||
* The behavior of an iterator is unspecified if the action modifies the
|
||||
* collection in any way (even by calling the {@link #remove remove} method),
|
||||
* collection in any way (even by calling the {@link #remove remove} method
|
||||
* or other mutator methods of {@code Iterator} subtypes),
|
||||
* unless an overriding class has specified a concurrent modification policy.
|
||||
* <p>
|
||||
* Subsequent behavior of an iterator is unspecified if the action throws an
|
||||
|
@ -69,6 +69,8 @@ package java.util;
|
||||
* {@link java.beans} package. For reliable and ordered
|
||||
* messaging among threads, consider using one of the concurrent data
|
||||
* structures in the {@link java.util.concurrent} package.
|
||||
* For reactive streams style programming, see the
|
||||
* {@link java.util.concurrent.Flow} API.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
public class Observable {
|
||||
|
@ -50,7 +50,6 @@ import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
@ -1836,7 +1835,7 @@ public abstract class ResourceBundle {
|
||||
cacheKey.setFormat(format);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (LinkageError|Exception e) {
|
||||
cacheKey.setCause(e);
|
||||
}
|
||||
}
|
||||
|
@ -31,10 +31,8 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.security.AccessControlContext;
|
||||
@ -50,7 +48,6 @@ import java.util.stream.StreamSupport;
|
||||
import jdk.internal.loader.BootLoader;
|
||||
import jdk.internal.loader.ClassLoaders;
|
||||
import jdk.internal.misc.JavaLangAccess;
|
||||
import jdk.internal.misc.JavaLangReflectModuleAccess;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.module.ServicesCatalog;
|
||||
@ -160,7 +157,7 @@ import jdk.internal.reflect.Reflection;
|
||||
* <h2> Locating providers </h2>
|
||||
*
|
||||
* <p> The {@code load} methods locate providers using a class loader or module
|
||||
* {@link Layer layer}. When locating providers using a class loader then
|
||||
* {@link ModuleLayer layer}. When locating providers using a class loader then
|
||||
* providers in both named and unnamed modules may be located. When locating
|
||||
* providers using a module layer then only providers in named modules in
|
||||
* the layer (or parent layers) are located.
|
||||
@ -168,11 +165,11 @@ import jdk.internal.reflect.Reflection;
|
||||
* <p> When locating providers using a class loader then any providers in named
|
||||
* modules defined to the class loader, or any class loader that is reachable
|
||||
* via parent delegation, are located. Additionally, providers in module layers
|
||||
* other than the {@link Layer#boot() boot} layer, where the module layer
|
||||
* other than the {@link ModuleLayer#boot() boot} layer, where the module layer
|
||||
* contains modules defined to the class loader, or any class loader reachable
|
||||
* via parent delegation, are also located. For example, suppose there is a
|
||||
* module layer where each module is defined to its own class loader (see {@link
|
||||
* Layer#defineModulesWithManyLoaders defineModulesWithManyLoaders}). If the
|
||||
* ModuleLayer#defineModulesWithManyLoaders defineModulesWithManyLoaders}). If the
|
||||
* {@code load} method is invoked to locate providers using any of these class
|
||||
* loaders for this layer then it will locate all of the providers in that
|
||||
* layer, irrespective of their defining class loader.
|
||||
@ -198,7 +195,7 @@ import jdk.internal.reflect.Reflection;
|
||||
* will locate providers in modules defined to the class loader, then its
|
||||
* parent class loader, its parent parent, and so on to the bootstrap class
|
||||
* loader. If a {@code ClassLoader}, or any class loader in the parent
|
||||
* delegation chain, defines modules in a custom module {@link Layer} then
|
||||
* delegation chain, defines modules in a custom module {@link ModuleLayer} then
|
||||
* all providers in that layer are located, irrespective of their class
|
||||
* loader. The ordering of modules defined to the same class loader, or the
|
||||
* ordering of modules in a layer, is not defined. </li>
|
||||
@ -216,11 +213,11 @@ import jdk.internal.reflect.Reflection;
|
||||
* method finds the service configuration files. </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p> Service loaders created to locate providers in a module {@link Layer}
|
||||
* will first locate providers in the layer, before locating providers in
|
||||
* parent layers. Traversal of parent layers is depth-first with each layer
|
||||
* visited at most once. For example, suppose L0 is the boot layer, L1 and
|
||||
* L2 are custom layers with L0 as their parent. Now suppose that L3 is
|
||||
* <p> Service loaders created to locate providers in a {@linkplain ModuleLayer
|
||||
* module layer} will first locate providers in the layer, before locating
|
||||
* providers in parent layers. Traversal of parent layers is depth-first with
|
||||
* each layer visited at most once. For example, suppose L0 is the boot layer,
|
||||
* L1 and L2 are custom layers with L0 as their parent. Now suppose that L3 is
|
||||
* created with L1 and L2 as the parents (in that order). Using a service
|
||||
* loader to locate providers with L3 as the content will locate providers
|
||||
* in the following order: L3, L1, L0, L2. The ordering of modules in a layer
|
||||
@ -352,12 +349,12 @@ public final class ServiceLoader<S>
|
||||
// The class of the service type
|
||||
private final String serviceName;
|
||||
|
||||
// The module Layer used to locate providers; null when locating
|
||||
// The module layer used to locate providers; null when locating
|
||||
// providers using a class loader
|
||||
private final Layer layer;
|
||||
private final ModuleLayer layer;
|
||||
|
||||
// The class loader used to locate, load, and instantiate providers;
|
||||
// null when locating provider using a module Layer
|
||||
// null when locating provider using a module layer
|
||||
private final ClassLoader loader;
|
||||
|
||||
// The access control context taken when the ServiceLoader is created
|
||||
@ -376,10 +373,8 @@ public final class ServiceLoader<S>
|
||||
private int reloadCount;
|
||||
|
||||
private static JavaLangAccess LANG_ACCESS;
|
||||
private static JavaLangReflectModuleAccess JLRM_ACCESS;
|
||||
static {
|
||||
LANG_ACCESS = SharedSecrets.getJavaLangAccess();
|
||||
JLRM_ACCESS = SharedSecrets.getJavaLangReflectModuleAccess();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -425,13 +420,13 @@ public final class ServiceLoader<S>
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this class for locating service providers
|
||||
* in a module Layer.
|
||||
* in a module layer.
|
||||
*
|
||||
* @throws ServiceConfigurationError
|
||||
* If {@code svc} is not accessible to {@code caller} or the caller
|
||||
* module does not use the service type.
|
||||
*/
|
||||
private ServiceLoader(Class<?> caller, Layer layer, Class<S> svc) {
|
||||
private ServiceLoader(Class<?> caller, ModuleLayer layer, Class<S> svc) {
|
||||
Objects.requireNonNull(caller);
|
||||
Objects.requireNonNull(layer);
|
||||
Objects.requireNonNull(svc);
|
||||
@ -512,12 +507,15 @@ public final class ServiceLoader<S>
|
||||
|
||||
/**
|
||||
* Checks that the given service type is accessible to types in the given
|
||||
* module, and check that the module declare that it uses the service type. ??
|
||||
* module, and check that the module declares that it uses the service type.
|
||||
*/
|
||||
private static void checkCaller(Class<?> caller, Class<?> svc) {
|
||||
Module callerModule = caller.getModule();
|
||||
if (caller == null) {
|
||||
fail(svc, "no caller to check if it declares `uses`");
|
||||
}
|
||||
|
||||
// Check access to the service type
|
||||
Module callerModule = caller.getModule();
|
||||
int mods = svc.getModifiers();
|
||||
if (!Reflection.verifyMemberAccess(caller, svc, null, mods)) {
|
||||
fail(svc, "service type not accessible to " + callerModule);
|
||||
@ -826,13 +824,13 @@ public final class ServiceLoader<S>
|
||||
|
||||
/**
|
||||
* Implements lazy service provider lookup of service providers that
|
||||
* are provided by modules in a module Layer (or parent layers)
|
||||
* are provided by modules in a module layer (or parent layers)
|
||||
*/
|
||||
private final class LayerLookupIterator<T>
|
||||
implements Iterator<Provider<T>>
|
||||
{
|
||||
Deque<Layer> stack = new ArrayDeque<>();
|
||||
Set<Layer> visited = new HashSet<>();
|
||||
Deque<ModuleLayer> stack = new ArrayDeque<>();
|
||||
Set<ModuleLayer> visited = new HashSet<>();
|
||||
Iterator<ServiceProvider> iterator;
|
||||
ServiceProvider next; // next provider to load
|
||||
|
||||
@ -841,8 +839,8 @@ public final class ServiceLoader<S>
|
||||
stack.push(layer);
|
||||
}
|
||||
|
||||
private Iterator<ServiceProvider> providers(Layer layer) {
|
||||
ServicesCatalog catalog = JLRM_ACCESS.getServicesCatalog(layer);
|
||||
private Iterator<ServiceProvider> providers(ModuleLayer layer) {
|
||||
ServicesCatalog catalog = LANG_ACCESS.getServicesCatalog(layer);
|
||||
return catalog.findServices(serviceName).iterator();
|
||||
}
|
||||
|
||||
@ -864,10 +862,10 @@ public final class ServiceLoader<S>
|
||||
if (stack.isEmpty())
|
||||
return false;
|
||||
|
||||
Layer layer = stack.pop();
|
||||
List<Layer> parents = layer.parents();
|
||||
ModuleLayer layer = stack.pop();
|
||||
List<ModuleLayer> parents = layer.parents();
|
||||
for (int i = parents.size() - 1; i >= 0; i--) {
|
||||
Layer parent = parents.get(i);
|
||||
ModuleLayer parent = parents.get(i);
|
||||
if (!visited.contains(parent)) {
|
||||
visited.add(parent);
|
||||
stack.push(parent);
|
||||
@ -915,8 +913,8 @@ public final class ServiceLoader<S>
|
||||
* Returns iterator to iterate over the implementations of {@code
|
||||
* service} in the given layer.
|
||||
*/
|
||||
private List<ServiceProvider> providers(Layer layer) {
|
||||
ServicesCatalog catalog = JLRM_ACCESS.getServicesCatalog(layer);
|
||||
private List<ServiceProvider> providers(ModuleLayer layer) {
|
||||
ServicesCatalog catalog = LANG_ACCESS.getServicesCatalog(layer);
|
||||
return catalog.findServices(serviceName);
|
||||
}
|
||||
|
||||
@ -946,10 +944,10 @@ public final class ServiceLoader<S>
|
||||
return providers.iterator();
|
||||
} else {
|
||||
List<ServiceProvider> allProviders = new ArrayList<>(providers);
|
||||
Layer bootLayer = Layer.boot();
|
||||
Iterator<Layer> iterator = JLRM_ACCESS.layers(loader).iterator();
|
||||
ModuleLayer bootLayer = ModuleLayer.boot();
|
||||
Iterator<ModuleLayer> iterator = LANG_ACCESS.layers(loader).iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Layer layer = iterator.next();
|
||||
ModuleLayer layer = iterator.next();
|
||||
if (layer != bootLayer) {
|
||||
allProviders.addAll(providers(layer));
|
||||
}
|
||||
@ -1535,7 +1533,7 @@ public final class ServiceLoader<S>
|
||||
|
||||
/**
|
||||
* Creates a new service loader for the given service type that loads
|
||||
* service providers from modules in the given {@code Layer} and its
|
||||
* service providers from modules in the given {@code ModuleLayer} and its
|
||||
* ancestors.
|
||||
*
|
||||
* @apiNote Unlike the other load methods defined here, the service type
|
||||
@ -1545,7 +1543,7 @@ public final class ServiceLoader<S>
|
||||
* @param <S> the class of the service type
|
||||
*
|
||||
* @param layer
|
||||
* The module Layer
|
||||
* The module layer
|
||||
*
|
||||
* @param service
|
||||
* The interface or abstract class representing the service
|
||||
@ -1561,7 +1559,7 @@ public final class ServiceLoader<S>
|
||||
* @spec JPMS
|
||||
*/
|
||||
@CallerSensitive
|
||||
public static <S> ServiceLoader<S> load(Layer layer, Class<S> service) {
|
||||
public static <S> ServiceLoader<S> load(ModuleLayer layer, Class<S> service) {
|
||||
return new ServiceLoader<>(Reflection.getCallerClass(), layer, service);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2008, 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
|
||||
@ -108,6 +108,7 @@ public class Timer {
|
||||
* finalizer forgetting to call it.
|
||||
*/
|
||||
private final Object threadReaper = new Object() {
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() throws Throwable {
|
||||
synchronized(queue) {
|
||||
thread.newTasksMayBeScheduled = false;
|
||||
|
@ -713,6 +713,7 @@ public class Executors {
|
||||
FinalizableDelegatedExecutorService(ExecutorService executor) {
|
||||
super(executor);
|
||||
}
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() {
|
||||
super.shutdown();
|
||||
}
|
||||
|
@ -1490,7 +1490,17 @@ public class ThreadPoolExecutor extends AbstractExecutorService {
|
||||
/**
|
||||
* Invokes {@code shutdown} when this executor is no longer
|
||||
* referenced and it has no threads.
|
||||
*
|
||||
* @deprecated The {@code finalize} method has been deprecated.
|
||||
* Subclasses that override {@code finalize} in order to perform cleanup
|
||||
* should be modified to use alternative cleanup mechanisms and
|
||||
* to remove the overriding {@code finalize} method.
|
||||
* When overriding the {@code finalize} method, its implementation must explicitly
|
||||
* ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
|
||||
* See the specification for {@link Object#finalize()} for further
|
||||
* information about migration options.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
protected void finalize() {
|
||||
shutdown();
|
||||
}
|
||||
|
@ -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
|
||||
@ -452,13 +452,13 @@ public abstract class Pack200 {
|
||||
String CODE_ATTRIBUTE_PFX = "pack.code.attribute.";
|
||||
|
||||
/**
|
||||
* The unpacker's progress as a percentage, as periodically
|
||||
* updated by the unpacker.
|
||||
* The packer's progress as a percentage, as periodically
|
||||
* updated by the packer.
|
||||
* Values of 0 - 100 are normal, and -1 indicates a stall.
|
||||
* Progress can be monitored by polling the value of this
|
||||
* property.
|
||||
* <p>
|
||||
* At a minimum, the unpacker must set progress to 0
|
||||
* At a minimum, the packer must set progress to 0
|
||||
* at the beginning of a packing operation, and to 100
|
||||
* at the end.
|
||||
*/
|
||||
@ -623,7 +623,7 @@ public abstract class Pack200 {
|
||||
* property.
|
||||
* <p>
|
||||
* At a minimum, the unpacker must set progress to 0
|
||||
* at the beginning of a packing operation, and to 100
|
||||
* at the beginning of an unpacking operation, and to 100
|
||||
* at the end.
|
||||
*/
|
||||
String PROGRESS = "unpack.progress";
|
||||
@ -631,7 +631,7 @@ public abstract class Pack200 {
|
||||
/**
|
||||
* Get the set of this engine's properties. This set is
|
||||
* a "live view", so that changing its
|
||||
* contents immediately affects the Packer engine, and
|
||||
* contents immediately affects the Unpacker engine, and
|
||||
* changes from the engine (such as progress indications)
|
||||
* are immediately visible in the map.
|
||||
*
|
||||
|
@ -31,7 +31,6 @@ import jdk.internal.misc.SharedSecrets;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.reflect.Module;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Locale;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, 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
|
||||
@ -551,7 +551,17 @@ class Deflater {
|
||||
|
||||
/**
|
||||
* Closes the compressor when garbage is collected.
|
||||
*
|
||||
* @deprecated The {@code finalize} method has been deprecated.
|
||||
* Subclasses that override {@code finalize} in order to perform cleanup
|
||||
* should be modified to use alternative cleanup mechanisms and
|
||||
* to remove the overriding {@code finalize} method.
|
||||
* When overriding the {@code finalize} method, its implementation must explicitly
|
||||
* ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
|
||||
* See the specification for {@link Object#finalize()} for further
|
||||
* information about migration options.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
protected void finalize() {
|
||||
end();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, 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
|
||||
@ -378,7 +378,17 @@ class Inflater {
|
||||
|
||||
/**
|
||||
* Closes the decompressor when garbage is collected.
|
||||
*
|
||||
* @deprecated The {@code finalize} method has been deprecated.
|
||||
* Subclasses that override {@code finalize} in order to perform cleanup
|
||||
* should be modified to use alternative cleanup mechanisms and
|
||||
* to remove the overriding {@code finalize} method.
|
||||
* When overriding the {@code finalize} method, its implementation must explicitly
|
||||
* ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
|
||||
* See the specification for {@link Object#finalize()} for further
|
||||
* information about migration options.
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
protected void finalize() {
|
||||
end();
|
||||
}
|
||||
|
@ -420,6 +420,7 @@ class ZipFile implements ZipConstants, Closeable {
|
||||
Integer.MAX_VALUE : (int) avail);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() throws Throwable {
|
||||
close();
|
||||
}
|
||||
@ -641,9 +642,18 @@ class ZipFile implements ZipConstants, Closeable {
|
||||
* This will prevent holding up system resources for an undetermined
|
||||
* length of time.
|
||||
*
|
||||
* @deprecated The {@code finalize} method has been deprecated.
|
||||
* Subclasses that override {@code finalize} in order to perform cleanup
|
||||
* should be modified to use alternative cleanup mechanisms and
|
||||
* to remove the overriding {@code finalize} method.
|
||||
* When overriding the {@code finalize} method, its implementation must explicitly
|
||||
* ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.
|
||||
* See the specification for {@link Object#finalize()} for further
|
||||
* information about migration options.
|
||||
* @throws IOException if an I/O error has occurred
|
||||
* @see java.util.zip.ZipFile#close()
|
||||
*/
|
||||
@Deprecated(since="9")
|
||||
protected void finalize() throws IOException {
|
||||
close();
|
||||
}
|
||||
@ -813,6 +823,7 @@ class ZipFile implements ZipConstants, Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() {
|
||||
close();
|
||||
}
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package javax.crypto;
|
||||
|
||||
import java.lang.reflect.Module;
|
||||
import java.security.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 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
|
||||
@ -106,6 +106,7 @@ class JrtFileSystem extends FileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
cleanup();
|
||||
|
@ -27,8 +27,6 @@ package jdk.internal.loader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
@ -62,8 +60,7 @@ public class BootLoader {
|
||||
private static final String JAVA_HOME = System.getProperty("java.home");
|
||||
|
||||
static {
|
||||
UNNAMED_MODULE
|
||||
= SharedSecrets.getJavaLangReflectModuleAccess().defineUnnamedModule(null);
|
||||
UNNAMED_MODULE = SharedSecrets.getJavaLangAccess().defineUnnamedModule(null);
|
||||
setBootLoaderUnnamedModule0(UNNAMED_MODULE);
|
||||
}
|
||||
|
||||
@ -255,7 +252,7 @@ public class BootLoader {
|
||||
|
||||
if (mn != null) {
|
||||
// named module from runtime image or exploded module
|
||||
Optional<Module> om = Layer.boot().findModule(mn);
|
||||
Optional<Module> om = ModuleLayer.boot().findModule(mn);
|
||||
if (!om.isPresent())
|
||||
throw new InternalError(mn + " not in boot layer");
|
||||
return om.get();
|
||||
|
@ -27,7 +27,6 @@ package jdk.internal.loader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.URL;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Paths;
|
||||
|
@ -33,7 +33,6 @@ import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleReader;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.lang.module.ResolvedModule;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
@ -80,8 +79,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 Layer#defineModulesWithOneLoader
|
||||
* @see Layer#defineModulesWithManyLoaders
|
||||
* @see ModuleModuleLayer#defineModulesWithOneLoader
|
||||
* @see ModuleModuleLayer#defineModulesWithManyLoaders
|
||||
*/
|
||||
|
||||
public final class Loader extends SecureClassLoader {
|
||||
@ -207,10 +206,10 @@ public final class Loader extends SecureClassLoader {
|
||||
* @param cf the Configuration containing at least modules to be defined to
|
||||
* this class loader
|
||||
*
|
||||
* @param parentLayers the parent Layers
|
||||
* @param parentModuleLayers the parent ModuleLayers
|
||||
*/
|
||||
public Loader initRemotePackageMap(Configuration cf,
|
||||
List<Layer> parentLayers)
|
||||
List<ModuleLayer> parentModuleLayers)
|
||||
{
|
||||
for (String name : nameToModule.keySet()) {
|
||||
ResolvedModule resolvedModule = cf.findModule(name).get();
|
||||
@ -236,8 +235,8 @@ public final class Loader extends SecureClassLoader {
|
||||
} else {
|
||||
|
||||
// find the layer for the target module
|
||||
Layer layer = parentLayers.stream()
|
||||
.map(parent -> findLayer(parent, other.configuration()))
|
||||
ModuleLayer layer = parentModuleLayers.stream()
|
||||
.map(parent -> findModuleLayer(parent, other.configuration()))
|
||||
.flatMap(Optional::stream)
|
||||
.findAny()
|
||||
.orElseThrow(() ->
|
||||
@ -286,8 +285,8 @@ public final class Loader extends SecureClassLoader {
|
||||
* Find the layer corresponding to the given configuration in the tree
|
||||
* of layers rooted at the given parent.
|
||||
*/
|
||||
private Optional<Layer> findLayer(Layer parent, Configuration cf) {
|
||||
return SharedSecrets.getJavaLangReflectModuleAccess().layers(parent)
|
||||
private Optional<ModuleLayer> findModuleLayer(ModuleLayer parent, Configuration cf) {
|
||||
return SharedSecrets.getJavaLangAccess().layers(parent)
|
||||
.filter(l -> l.configuration() == cf)
|
||||
.findAny();
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ package jdk.internal.loader;
|
||||
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ResolvedModule;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -36,7 +35,7 @@ import java.util.stream.Stream;
|
||||
/**
|
||||
* A pool of class loaders.
|
||||
*
|
||||
* @see Layer#defineModulesWithManyLoaders
|
||||
* @see ModuleLayer#defineModulesWithManyLoaders
|
||||
*/
|
||||
|
||||
public final class LoaderPool {
|
||||
@ -51,7 +50,7 @@ public final class LoaderPool {
|
||||
* created with the given parent class loader as its parent.
|
||||
*/
|
||||
public LoaderPool(Configuration cf,
|
||||
List<Layer> parentLayers,
|
||||
List<ModuleLayer> parentLayers,
|
||||
ClassLoader parentLoader)
|
||||
{
|
||||
Map<String, Loader> loaders = new HashMap<>();
|
||||
|
@ -30,10 +30,10 @@ import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.Objects;
|
||||
import java.lang.System.LoggerFinder;
|
||||
import java.lang.System.Logger;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.reflect.Module;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Collection;
|
||||
@ -155,6 +155,8 @@ public class DefaultLoggerFinder extends LoggerFinder {
|
||||
|
||||
@Override
|
||||
public final Logger getLogger(String name, Module module) {
|
||||
Objects.requireNonNull(name, "name");
|
||||
Objects.requireNonNull(module, "module");
|
||||
checkPermission();
|
||||
return demandLoggerFor(name, module);
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ import java.util.function.BiFunction;
|
||||
import java.lang.System.LoggerFinder;
|
||||
import java.lang.System.Logger;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Module;
|
||||
import java.util.Objects;
|
||||
import jdk.internal.misc.VM;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
@ -402,10 +401,10 @@ public final class LazyLoggers {
|
||||
* @param module The module on behalf of which the logger is created.
|
||||
* If the module is not loaded from the Boot ClassLoader,
|
||||
* the LoggerFinder is accessed and the logger returned
|
||||
* by {@link LoggerFinder#getLogger(java.lang.String, java.lang.reflect.Module)}
|
||||
* by {@link LoggerFinder#getLogger(java.lang.String, java.lang.Module)}
|
||||
* is returned to the caller directly.
|
||||
* Otherwise, the logger returned by
|
||||
* {@link #getLazyLogger(java.lang.String, java.lang.reflect.Module)}
|
||||
* {@link #getLazyLogger(java.lang.String, java.lang.Module)}
|
||||
* is returned to the caller.
|
||||
*
|
||||
* @return a (possibly lazy) Logger instance.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, 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
|
||||
@ -27,10 +27,10 @@ package jdk.internal.misc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.ProtectionDomain;
|
||||
@ -38,6 +38,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.module.ServicesCatalog;
|
||||
import jdk.internal.reflect.ConstantPool;
|
||||
import sun.reflect.annotation.AnnotationType;
|
||||
import sun.nio.ch.Interruptible;
|
||||
@ -139,11 +140,6 @@ public interface JavaLangAccess {
|
||||
*/
|
||||
void invokeFinalize(Object o) throws Throwable;
|
||||
|
||||
/**
|
||||
* Returns the boot Layer
|
||||
*/
|
||||
Layer getBootLayer();
|
||||
|
||||
/**
|
||||
* Returns the ConcurrentHashMap used as a storage for ClassLoaderValue(s)
|
||||
* associated with the given class loader, creating it if it doesn't already exist.
|
||||
@ -185,4 +181,74 @@ public interface JavaLangAccess {
|
||||
* Invalidate package access cache
|
||||
*/
|
||||
void invalidatePackageAccessCache();
|
||||
|
||||
/**
|
||||
* Defines a new module to the Java virtual machine. The module
|
||||
* is defined to the given class loader.
|
||||
*
|
||||
* The URI is for information purposes only, it can be {@code null}.
|
||||
*/
|
||||
Module defineModule(ClassLoader loader, ModuleDescriptor descriptor, URI uri);
|
||||
|
||||
/**
|
||||
* Defines the unnamed module for the given class loader.
|
||||
*/
|
||||
Module defineUnnamedModule(ClassLoader loader);
|
||||
|
||||
/**
|
||||
* Updates the readability so that module m1 reads m2. The new read edge
|
||||
* does not result in a strong reference to m2 (m2 can be GC'ed).
|
||||
*
|
||||
* This method is the same as m1.addReads(m2) but without a permission check.
|
||||
*/
|
||||
void addReads(Module m1, Module m2);
|
||||
|
||||
/**
|
||||
* Updates module m to read all unnamed modules.
|
||||
*/
|
||||
void addReadsAllUnnamed(Module m);
|
||||
|
||||
/**
|
||||
* Updates module m1 to export a package to module m2. The export does
|
||||
* not result in a strong reference to m2 (m2 can be GC'ed).
|
||||
*/
|
||||
void addExports(Module m1, String pkg, Module m2);
|
||||
|
||||
/**
|
||||
* Updates a module m to export a package to all unnamed modules.
|
||||
*/
|
||||
void addExportsToAllUnnamed(Module m, String pkg);
|
||||
|
||||
/**
|
||||
* Updates module m1 to open a package to module m2. Opening the
|
||||
* package does not result in a strong reference to m2 (m2 can be GC'ed).
|
||||
*/
|
||||
void addOpens(Module m1, String pkg, Module m2);
|
||||
|
||||
/**
|
||||
* Updates a module m to open a package to all unnamed modules.
|
||||
*/
|
||||
void addOpensToAllUnnamed(Module m, String pkg);
|
||||
|
||||
/**
|
||||
* Updates a module m to use a service.
|
||||
*/
|
||||
void addUses(Module m, Class<?> service);
|
||||
|
||||
/**
|
||||
* Returns the ServicesCatalog for the given Layer.
|
||||
*/
|
||||
ServicesCatalog getServicesCatalog(ModuleLayer layer);
|
||||
|
||||
/**
|
||||
* Returns an ordered stream of layers. The first element is is the
|
||||
* given layer, the remaining elements are its parents, in DFS order.
|
||||
*/
|
||||
Stream<ModuleLayer> layers(ModuleLayer layer);
|
||||
|
||||
/**
|
||||
* Returns a stream of the layers that have modules defined to the
|
||||
* given class loader.
|
||||
*/
|
||||
Stream<ModuleLayer> layers(ClassLoader loader);
|
||||
}
|
||||
|
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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.misc;
|
||||
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.URI;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.module.ServicesCatalog;
|
||||
|
||||
/**
|
||||
* Provides access to non-public methods in java.lang.reflect.Module
|
||||
*/
|
||||
|
||||
public interface JavaLangReflectModuleAccess {
|
||||
|
||||
/**
|
||||
* Defines the unnamed module for the given class loader.
|
||||
*/
|
||||
Module defineUnnamedModule(ClassLoader loader);
|
||||
|
||||
/**
|
||||
* Defines a new module to the Java virtual machine. The module
|
||||
* is defined to the given class loader.
|
||||
*
|
||||
* The URI is for information purposes only, it can be {@code null}.
|
||||
*/
|
||||
Module defineModule(ClassLoader loader, ModuleDescriptor descriptor, URI uri);
|
||||
|
||||
/**
|
||||
* Updates the readability so that module m1 reads m2. The new read edge
|
||||
* does not result in a strong reference to m2 (m2 can be GC'ed).
|
||||
*
|
||||
* This method is the same as m1.addReads(m2) but without a permission check.
|
||||
*/
|
||||
void addReads(Module m1, Module m2);
|
||||
|
||||
/**
|
||||
* Updates module m to read all unnamed modules.
|
||||
*/
|
||||
void addReadsAllUnnamed(Module m);
|
||||
|
||||
/**
|
||||
* Update module m to export a package to all modules.
|
||||
*/
|
||||
void addExports(Module m, String pn);
|
||||
|
||||
/**
|
||||
* Updates module m1 to export a package to module m2. The export does
|
||||
* not result in a strong reference to m2 (m2 can be GC'ed).
|
||||
*/
|
||||
void addExports(Module m1, String pkg, Module m2);
|
||||
|
||||
/**
|
||||
* Updates a module m to export a package to all unnamed modules.
|
||||
*/
|
||||
void addExportsToAllUnnamed(Module m, String pkg);
|
||||
|
||||
/**
|
||||
* Updates a module m to open a package to all modules.
|
||||
*/
|
||||
void addOpens(Module m, String pkg);
|
||||
|
||||
/**
|
||||
* Updates module m1 to open a package to module m2. Opening the
|
||||
* package does not result in a strong reference to m2 (m2 can be GC'ed).
|
||||
*/
|
||||
void addOpens(Module m1, String pkg, Module m2);
|
||||
|
||||
/**
|
||||
* Updates a module m to open a package to all unnamed modules.
|
||||
*/
|
||||
void addOpensToAllUnnamed(Module m, String pkg);
|
||||
|
||||
/**
|
||||
* Updates a module m to use a service.
|
||||
*/
|
||||
void addUses(Module m, Class<?> service);
|
||||
|
||||
/**
|
||||
* Returns the ServicesCatalog for the given Layer.
|
||||
*/
|
||||
ServicesCatalog getServicesCatalog(Layer layer);
|
||||
|
||||
/**
|
||||
* Returns an ordered stream of layers. The first element is is the
|
||||
* given layer, the remaining elements are its parents, in DFS order.
|
||||
*/
|
||||
Stream<Layer> layers(Layer layer);
|
||||
|
||||
/**
|
||||
* Returns a stream of the layers that have modules defined to the
|
||||
* given class loader.
|
||||
*/
|
||||
Stream<Layer> layers(ClassLoader loader);
|
||||
}
|
@ -25,7 +25,6 @@
|
||||
|
||||
package jdk.internal.misc;
|
||||
|
||||
import java.lang.reflect.Module;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
|
@ -50,7 +50,6 @@ public class SharedSecrets {
|
||||
private static JavaUtilJarAccess javaUtilJarAccess;
|
||||
private static JavaLangAccess javaLangAccess;
|
||||
private static JavaLangModuleAccess javaLangModuleAccess;
|
||||
private static JavaLangReflectModuleAccess javaLangReflectModuleAccess;
|
||||
private static JavaLangInvokeAccess javaLangInvokeAccess;
|
||||
private static JavaLangRefAccess javaLangRefAccess;
|
||||
private static JavaIOAccess javaIOAccess;
|
||||
@ -119,16 +118,6 @@ public class SharedSecrets {
|
||||
return javaLangModuleAccess;
|
||||
}
|
||||
|
||||
public static void setJavaLangReflectModuleAccess(JavaLangReflectModuleAccess jlrma) {
|
||||
javaLangReflectModuleAccess = jlrma;
|
||||
}
|
||||
|
||||
public static JavaLangReflectModuleAccess getJavaLangReflectModuleAccess() {
|
||||
if (javaLangReflectModuleAccess == null)
|
||||
unsafe.ensureClassInitialized(java.lang.reflect.Module.class);
|
||||
return javaLangReflectModuleAccess;
|
||||
}
|
||||
|
||||
public static void setJavaLangRefAccess(JavaLangRefAccess jlra) {
|
||||
javaLangRefAccess = jlra;
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ package jdk.internal.module;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.CodeSource;
|
||||
|
@ -32,9 +32,6 @@ import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.lang.module.ResolvedModule;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.LayerInstantiationException;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@ -61,7 +58,7 @@ import jdk.internal.perf.PerfCounter;
|
||||
* resolving a set of module names specified via the launcher (or equivalent)
|
||||
* -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 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.
|
||||
*/
|
||||
|
||||
@ -106,11 +103,11 @@ public final class ModuleBootstrap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the module system, returning the boot Layer.
|
||||
* Initialize the module system, returning the boot layer.
|
||||
*
|
||||
* @see java.lang.System#initPhase2()
|
||||
*/
|
||||
public static Layer boot() {
|
||||
public static ModuleLayer boot() {
|
||||
|
||||
long t0 = System.nanoTime();
|
||||
|
||||
@ -237,7 +234,6 @@ public final class ModuleBootstrap {
|
||||
ModuleFinder f = finder; // observable modules
|
||||
systemModules.findAll()
|
||||
.stream()
|
||||
.filter(mref -> !ModuleResolution.doNotResolveByDefault(mref))
|
||||
.map(ModuleReference::descriptor)
|
||||
.map(ModuleDescriptor::name)
|
||||
.filter(mn -> f.find(mn).isPresent()) // observable
|
||||
@ -321,8 +317,7 @@ public final class ModuleBootstrap {
|
||||
if (SystemModules.hasSplitPackages() || needPostResolutionChecks) {
|
||||
Map<String, String> packageToModule = new HashMap<>();
|
||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||
ModuleDescriptor descriptor =
|
||||
resolvedModule.reference().descriptor();
|
||||
ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
|
||||
String name = descriptor.name();
|
||||
for (String p : descriptor.packages()) {
|
||||
String other = packageToModule.putIfAbsent(p, name);
|
||||
@ -338,7 +333,7 @@ public final class ModuleBootstrap {
|
||||
long t4 = System.nanoTime();
|
||||
|
||||
// define modules to VM/runtime
|
||||
Layer bootLayer = Layer.empty().defineModules(cf, clf);
|
||||
ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
|
||||
|
||||
PerfCounters.layerCreateTime.addElapsedTimeFrom(t4);
|
||||
|
||||
@ -476,7 +471,7 @@ public final class ModuleBootstrap {
|
||||
* Process the --add-reads options to add any additional read edges that
|
||||
* are specified on the command-line.
|
||||
*/
|
||||
private static void addExtraReads(Layer bootLayer) {
|
||||
private static void addExtraReads(ModuleLayer bootLayer) {
|
||||
|
||||
// decode the command line options
|
||||
Map<String, List<String>> map = decode("jdk.module.addreads.");
|
||||
@ -514,7 +509,7 @@ 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(Layer bootLayer) {
|
||||
private static void addExtraExportsAndOpens(ModuleLayer bootLayer) {
|
||||
// --add-exports
|
||||
String prefix = "jdk.module.addexports.";
|
||||
Map<String, List<String>> extraExports = decode(prefix);
|
||||
@ -548,7 +543,7 @@ public final class ModuleBootstrap {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addExtraExportsOrOpens(Layer bootLayer,
|
||||
private static void addExtraExportsOrOpens(ModuleLayer bootLayer,
|
||||
Map<String, List<String>> map,
|
||||
boolean opens)
|
||||
{
|
||||
|
@ -135,8 +135,9 @@ public final class ModulePatcher {
|
||||
Path top = file;
|
||||
Files.find(top, Integer.MAX_VALUE,
|
||||
((path, attrs) -> attrs.isRegularFile()))
|
||||
.filter(path -> !isAutomatic
|
||||
.filter(path -> (!isAutomatic
|
||||
|| path.toString().endsWith(".class"))
|
||||
&& !isHidden(path))
|
||||
.map(path -> toPackageName(top, path))
|
||||
.filter(Checks::isPackageName)
|
||||
.forEach(packages::add);
|
||||
@ -177,11 +178,13 @@ public final class ModulePatcher {
|
||||
|
||||
ModuleTarget target = null;
|
||||
ModuleHashes recordedHashes = null;
|
||||
ModuleHashes.HashSupplier hasher = null;
|
||||
ModuleResolution mres = null;
|
||||
if (mref instanceof ModuleReferenceImpl) {
|
||||
ModuleReferenceImpl impl = (ModuleReferenceImpl)mref;
|
||||
target = impl.moduleTarget();
|
||||
recordedHashes = impl.recordedHashes();
|
||||
hasher = impl.hasher();
|
||||
mres = impl.moduleResolution();
|
||||
}
|
||||
|
||||
@ -191,7 +194,7 @@ public final class ModulePatcher {
|
||||
this,
|
||||
target,
|
||||
recordedHashes,
|
||||
null,
|
||||
hasher,
|
||||
mres);
|
||||
|
||||
}
|
||||
@ -556,7 +559,7 @@ public final class ModulePatcher {
|
||||
|
||||
|
||||
/**
|
||||
* Derives a package name from a file path to a .class file.
|
||||
* Derives a package name from the file path of an entry in an exploded patch
|
||||
*/
|
||||
private static String toPackageName(Path top, Path file) {
|
||||
Path entry = top.relativize(file);
|
||||
@ -568,6 +571,17 @@ public final class ModulePatcher {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given file exists and is a hidden file
|
||||
*/
|
||||
private boolean isHidden(Path file) {
|
||||
try {
|
||||
return Files.isHidden(file);
|
||||
} catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a package name from the name of an entry in a JAR file.
|
||||
*/
|
||||
|
@ -547,7 +547,6 @@ public class ModulePath implements ModuleFinder {
|
||||
*/
|
||||
private static class Patterns {
|
||||
static final Pattern DASH_VERSION = Pattern.compile("-(\\d+(\\.|$))");
|
||||
static final Pattern TRAILING_VERSION = Pattern.compile("(\\.|\\d)*$");
|
||||
static final Pattern NON_ALPHANUM = Pattern.compile("[^A-Za-z0-9]");
|
||||
static final Pattern REPEATING_DOTS = Pattern.compile("(\\.)(\\1)+");
|
||||
static final Pattern LEADING_DOTS = Pattern.compile("^\\.");
|
||||
@ -558,9 +557,6 @@ public class ModulePath implements ModuleFinder {
|
||||
* Clean up candidate module name derived from a JAR file name.
|
||||
*/
|
||||
private static String cleanModuleName(String mn) {
|
||||
// drop trailing version from name
|
||||
mn = Patterns.TRAILING_VERSION.matcher(mn).replaceAll("");
|
||||
|
||||
// replace non-alphanumeric
|
||||
mn = Patterns.NON_ALPHANUM.matcher(mn).replaceAll(".");
|
||||
|
||||
@ -630,7 +626,7 @@ public class ModulePath implements ModuleFinder {
|
||||
private Set<String> explodedPackages(Path dir) {
|
||||
try {
|
||||
return Files.find(dir, Integer.MAX_VALUE,
|
||||
((path, attrs) -> attrs.isRegularFile()))
|
||||
((path, attrs) -> attrs.isRegularFile() && !isHidden(path)))
|
||||
.map(path -> dir.relativize(path))
|
||||
.map(this::toPackageName)
|
||||
.flatMap(Optional::stream)
|
||||
@ -726,6 +722,17 @@ public class ModulePath implements ModuleFinder {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given file exists and is a hidden file
|
||||
*/
|
||||
private boolean isHidden(Path file) {
|
||||
try {
|
||||
return Files.isHidden(file);
|
||||
} catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final PerfCounter scanTime
|
||||
= PerfCounter.newPerfCounter("jdk.module.finder.modulepath.scanTime");
|
||||
private static final PerfCounter moduleCount
|
||||
|
@ -26,15 +26,13 @@
|
||||
package jdk.internal.module;
|
||||
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.Module;
|
||||
import java.net.URI;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import jdk.internal.loader.BootLoader;
|
||||
import jdk.internal.loader.ClassLoaders;
|
||||
import jdk.internal.misc.JavaLangReflectModuleAccess;
|
||||
import jdk.internal.misc.JavaLangAccess;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
@ -51,8 +49,7 @@ import jdk.internal.misc.SharedSecrets;
|
||||
public class Modules {
|
||||
private Modules() { }
|
||||
|
||||
private static final JavaLangReflectModuleAccess JLRMA
|
||||
= SharedSecrets.getJavaLangReflectModuleAccess();
|
||||
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
|
||||
|
||||
/**
|
||||
* Creates a new Module. The module has the given ModuleDescriptor and
|
||||
@ -67,7 +64,7 @@ public class Modules {
|
||||
ModuleDescriptor descriptor,
|
||||
URI uri)
|
||||
{
|
||||
return JLRMA.defineModule(loader, descriptor, uri);
|
||||
return JLA.defineModule(loader, descriptor, uri);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,23 +72,14 @@ public class Modules {
|
||||
* Same as m1.addReads(m2) but without a caller check.
|
||||
*/
|
||||
public static void addReads(Module m1, Module m2) {
|
||||
JLRMA.addReads(m1, m2);
|
||||
JLA.addReads(m1, m2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update module m to read all unnamed modules.
|
||||
*/
|
||||
public static void addReadsAllUnnamed(Module m) {
|
||||
JLRMA.addReadsAllUnnamed(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update module m to export a package to all modules.
|
||||
*
|
||||
* This method is for intended for use by tests only.
|
||||
*/
|
||||
public static void addExports(Module m, String pn) {
|
||||
JLRMA.addExports(m, pn);
|
||||
JLA.addReadsAllUnnamed(m);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,23 +87,14 @@ public class Modules {
|
||||
* Same as m1.addExports(pn, m2) but without a caller check
|
||||
*/
|
||||
public static void addExports(Module m1, String pn, Module m2) {
|
||||
JLRMA.addExports(m1, pn, m2);
|
||||
JLA.addExports(m1, pn, m2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates module m to export a package to all unnamed modules.
|
||||
*/
|
||||
public static void addExportsToAllUnnamed(Module m, String pn) {
|
||||
JLRMA.addExportsToAllUnnamed(m, pn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update module m to open a package to all modules.
|
||||
*
|
||||
* This method is for intended for use by tests only.
|
||||
*/
|
||||
public static void addOpens(Module m, String pn) {
|
||||
JLRMA.addOpens(m, pn);
|
||||
JLA.addExportsToAllUnnamed(m, pn);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,14 +102,14 @@ public class Modules {
|
||||
* Same as m1.addOpens(pn, m2) but without a caller check.
|
||||
*/
|
||||
public static void addOpens(Module m1, String pn, Module m2) {
|
||||
JLRMA.addOpens(m1, pn, m2);
|
||||
JLA.addOpens(m1, pn, m2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates module m to open a package to all unnamed modules.
|
||||
*/
|
||||
public static void addOpensToAllUnnamed(Module m, String pn) {
|
||||
JLRMA.addOpensToAllUnnamed(m, pn);
|
||||
JLA.addOpensToAllUnnamed(m, pn);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,16 +117,16 @@ public class Modules {
|
||||
* Same as m2.addUses(service) but without a caller check.
|
||||
*/
|
||||
public static void addUses(Module m, Class<?> service) {
|
||||
JLRMA.addUses(m, service);
|
||||
JLA.addUses(m, service);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates module m to provide a service
|
||||
*/
|
||||
public static void addProvides(Module m, Class<?> service, Class<?> impl) {
|
||||
Layer layer = m.getLayer();
|
||||
ModuleLayer layer = m.getLayer();
|
||||
|
||||
if (layer == null || layer == Layer.boot()) {
|
||||
if (layer == null || layer == ModuleLayer.boot()) {
|
||||
// update ClassLoader catalog
|
||||
PrivilegedAction<ClassLoader> pa = m::getClassLoader;
|
||||
ClassLoader loader = AccessController.doPrivileged(pa);
|
||||
@ -162,9 +141,7 @@ public class Modules {
|
||||
|
||||
if (layer != null) {
|
||||
// update Layer catalog
|
||||
SharedSecrets.getJavaLangReflectModuleAccess()
|
||||
.getServicesCatalog(layer)
|
||||
.addProvider(m, service, impl);
|
||||
JLA.getServicesCatalog(layer).addProvider(m, service, impl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package jdk.internal.module;
|
||||
|
||||
import java.lang.reflect.Module;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleDescriptor.Provides;
|
||||
import java.util.ArrayList;
|
||||
|
@ -26,6 +26,7 @@
|
||||
/**
|
||||
* Defines the foundational APIs of the Java SE Platform.
|
||||
*
|
||||
* @moduleGraph
|
||||
* @since 9
|
||||
*/
|
||||
module java.base {
|
||||
|
@ -27,7 +27,6 @@ package sun.invoke.util;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import static java.lang.reflect.Modifier.*;
|
||||
import java.lang.reflect.Module;
|
||||
import java.util.Objects;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
|
||||
|
@ -50,10 +50,8 @@ import java.lang.module.ModuleDescriptor.Requires;
|
||||
import java.lang.module.ModuleDescriptor.Exports;
|
||||
import java.lang.module.ModuleDescriptor.Opens;
|
||||
import java.lang.module.ModuleDescriptor.Provides;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Module;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.URI;
|
||||
@ -467,7 +465,7 @@ public final class LauncherHelper {
|
||||
String mn = s[0];
|
||||
String pn = s[1];
|
||||
|
||||
Layer.boot().findModule(mn).ifPresent(m -> {
|
||||
ModuleLayer.boot().findModule(mn).ifPresent(m -> {
|
||||
if (m.getDescriptor().packages().contains(pn)) {
|
||||
if (open) {
|
||||
Modules.addOpensToAllUnnamed(m, pn);
|
||||
@ -564,7 +562,7 @@ public final class LauncherHelper {
|
||||
}
|
||||
|
||||
// main module is in the boot layer
|
||||
Layer layer = Layer.boot();
|
||||
ModuleLayer layer = ModuleLayer.boot();
|
||||
Optional<Module> om = layer.findModule(mainModule);
|
||||
if (!om.isPresent()) {
|
||||
// should not happen
|
||||
@ -854,7 +852,7 @@ public final class LauncherHelper {
|
||||
private static void setFXLaunchParameters(String what, int mode) {
|
||||
|
||||
// find the module with the FX launcher
|
||||
Optional<Module> om = Layer.boot().findModule(JAVAFX_GRAPHICS_MODULE_NAME);
|
||||
Optional<Module> om = ModuleLayer.boot().findModule(JAVAFX_GRAPHICS_MODULE_NAME);
|
||||
if (!om.isPresent()) {
|
||||
abort(null, "java.launcher.cls.error5");
|
||||
}
|
||||
@ -938,8 +936,7 @@ public final class LauncherHelper {
|
||||
* Called by the launcher to list the observable modules.
|
||||
* If called without any sub-options then the output is a simple list of
|
||||
* the modules. If called with sub-options then the sub-options are the
|
||||
* names of the modules to list (-listmods:java.base,java.desktop for
|
||||
* example).
|
||||
* names of the modules to list (e.g. --list-modules java.base,java.desktop)
|
||||
*/
|
||||
static void listModules(boolean printToStderr, String optionFlag)
|
||||
throws IOException, ClassNotFoundException
|
||||
@ -947,89 +944,97 @@ public final class LauncherHelper {
|
||||
initOutput(printToStderr);
|
||||
|
||||
ModuleFinder finder = jdk.internal.module.ModuleBootstrap.finder();
|
||||
|
||||
int colon = optionFlag.indexOf('=');
|
||||
if (colon == -1) {
|
||||
finder.findAll().stream()
|
||||
.sorted(Comparator.comparing(ModuleReference::descriptor))
|
||||
.forEach(md -> {
|
||||
ostream.println(midAndLocation(md.descriptor(),
|
||||
md.location()));
|
||||
});
|
||||
.sorted(Comparator.comparing(ModuleReference::descriptor))
|
||||
.forEach(mref -> describeModule(finder, mref, false));
|
||||
} else {
|
||||
String[] names = optionFlag.substring(colon+1).split(",");
|
||||
for (String name: names) {
|
||||
ModuleReference mref = finder.find(name).orElse(null);
|
||||
if (mref == null) {
|
||||
System.err.format("%s not observable!%n", name);
|
||||
System.err.format("%s not found%n", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
ModuleDescriptor md = mref.descriptor();
|
||||
if (md.isOpen())
|
||||
ostream.print("open ");
|
||||
if (md.isAutomatic())
|
||||
ostream.print("automatic ");
|
||||
if (md.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC))
|
||||
ostream.print("synthetic ");
|
||||
if (md.modifiers().contains(ModuleDescriptor.Modifier.MANDATED))
|
||||
ostream.print("mandated ");
|
||||
ostream.println("module " + midAndLocation(md, mref.location()));
|
||||
|
||||
// unqualified exports (sorted by package)
|
||||
Set<Exports> exports = new TreeSet<>(Comparator.comparing(Exports::source));
|
||||
md.exports().stream().filter(e -> !e.isQualified()).forEach(exports::add);
|
||||
for (Exports e : exports) {
|
||||
String modsAndSource = Stream.concat(toStringStream(e.modifiers()),
|
||||
Stream.of(e.source()))
|
||||
.collect(Collectors.joining(" "));
|
||||
ostream.format(" exports %s%n", modsAndSource);
|
||||
}
|
||||
|
||||
for (Requires d : md.requires()) {
|
||||
ostream.format(" requires %s%n", d);
|
||||
}
|
||||
for (String s : md.uses()) {
|
||||
ostream.format(" uses %s%n", s);
|
||||
}
|
||||
|
||||
for (Provides ps : md.provides()) {
|
||||
ostream.format(" provides %s with %s%n", ps.service(),
|
||||
ps.providers().stream().collect(Collectors.joining(", ")));
|
||||
}
|
||||
|
||||
// qualified exports
|
||||
for (Exports e : md.exports()) {
|
||||
if (e.isQualified()) {
|
||||
String modsAndSource = Stream.concat(toStringStream(e.modifiers()),
|
||||
Stream.of(e.source()))
|
||||
.collect(Collectors.joining(" "));
|
||||
ostream.format(" exports %s", modsAndSource);
|
||||
formatCommaList(ostream, " to", e.targets());
|
||||
}
|
||||
}
|
||||
|
||||
// open packages
|
||||
for (Opens obj: md.opens()) {
|
||||
String modsAndSource = Stream.concat(toStringStream(obj.modifiers()),
|
||||
Stream.of(obj.source()))
|
||||
.collect(Collectors.joining(" "));
|
||||
ostream.format(" opens %s", modsAndSource);
|
||||
if (obj.isQualified())
|
||||
formatCommaList(ostream, " to", obj.targets());
|
||||
else
|
||||
ostream.println();
|
||||
}
|
||||
|
||||
// non-exported/non-open packages
|
||||
Set<String> concealed = new TreeSet<>(md.packages());
|
||||
md.exports().stream().map(Exports::source).forEach(concealed::remove);
|
||||
md.opens().stream().map(Opens::source).forEach(concealed::remove);
|
||||
concealed.forEach(p -> ostream.format(" contains %s%n", p));
|
||||
describeModule(finder, mref, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the given module.
|
||||
*/
|
||||
static void describeModule(ModuleFinder finder,
|
||||
ModuleReference mref,
|
||||
boolean verbose)
|
||||
{
|
||||
ModuleDescriptor md = mref.descriptor();
|
||||
ostream.print("module " + midAndLocation(md, mref.location()));
|
||||
if (md.isAutomatic())
|
||||
ostream.print(" automatic");
|
||||
ostream.println();
|
||||
|
||||
if (!verbose)
|
||||
return;
|
||||
|
||||
// unqualified exports (sorted by package)
|
||||
Set<Exports> exports = new TreeSet<>(Comparator.comparing(Exports::source));
|
||||
md.exports().stream().filter(e -> !e.isQualified()).forEach(exports::add);
|
||||
for (Exports e : exports) {
|
||||
String modsAndSource = Stream.concat(toStringStream(e.modifiers()),
|
||||
Stream.of(e.source()))
|
||||
.collect(Collectors.joining(" "));
|
||||
ostream.format(" exports %s%n", modsAndSource);
|
||||
}
|
||||
|
||||
for (Requires d : md.requires()) {
|
||||
ostream.format(" requires %s", d);
|
||||
String suffix = finder.find(d.name())
|
||||
.map(ModuleReference::descriptor)
|
||||
.map(any -> any.isAutomatic() ? " automatic" : "")
|
||||
.orElse(" not found");
|
||||
ostream.println(suffix);
|
||||
}
|
||||
for (String s : md.uses()) {
|
||||
ostream.format(" uses %s%n", s);
|
||||
}
|
||||
|
||||
for (Provides ps : md.provides()) {
|
||||
ostream.format(" provides %s with %s%n", ps.service(),
|
||||
ps.providers().stream().collect(Collectors.joining(", ")));
|
||||
}
|
||||
|
||||
// qualified exports
|
||||
for (Exports e : md.exports()) {
|
||||
if (e.isQualified()) {
|
||||
String modsAndSource = Stream.concat(toStringStream(e.modifiers()),
|
||||
Stream.of(e.source()))
|
||||
.collect(Collectors.joining(" "));
|
||||
ostream.format(" exports %s", modsAndSource);
|
||||
formatCommaList(ostream, " to", e.targets());
|
||||
}
|
||||
}
|
||||
|
||||
// open packages
|
||||
for (Opens obj: md.opens()) {
|
||||
String modsAndSource = Stream.concat(toStringStream(obj.modifiers()),
|
||||
Stream.of(obj.source()))
|
||||
.collect(Collectors.joining(" "));
|
||||
ostream.format(" opens %s", modsAndSource);
|
||||
if (obj.isQualified())
|
||||
formatCommaList(ostream, " to", obj.targets());
|
||||
else
|
||||
ostream.println();
|
||||
}
|
||||
|
||||
// non-exported/non-open packages
|
||||
Set<String> concealed = new TreeSet<>(md.packages());
|
||||
md.exports().stream().map(Exports::source).forEach(concealed::remove);
|
||||
md.opens().stream().map(Opens::source).forEach(concealed::remove);
|
||||
concealed.forEach(p -> ostream.format(" contains %s%n", p));
|
||||
}
|
||||
|
||||
static <T> String toString(Set<T> s) {
|
||||
return toStringStream(s).collect(Collectors.joining(" "));
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ java.launcher.opt.vmselect =\ {0}\t to select the "{1}" VM\n
|
||||
java.launcher.opt.hotspot =\ {0}\t is a synonym for the "{1}" VM [deprecated]\n
|
||||
|
||||
# Translators please note do not translate the options themselves
|
||||
java.launcher.opt.footer =\ -cp <class search path of directories and zip/jar files>\n\
|
||||
java.launcher.opt.footer = \
|
||||
\ -cp <class search path of directories and zip/jar files>\n\
|
||||
\ -classpath <class search path of directories and zip/jar files>\n\
|
||||
\ --class-path <class search path of directories and zip/jar files>\n\
|
||||
\ A {0} separated list of directories, JAR archives,\n\
|
||||
@ -101,8 +102,11 @@ java.launcher.opt.footer =\ -cp <class search path of directories and zip
|
||||
\ should always be passed as the argument to the -splash option.\n\
|
||||
\ The most appropriate scaled image provided will be picked up\n\
|
||||
\ automatically.\n\
|
||||
\ See the SplashScreen API documentation for more information.\n\
|
||||
\ @<filepath> read options from the specified file\n\n\
|
||||
\ See the SplashScreen API documentation for more information\n\
|
||||
\ @argument files\n\
|
||||
\ one or more argument files containing options\n\
|
||||
\ -disable-@files\n\
|
||||
\ prevent further argument file expansion\n\
|
||||
\To specify an argument for a long option, you can use --<name>=<value> or\n\
|
||||
\--<name> <value>.\n
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 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
|
||||
@ -203,6 +203,7 @@ public class MeteredStream extends FilterInputStream {
|
||||
return super.markSupported();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
close();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2005, 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
|
||||
@ -77,6 +77,7 @@ public class DelegateHttpsURLConnection extends AbstractDelegateHttpsURLConnecti
|
||||
* Called by layered delegator's finalize() method to handle closing
|
||||
* the underlying object.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void dispose() throws Throwable {
|
||||
super.finalize();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2016, 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
|
||||
@ -478,6 +478,7 @@ public class HttpsURLConnectionImpl
|
||||
* sun.net.www.protocol.http.HttpURLConnection's finalize()
|
||||
* would have to be made public.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() throws Throwable {
|
||||
delegate.dispose();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2016, 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
|
||||
@ -1034,6 +1034,7 @@ class DatagramChannelImpl
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() throws IOException {
|
||||
// fd is null if constructor threw exception
|
||||
if (fd != null)
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
package sun.reflect.misc;
|
||||
|
||||
import java.lang.reflect.Module;
|
||||
import java.io.EOFException;
|
||||
import java.security.AllPermission;
|
||||
import java.security.AccessController;
|
||||
|
@ -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
|
||||
@ -147,6 +147,7 @@ final class KeyProtector {
|
||||
* Ensures that the password bytes of this key protector are
|
||||
* set to zero when there are no more references to it.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() {
|
||||
if (passwdBytes != null) {
|
||||
Arrays.fill(passwdBytes, (byte)0x00);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 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
|
||||
@ -265,6 +265,7 @@ abstract class BaseSSLSocketImpl extends SSLSocket {
|
||||
* the penalty of prematurly killing SSL sessions.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
protected final void finalize() throws Throwable {
|
||||
try {
|
||||
close();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user