Merge
This commit is contained in:
commit
58b8478bb6
@ -391,3 +391,4 @@ efa71dc820eb8bd5a6c9f2f66f39c383ac3ee99d jdk-9+144
|
||||
6e4ff59afb5d0adf21a72c4ff534326594a99e5d jdk-9+146
|
||||
c41140100bf1e5c10c7b8f3bde91c16eff7485f5 jdk-9+147
|
||||
9098b2b9d997d65af0026fc2f39cf75234e26bc5 jdk-9+148
|
||||
5a846396a24c7aff01d6a8feaa7afc0a6369f04d jdk-9+149
|
||||
|
@ -100,8 +100,7 @@ else
|
||||
# Allow override by ALT_JVMCFG_SRC if it exists
|
||||
JVMCFG_SRC := $(if $(wildcard $(ALT_JVMCFG_SRC)),$(ALT_JVMCFG_SRC),$(JVMCFG_SRC))
|
||||
endif
|
||||
JVMCFG_DIR := $(LIB_DST_DIR)$(OPENJDK_TARGET_CPU_LIBDIR)
|
||||
JVMCFG := $(JVMCFG_DIR)/jvm.cfg
|
||||
JVMCFG := $(LIB_DST_DIR)/jvm.cfg
|
||||
|
||||
# To do: should this also support -zeroshark?
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
# 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
|
||||
@ -64,7 +64,7 @@ ifneq ($(FREETYPE_BUNDLE_LIB_PATH), )
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
FREETYPE_TARGET_LIB := $(LIB_DST_DIR)/$(call SHARED_LIBRARY,freetype)
|
||||
else
|
||||
FREETYPE_TARGET_LIB := $(LIB_DST_DIR)$(OPENJDK_TARGET_CPU_LIBDIR)/$(call SHARED_LIBRARY,freetype).6
|
||||
FREETYPE_TARGET_LIB := $(LIB_DST_DIR)/$(call SHARED_LIBRARY,freetype).6
|
||||
endif
|
||||
|
||||
# We can't use $(install-file) in this rule because it preserves symbolic links and
|
||||
|
@ -30,7 +30,7 @@ include CopyCommon.gmk
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
|
||||
SUNPKCS11_CFG_SRC := \
|
||||
$(JDK_TOPDIR)/src/jdk.crypto.pkcs11/solaris/conf/security/sunpkcs11-solaris.cfg
|
||||
$(JDK_TOPDIR)/src/jdk.crypto.token/solaris/conf/security/sunpkcs11-solaris.cfg
|
||||
SUNPKCS11_CFG_DST := $(CONF_DST_DIR)/security/sunpkcs11-solaris.cfg
|
||||
|
||||
$(SUNPKCS11_CFG_DST): $(SUNPKCS11_CFG_SRC)
|
@ -74,7 +74,7 @@ $(eval $(call SetupBuildLauncher, keytool, \
|
||||
BUILD_JEXEC :=
|
||||
BUILD_JEXEC_SRC :=
|
||||
BUILD_JEXEC_INC :=
|
||||
BUILD_JEXEC_DST_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR)
|
||||
BUILD_JEXEC_DST_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base
|
||||
|
||||
#
|
||||
# UNHANDLED:
|
||||
@ -138,7 +138,7 @@ endif
|
||||
BUILD_JSPAWNHELPER :=
|
||||
BUILD_JSPAWNHELPER_SRC := $(JDK_TOPDIR)/src/java.base/unix/native/jspawnhelper
|
||||
JSPAWNHELPER_CFLAGS := -I$(JDK_TOPDIR)/src/java.base/unix/native/libjava
|
||||
BUILD_JSPAWNHELPER_DST_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR)
|
||||
BUILD_JSPAWNHELPER_DST_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base
|
||||
LINK_JSPAWNHELPER_OBJECTS := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjava/childproc.o
|
||||
BUILD_JSPAWNHELPER_LDFLAGS :=
|
||||
|
||||
|
37
jdk/make/launcher/Launcher-jdk.aot.gmk
Normal file
37
jdk/make/launcher/Launcher-jdk.aot.gmk
Normal file
@ -0,0 +1,37 @@
|
||||
#
|
||||
# Copyright (c) 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.
|
||||
#
|
||||
|
||||
include LauncherCommon.gmk
|
||||
|
||||
$(eval $(call SetupBuildLauncher, jaotc, \
|
||||
MAIN_CLASS := jdk.tools.jaotc.Main, \
|
||||
JAVA_ARGS := -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI \
|
||||
-XX:+UseAOT \
|
||||
-Djvmci.UseProfilingInformation=false \
|
||||
-Dgraal.UseExceptionProbability=false \
|
||||
-Djvmci.Compiler=graal \
|
||||
--add-modules ALL-DEFAULT \
|
||||
, \
|
||||
))
|
@ -34,9 +34,9 @@ $(eval $(call SetupBuildLauncher, pack200, \
|
||||
# The order of the object files on the link command line affects the size of the resulting
|
||||
# binary (at least on linux) which causes the size to differ between old and new build.
|
||||
|
||||
UNPACKEXE_SRC := $(JDK_TOPDIR)/src/jdk.pack200/share/native/common-unpack \
|
||||
$(JDK_TOPDIR)/src/jdk.pack200/share/native/unpack200
|
||||
UNPACKEXE_CFLAGS := -I$(JDK_TOPDIR)/src/jdk.pack200/share/native/common-unpack \
|
||||
UNPACKEXE_SRC := $(JDK_TOPDIR)/src/jdk.pack/share/native/common-unpack \
|
||||
$(JDK_TOPDIR)/src/jdk.pack/share/native/unpack200
|
||||
UNPACKEXE_CFLAGS := -I$(JDK_TOPDIR)/src/jdk.pack/share/native/common-unpack \
|
||||
-I$(JDK_TOPDIR)/src/java.base/share/native/libjava \
|
||||
-I$(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjava
|
||||
|
||||
@ -97,7 +97,7 @@ $(eval $(call SetupNativeCompilation,BUILD_UNPACKEXE, \
|
||||
-D "JDK_FNAME=unpack200.exe" \
|
||||
-D "JDK_INTERNAL_NAME=unpack200" \
|
||||
-D "JDK_FTYPE=0x1L", \
|
||||
MANIFEST := $(JDK_TOPDIR)/src/jdk.pack200/windows/native/unpack200/unpack200_proto.exe.manifest, \
|
||||
MANIFEST := $(JDK_TOPDIR)/src/jdk.pack/windows/native/unpack200/unpack200_proto.exe.manifest, \
|
||||
MANIFEST_VERSION := $(VERSION_NUMBER_FOUR_POSITIONS), \
|
||||
))
|
||||
|
@ -32,13 +32,13 @@ else
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
DISABLE_MAPFILES := true
|
||||
endif
|
||||
ORIGIN_ARG := $(call SET_EXECUTABLE_ORIGIN,/../lib$(OPENJDK_TARGET_CPU_LIBDIR)/jli)
|
||||
ORIGIN_ARG := $(call SET_EXECUTABLE_ORIGIN,/../lib/jli)
|
||||
|
||||
# Applications expect to be able to link against libjawt without invoking
|
||||
# System.loadLibrary("jawt") first. This was the behaviour described in the
|
||||
# devloper documentation of JAWT and what worked with OpenJDK6.
|
||||
ifneq ($(findstring $(OPENJDK_TARGET_OS), linux solaris), )
|
||||
ORIGIN_ARG += $(call SET_EXECUTABLE_ORIGIN,/../lib$(OPENJDK_TARGET_CPU_LIBDIR))
|
||||
ORIGIN_ARG += $(call SET_EXECUTABLE_ORIGIN,/../lib)
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -190,9 +190,9 @@ define SetupBuildLauncherBody
|
||||
$$(ORIGIN_ARG) \
|
||||
$$($1_LDFLAGS), \
|
||||
LDFLAGS_linux := \
|
||||
-L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR)/jli, \
|
||||
-L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base/jli, \
|
||||
LDFLAGS_solaris := $$($1_LDFLAGS_solaris) \
|
||||
-L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR)/jli, \
|
||||
-L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base/jli, \
|
||||
MAPFILE := $$($1_MAPFILE), \
|
||||
LIBS := $(JDKEXE_LIBS) $$($1_LIBS), \
|
||||
LIBS_unix := $$($1_LIBS_unix), \
|
||||
|
@ -340,9 +340,6 @@ endif
|
||||
|
||||
LIBJLI_CFLAGS += $(addprefix -I, $(LIBJLI_SRC_DIRS))
|
||||
|
||||
# Append defines depending on target platform
|
||||
LIBJLI_CFLAGS += $(OPENJDK_TARGET_CPU_JLI_CFLAGS)
|
||||
|
||||
ifneq ($(USE_EXTERNAL_LIBZ), true)
|
||||
LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS)
|
||||
LIBJLI_EXTRA_FILES += \
|
||||
|
@ -27,8 +27,8 @@ include LibCommon.gmk
|
||||
|
||||
################################################################################
|
||||
|
||||
LIBJ2PKCS11_SRC := $(JDK_TOPDIR)/src/jdk.crypto.pkcs11/share/native/libj2pkcs11 \
|
||||
$(JDK_TOPDIR)/src/jdk.crypto.pkcs11/$(OPENJDK_TARGET_OS_TYPE)/native/libj2pkcs11
|
||||
LIBJ2PKCS11_SRC := $(JDK_TOPDIR)/src/jdk.crypto.token/share/native/libj2pkcs11 \
|
||||
$(JDK_TOPDIR)/src/jdk.crypto.token/$(OPENJDK_TARGET_OS_TYPE)/native/libj2pkcs11
|
||||
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \
|
||||
LIBRARY := j2pkcs11, \
|
||||
@ -37,7 +37,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \
|
||||
$(LIBJAVA_HEADER_FLAGS) \
|
||||
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.crypto.pkcs11, \
|
||||
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.crypto.token, \
|
||||
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2pkcs11/mapfile-vers, \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
@ -30,14 +30,14 @@ include LibCommon.gmk
|
||||
$(eval $(call SetupNativeCompilation,BUILD_LIBUNPACK, \
|
||||
LIBRARY := unpack, \
|
||||
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
|
||||
SRC := $(JDK_TOPDIR)/src/jdk.pack200/share/native/libunpack \
|
||||
$(JDK_TOPDIR)/src/jdk.pack200/share/native/common-unpack, \
|
||||
SRC := $(JDK_TOPDIR)/src/jdk.pack/share/native/libunpack \
|
||||
$(JDK_TOPDIR)/src/jdk.pack/share/native/common-unpack, \
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
OPTIMIZATION := LOW, \
|
||||
CFLAGS := $(CXXFLAGS_JDKLIB) \
|
||||
-DNO_ZLIB -DUNPACK_JNI -DFULL \
|
||||
-I$(SUPPORT_OUTPUTDIR)/headers/java.base \
|
||||
-I$(JDK_TOPDIR)/src/jdk.pack200/share/native/common-unpack \
|
||||
-I$(JDK_TOPDIR)/src/jdk.pack/share/native/common-unpack \
|
||||
$(LIBJAVA_HEADER_FLAGS), \
|
||||
CFLAGS_release := -DPRODUCT, \
|
||||
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libunpack/mapfile-vers, \
|
@ -150,7 +150,6 @@ SUNWprivate_1.1 {
|
||||
Java_java_lang_StrictMath_atan;
|
||||
Java_java_lang_StrictMath_atan2;
|
||||
Java_java_lang_StrictMath_cos;
|
||||
Java_java_lang_StrictMath_exp;
|
||||
Java_java_lang_StrictMath_log;
|
||||
Java_java_lang_StrictMath_log10;
|
||||
Java_java_lang_StrictMath_sin;
|
||||
|
@ -26,6 +26,7 @@
|
||||
package build.tools.jigsaw;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
@ -35,14 +36,17 @@ import java.lang.module.ResolvedModule;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.stream.Collectors.*;
|
||||
import static java.lang.module.ModuleDescriptor.Requires.Modifier.TRANSITIVE;
|
||||
|
||||
/**
|
||||
@ -67,42 +71,25 @@ public class GenGraphs {
|
||||
.map(ModuleReference::descriptor)
|
||||
.filter(m -> (m.name().startsWith("java.") &&
|
||||
!m.name().equals("java.smartcardio")))
|
||||
.collect(Collectors.toSet()));
|
||||
.collect(toSet()));
|
||||
Set<ModuleDescriptor> jdkModules
|
||||
= new TreeSet<>(finder.findAll().stream()
|
||||
.map(ModuleReference::descriptor)
|
||||
.filter(m -> !javaSEModules.contains(m))
|
||||
.collect(Collectors.toSet()));
|
||||
.collect(toSet()));
|
||||
|
||||
GenGraphs genGraphs = new GenGraphs(javaSEModules, jdkModules);
|
||||
GenGraphs genGraphs = new GenGraphs(dir, javaSEModules, jdkModules);
|
||||
Set<String> mods = new HashSet<>();
|
||||
for (ModuleReference mref: finder.findAll()) {
|
||||
ModuleDescriptor descriptor = mref.descriptor();
|
||||
String name = descriptor.name();
|
||||
mods.add(name);
|
||||
Configuration cf = Configuration.empty()
|
||||
.resolveRequires(finder,
|
||||
ModuleFinder.of(),
|
||||
Set.of(name));
|
||||
genGraphs.genDotFile(dir, name, cf);
|
||||
mods.add(mref.descriptor().name());
|
||||
genGraphs.genDotFile(mref);
|
||||
}
|
||||
|
||||
Configuration cf = Configuration.empty()
|
||||
.resolveRequires(finder,
|
||||
ModuleFinder.of(),
|
||||
mods);
|
||||
genGraphs.genDotFile(dir, "jdk", cf);
|
||||
// all modules
|
||||
genGraphs.genDotFile("jdk", mods);
|
||||
|
||||
}
|
||||
|
||||
private final Set<ModuleDescriptor> javaGroup;
|
||||
private final Set<ModuleDescriptor> jdkGroup;
|
||||
|
||||
GenGraphs(Set<ModuleDescriptor> javaGroup, Set<ModuleDescriptor> jdkGroup) {
|
||||
this.javaGroup = Collections.unmodifiableSet(javaGroup);
|
||||
this.jdkGroup = Collections.unmodifiableSet(jdkGroup);
|
||||
}
|
||||
|
||||
private static final String ORANGE = "#e76f00";
|
||||
private static final String BLUE = "#437291";
|
||||
private static final String GRAY = "#dddddd";
|
||||
@ -112,6 +99,7 @@ public class GenGraphs {
|
||||
private static final String REQUIRES_BASE = "color=\"" + GRAY + "\"";
|
||||
|
||||
private static final Map<String,Integer> weights = new HashMap<>();
|
||||
private static final List<Set<String>> ranks = new ArrayList<>();
|
||||
|
||||
private static void weight(String s, String t, int w) {
|
||||
weights.put(s + ":" + t, w);
|
||||
@ -128,23 +116,84 @@ public class GenGraphs {
|
||||
|
||||
static {
|
||||
int h = 1000;
|
||||
weight("java.se", "java.compact3", h * 10);
|
||||
weight("jdk.compact3", "java.compact3", h * 10);
|
||||
weight("java.compact3", "java.compact2", h * 10);
|
||||
weight("java.compact2", "java.compact1", h * 10);
|
||||
weight("java.compact1", "java.logging", h * 10);
|
||||
weight("java.logging", "java.base", h * 10);
|
||||
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.annotations.common"));
|
||||
|
||||
}
|
||||
|
||||
private void genDotFile(Path dir, String name, Configuration cf) throws IOException {
|
||||
try (PrintStream out
|
||||
= new PrintStream(Files.newOutputStream(dir.resolve(name + ".dot")))) {
|
||||
private final Path dir;
|
||||
private final Set<ModuleDescriptor> javaGroup;
|
||||
private final Set<ModuleDescriptor> jdkGroup;
|
||||
|
||||
Map<String, ModuleDescriptor> nameToModule = cf.modules().stream()
|
||||
.map(ResolvedModule::reference)
|
||||
.map(ModuleReference::descriptor)
|
||||
.collect(Collectors.toMap(ModuleDescriptor::name, Function.identity()));
|
||||
GenGraphs(Path dir, Set<ModuleDescriptor> javaGroup, Set<ModuleDescriptor> jdkGroup) {
|
||||
this.dir = dir;
|
||||
this.javaGroup = Collections.unmodifiableSet(javaGroup);
|
||||
this.jdkGroup = Collections.unmodifiableSet(jdkGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a dot file for the given module reference as the root.
|
||||
*/
|
||||
void genDotFile(ModuleReference mref) throws IOException {
|
||||
String name = mref.descriptor().name();
|
||||
genDotFile(name, Set.of(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a dot file for the given set of root modules.
|
||||
*/
|
||||
void genDotFile(String name, Set<String> roots) throws IOException {
|
||||
Configuration cf =
|
||||
Configuration.empty().resolveRequires(ModuleFinder.ofSystem(),
|
||||
ModuleFinder.of(),
|
||||
roots);
|
||||
|
||||
Set<ModuleDescriptor> mds = cf.modules().stream()
|
||||
.map(ResolvedModule::reference)
|
||||
.map(ModuleReference::descriptor)
|
||||
.collect(toSet());
|
||||
|
||||
// generate a dot file for the resolved graph
|
||||
try (OutputStream os = Files.newOutputStream(dir.resolve(name + ".dot"));
|
||||
PrintStream out = new PrintStream(os)) {
|
||||
printGraph(out, name, gengraph(cf),
|
||||
mds.stream()
|
||||
.collect(toMap(ModuleDescriptor::name, Function.identity()))
|
||||
);
|
||||
}
|
||||
|
||||
if (name.equals("java.se") || name.equals("java.se.ee")) {
|
||||
// generate a dot file for Java SE module graph
|
||||
try (OutputStream os = Files.newOutputStream(dir.resolve(name + "-spec.dot"));
|
||||
PrintStream out = new PrintStream(os)) {
|
||||
// transitive reduction on the graph of `requires transitive` edges
|
||||
// filter out jdk.* modules which are implementation dependences
|
||||
Graph<String> graph = requiresTransitiveGraph(cf, true);
|
||||
printGraph(out, name, graph,
|
||||
mds.stream()
|
||||
.filter(md -> !md.name().startsWith("jdk.") &&
|
||||
graph.nodes().contains(md.name()))
|
||||
.collect(toMap(ModuleDescriptor::name, Function.identity()))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void printGraph(PrintStream out,
|
||||
String name,
|
||||
Graph<String> graph,
|
||||
Map<String, ModuleDescriptor> nameToModule)
|
||||
throws IOException
|
||||
{
|
||||
Set<ModuleDescriptor> descriptors = new TreeSet<>(nameToModule.values());
|
||||
|
||||
out.format("digraph \"%s\" {%n", name);
|
||||
@ -162,33 +211,45 @@ public class GenGraphs {
|
||||
.forEach(mn -> out.format(" \"%s\" [fontcolor=\"%s\", group=%s];%n",
|
||||
mn, ORANGE, "java"));
|
||||
out.format("}%n");
|
||||
|
||||
// same ranks
|
||||
ranks.stream()
|
||||
.map(group -> descriptors.stream()
|
||||
.map(ModuleDescriptor::name)
|
||||
.filter(group::contains)
|
||||
.map(mn -> "\"" + mn + "\"")
|
||||
.collect(joining(",")))
|
||||
.filter(group -> group.length() > 0)
|
||||
.forEach(group -> out.format("{rank=same %s}%n", group));
|
||||
|
||||
descriptors.stream()
|
||||
.filter(jdkGroup::contains)
|
||||
.map(ModuleDescriptor::name)
|
||||
.forEach(mn -> out.format(" \"%s\" [fontcolor=\"%s\", group=%s];%n",
|
||||
mn, BLUE, "jdk"));
|
||||
|
||||
// transitive reduction
|
||||
Graph<String> graph = gengraph(cf);
|
||||
descriptors.forEach(md -> {
|
||||
String mn = md.name();
|
||||
Set<String> requiresTransitive = md.requires().stream()
|
||||
.filter(d -> d.modifiers().contains(TRANSITIVE))
|
||||
.map(d -> d.name())
|
||||
.collect(Collectors.toSet());
|
||||
descriptors.stream()
|
||||
.forEach(md -> {
|
||||
String mn = md.name();
|
||||
Set<String> requiresTransitive = md.requires().stream()
|
||||
.filter(d -> d.modifiers().contains(TRANSITIVE))
|
||||
.map(d -> d.name())
|
||||
.collect(toSet());
|
||||
|
||||
graph.adjacentNodes(mn).forEach(dn -> {
|
||||
String attr = dn.equals("java.base") ? REQUIRES_BASE
|
||||
: (requiresTransitive.contains(dn) ? REEXPORTS : REQUIRES);
|
||||
int w = weightOf(mn, dn);
|
||||
if (w > 1)
|
||||
attr += "weight=" + w;
|
||||
out.format(" \"%s\" -> \"%s\" [%s];%n", mn, dn, attr);
|
||||
graph.adjacentNodes(mn)
|
||||
.stream()
|
||||
.filter(nameToModule::containsKey)
|
||||
.forEach(dn -> {
|
||||
String attr = dn.equals("java.base") ? REQUIRES_BASE
|
||||
: (requiresTransitive.contains(dn) ? REEXPORTS : REQUIRES);
|
||||
int w = weightOf(mn, dn);
|
||||
if (w > 1)
|
||||
attr += "weight=" + w;
|
||||
out.format(" \"%s\" -> \"%s\" [%s];%n", mn, dn, attr);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
out.println("}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -208,7 +269,7 @@ public class GenGraphs {
|
||||
.map(ResolvedModule::name)
|
||||
.forEach(target -> builder.addEdge(mn, target));
|
||||
}
|
||||
Graph<String> rpg = requiresTransitiveGraph(cf);
|
||||
Graph<String> rpg = requiresTransitiveGraph(cf, false);
|
||||
return builder.build().reduce(rpg);
|
||||
}
|
||||
|
||||
@ -216,13 +277,14 @@ public class GenGraphs {
|
||||
* Returns a Graph containing only requires transitive edges
|
||||
* with transitive reduction.
|
||||
*/
|
||||
private Graph<String> requiresTransitiveGraph(Configuration cf) {
|
||||
private Graph<String> requiresTransitiveGraph(Configuration cf, boolean includeBase) {
|
||||
Graph.Builder<String> builder = new Graph.Builder<>();
|
||||
for (ResolvedModule resolvedModule : cf.modules()) {
|
||||
ModuleDescriptor descriptor = resolvedModule.reference().descriptor();
|
||||
String mn = descriptor.name();
|
||||
descriptor.requires().stream()
|
||||
.filter(d -> d.modifiers().contains(TRANSITIVE))
|
||||
.filter(d -> d.modifiers().contains(TRANSITIVE)
|
||||
|| (includeBase && d.name().equals("java.base")))
|
||||
.map(d -> d.name())
|
||||
.forEach(d -> builder.addEdge(mn, d));
|
||||
}
|
||||
|
@ -171,8 +171,6 @@ struct NSAppArgs {
|
||||
* Main
|
||||
*/
|
||||
|
||||
#define GetArch() GetArchPath(CURRENT_DATA_MODEL)
|
||||
|
||||
/* Store the name of the executable once computed */
|
||||
static char *execname = NULL;
|
||||
|
||||
@ -184,16 +182,6 @@ GetExecName() {
|
||||
return execname;
|
||||
}
|
||||
|
||||
const char *
|
||||
GetArchPath(int nbits)
|
||||
{
|
||||
switch(nbits) {
|
||||
default:
|
||||
return LIBARCHNAME;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Exports the JNI interface from libjli
|
||||
*
|
||||
@ -211,7 +199,7 @@ static InvocationFunctions *GetExportedJNIFunctions() {
|
||||
if (sExportedJNIFunctions != NULL) return sExportedJNIFunctions;
|
||||
|
||||
char jrePath[PATH_MAX];
|
||||
jboolean gotJREPath = GetJREPath(jrePath, sizeof(jrePath), GetArch(), JNI_FALSE);
|
||||
jboolean gotJREPath = GetJREPath(jrePath, sizeof(jrePath), JNI_FALSE);
|
||||
if (!gotJREPath) {
|
||||
JLI_ReportErrorMessage("Failed to GetJREPath()");
|
||||
return NULL;
|
||||
@ -229,7 +217,7 @@ static InvocationFunctions *GetExportedJNIFunctions() {
|
||||
}
|
||||
|
||||
char jvmPath[PATH_MAX];
|
||||
jboolean gotJVMPath = GetJVMPath(jrePath, preferredJVM, jvmPath, sizeof(jvmPath), GetArch(), CURRENT_DATA_MODEL);
|
||||
jboolean gotJVMPath = GetJVMPath(jrePath, preferredJVM, jvmPath, sizeof(jvmPath), CURRENT_DATA_MODEL);
|
||||
if (!gotJVMPath) {
|
||||
JLI_ReportErrorMessage("Failed to GetJVMPath()");
|
||||
return NULL;
|
||||
@ -390,7 +378,6 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
|
||||
/* Check data model flags, and exec process, if needed */
|
||||
{
|
||||
char *arch = (char *)GetArch(); /* like sparc or sparcv9 */
|
||||
char * jvmtype = NULL;
|
||||
int argc = *pargc;
|
||||
char **argv = *pargv;
|
||||
@ -462,7 +449,7 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
jvmpath does not exist */
|
||||
if (wanted == running) {
|
||||
/* Find out where the JRE is that we will be using. */
|
||||
if (!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) {
|
||||
if (!GetJREPath(jrepath, so_jrepath, JNI_FALSE) ) {
|
||||
JLI_ReportErrorMessage(JRE_ERROR1);
|
||||
exit(2);
|
||||
}
|
||||
@ -481,7 +468,7 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
exit(4);
|
||||
}
|
||||
|
||||
if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, arch, wanted)) {
|
||||
if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, wanted)) {
|
||||
JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath);
|
||||
exit(4);
|
||||
}
|
||||
@ -502,7 +489,7 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
#if defined(DUAL_MODE)
|
||||
if (running != wanted) {
|
||||
/* Find out where the JRE is that we will be using. */
|
||||
if (!GetJREPath(jrepath, so_jrepath, GetArchPath(wanted), JNI_TRUE)) {
|
||||
if (!GetJREPath(jrepath, so_jrepath, JNI_TRUE)) {
|
||||
/* give up and let other code report error message */
|
||||
JLI_ReportErrorMessage(JRE_ERROR2, wanted);
|
||||
exit(1);
|
||||
@ -526,7 +513,7 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
}
|
||||
|
||||
/* exec child can do error checking on the existence of the path */
|
||||
jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, GetArchPath(wanted), wanted);
|
||||
jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, wanted);
|
||||
}
|
||||
#else /* ! DUAL_MODE */
|
||||
JLI_ReportErrorMessage(JRE_ERROR2, wanted);
|
||||
@ -579,7 +566,7 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
*/
|
||||
static jboolean
|
||||
GetJVMPath(const char *jrepath, const char *jvmtype,
|
||||
char *jvmpath, jint jvmpathsize, const char * arch, int bitsWanted)
|
||||
char *jvmpath, jint jvmpathsize, int bitsWanted)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
@ -613,7 +600,7 @@ GetJVMPath(const char *jrepath, const char *jvmtype,
|
||||
* Find path to JRE based on .exe's location or registry settings.
|
||||
*/
|
||||
static jboolean
|
||||
GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative)
|
||||
GetJREPath(char *path, jint pathsize, jboolean speculative)
|
||||
{
|
||||
char libjava[MAXPATHLEN];
|
||||
|
||||
@ -841,7 +828,7 @@ static void* hSplashLib = NULL;
|
||||
void* SplashProcAddress(const char* name) {
|
||||
if (!hSplashLib) {
|
||||
char jrePath[PATH_MAX];
|
||||
if (!GetJREPath(jrePath, sizeof(jrePath), GetArch(), JNI_FALSE)) {
|
||||
if (!GetJREPath(jrePath, sizeof(jrePath), JNI_FALSE)) {
|
||||
JLI_ReportErrorMessage(JRE_ERROR1);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -142,6 +142,9 @@ class CipherBlockChaining extends FeedbackCipher {
|
||||
*/
|
||||
int encrypt(byte[] plain, int plainOffset, int plainLen,
|
||||
byte[] cipher, int cipherOffset) {
|
||||
if (plainLen <= 0) {
|
||||
return plainLen;
|
||||
}
|
||||
cryptBlockSizeCheck(plainLen);
|
||||
cryptNullAndBoundsCheck(plain, plainOffset, plainLen);
|
||||
cryptNullAndBoundsCheck(cipher, cipherOffset, plainLen);
|
||||
@ -190,6 +193,9 @@ class CipherBlockChaining extends FeedbackCipher {
|
||||
*/
|
||||
int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
|
||||
byte[] plain, int plainOffset) {
|
||||
if (cipherLen <= 0) {
|
||||
return cipherLen;
|
||||
}
|
||||
cryptBlockSizeCheck(cipherLen);
|
||||
cryptNullAndBoundsCheck(cipher, cipherOffset, cipherLen);
|
||||
cryptNullAndBoundsCheck(plain, plainOffset, cipherLen);
|
||||
@ -220,10 +226,6 @@ class CipherBlockChaining extends FeedbackCipher {
|
||||
}
|
||||
|
||||
private static void cryptNullAndBoundsCheck(byte[] array, int offset, int len) {
|
||||
if (len <= 0) {
|
||||
return; // not an error because cryptImpl/decryptImpl won't execute if len <= 0
|
||||
}
|
||||
|
||||
Objects.requireNonNull(array);
|
||||
|
||||
if (offset < 0 || offset >= array.length) {
|
||||
|
@ -172,10 +172,12 @@ final class CounterMode extends FeedbackCipher {
|
||||
* are encrypted on demand.
|
||||
*/
|
||||
private int crypt(byte[] in, int inOff, int len, byte[] out, int outOff) {
|
||||
|
||||
Objects.checkFromIndexSize(inOff, len, in.length);
|
||||
Objects.checkFromIndexSize(outOff, len, out.length);
|
||||
return implCrypt(in, inOff, len, out, outOff);
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
Objects.checkFromIndexSize(inOff, len, in.length);
|
||||
Objects.checkFromIndexSize(outOff, len, out.length);
|
||||
return implCrypt(in, inOff, len, out, outOff);
|
||||
}
|
||||
|
||||
// Implementation of crpyt() method. Possibly replaced with a compiler intrinsic.
|
||||
|
@ -317,7 +317,7 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
|
||||
this(null, je);
|
||||
}
|
||||
boolean isClassFile() {
|
||||
if (!name.endsWith(".class")) {
|
||||
if (!name.endsWith(".class") || name.endsWith("module-info.class")) {
|
||||
return false;
|
||||
}
|
||||
for (String prefix = name;;) {
|
||||
|
@ -14,15 +14,6 @@ pack.code.attribute.CharacterRangeTable = NH[PHPOHIIH]
|
||||
pack.class.attribute.SourceID = RUH
|
||||
pack.class.attribute.CompilationID = RUH
|
||||
|
||||
# Module attributes, supported by the tool and not JSR-200
|
||||
pack.class.attribute.Module = RUHFHNH[RUHFH]NH[RUHFHNH[RUH]]NH[RUHFHNH[RUH]]NH[RCH]NH[RCHNH[RCH]]
|
||||
pack.class.attribute.ModulePackages = NH[RUH]
|
||||
pack.class.attribute.ModuleVersion = RUH
|
||||
pack.class.attribute.ModuleMainClass = RCH
|
||||
pack.class.attribute.ModuleTarget = RUHRUHRUH
|
||||
pack.class.attribute.ModuleHashes = RUHNH[RUHNH[B]]
|
||||
|
||||
|
||||
# Note: Zero-length ("marker") attributes do not need to be specified here.
|
||||
# They are automatically defined to have an empty layout.
|
||||
#pack.class.attribute.Deprecated =
|
||||
|
@ -206,12 +206,6 @@ public final class FilePermission extends Permission implements Serializable {
|
||||
DefaultFileSystemProvider.create()
|
||||
.getFileSystem(URI.create("file:///"));
|
||||
|
||||
/**
|
||||
* Creates FilePermission objects with special internals.
|
||||
* See {@link FilePermCompat#newPermPlusAltPath(Permission)} and
|
||||
* {@link FilePermCompat#newPermUsingAltPath(Permission)}.
|
||||
*/
|
||||
|
||||
private static final Path here = builtInFS.getPath(
|
||||
GetPropertyAction.privilegedGetProperty("user.dir"));
|
||||
|
||||
@ -261,9 +255,14 @@ public final class FilePermission extends Permission implements Serializable {
|
||||
|
||||
static {
|
||||
SharedSecrets.setJavaIOFilePermissionAccess(
|
||||
/**
|
||||
* Creates FilePermission objects with special internals.
|
||||
* See {@link FilePermCompat#newPermPlusAltPath(Permission)} and
|
||||
* {@link FilePermCompat#newPermUsingAltPath(Permission)}.
|
||||
*/
|
||||
new JavaIOFilePermissionAccess() {
|
||||
public FilePermission newPermPlusAltPath(FilePermission input) {
|
||||
if (input.npath2 == null && !input.allFiles) {
|
||||
if (!input.invalid && input.npath2 == null && !input.allFiles) {
|
||||
Path npath2 = altPath(input.npath);
|
||||
if (npath2 != null) {
|
||||
// Please note the name of the new permission is
|
||||
@ -281,7 +280,7 @@ public final class FilePermission extends Permission implements Serializable {
|
||||
return input;
|
||||
}
|
||||
public FilePermission newPermUsingAltPath(FilePermission input) {
|
||||
if (!input.allFiles) {
|
||||
if (!input.invalid && !input.allFiles) {
|
||||
Path npath2 = altPath(input.npath);
|
||||
if (npath2 != null) {
|
||||
// New name, see above.
|
||||
@ -340,6 +339,16 @@ public final class FilePermission extends Permission implements Serializable {
|
||||
// Windows. Some JDK codes generate such illegal names.
|
||||
npath = builtInFS.getPath(new File(name).getPath())
|
||||
.normalize();
|
||||
// lastName should always be non-null now
|
||||
Path lastName = npath.getFileName();
|
||||
if (lastName != null && lastName.toString().equals("-")) {
|
||||
directory = true;
|
||||
recursive = !rememberStar;
|
||||
npath = npath.getParent();
|
||||
}
|
||||
if (npath == null) {
|
||||
npath = builtInFS.getPath("");
|
||||
}
|
||||
invalid = false;
|
||||
} catch (InvalidPathException ipe) {
|
||||
// Still invalid. For compatibility reason, accept it
|
||||
@ -348,16 +357,6 @@ public final class FilePermission extends Permission implements Serializable {
|
||||
invalid = true;
|
||||
}
|
||||
|
||||
// lastName should always be non-null now
|
||||
Path lastName = npath.getFileName();
|
||||
if (lastName != null && lastName.toString().equals("-")) {
|
||||
directory = true;
|
||||
recursive = !rememberStar;
|
||||
npath = npath.getParent();
|
||||
}
|
||||
if (npath == null) {
|
||||
npath = builtInFS.getPath("");
|
||||
}
|
||||
} else {
|
||||
if ((cpath = getName()) == null)
|
||||
throw new NullPointerException("name can't be null");
|
||||
@ -452,6 +451,8 @@ public final class FilePermission extends Permission implements Serializable {
|
||||
* is converted to a {@link java.nio.file.Path} object named {@code npath}
|
||||
* after {@link Path#normalize() normalization}. No canonicalization is
|
||||
* performed which means the underlying file system is not accessed.
|
||||
* If an {@link InvalidPathException} is thrown during the conversion,
|
||||
* this {@code FilePermission} will be labeled as invalid.
|
||||
* <P>
|
||||
* In either case, the "*" or "-" character at the end of a wildcard
|
||||
* {@code path} is removed before canonicalization or normalization.
|
||||
@ -532,7 +533,12 @@ public final class FilePermission extends Permission implements Serializable {
|
||||
* {@code simple_npath.relativize(wildcard_npath)} is exactly "..",
|
||||
* a simple {@code npath} is recursively inside a wildcard {@code npath}
|
||||
* if and only if {@code simple_npath.relativize(wildcard_npath)}
|
||||
* is a series of one or more "..".
|
||||
* is a series of one or more "..". An invalid {@code FilePermission} does
|
||||
* not imply any object except for itself. An invalid {@code FilePermission}
|
||||
* is not implied by any object except for itself or a {@code FilePermission}
|
||||
* on {@literal "<<ALL FILES>>"} whose actions is a superset of this
|
||||
* invalid {@code FilePermission}. Even if two {@code FilePermission}
|
||||
* are created with the same invalid path, one does not imply the other.
|
||||
*
|
||||
* @param p the permission to check against.
|
||||
*
|
||||
@ -566,12 +572,12 @@ public final class FilePermission extends Permission implements Serializable {
|
||||
if (this == that) {
|
||||
return true;
|
||||
}
|
||||
if (this.invalid || that.invalid) {
|
||||
return false;
|
||||
}
|
||||
if (allFiles) {
|
||||
return true;
|
||||
}
|
||||
if (this.invalid || that.invalid) {
|
||||
return false;
|
||||
}
|
||||
if (that.allFiles) {
|
||||
return false;
|
||||
}
|
||||
@ -699,6 +705,10 @@ public final class FilePermission extends Permission implements Serializable {
|
||||
* (if {@code jdk.io.permissionsUseCanonicalPath} is {@code true}) or
|
||||
* {@code npath} (if {@code jdk.io.permissionsUseCanonicalPath}
|
||||
* is {@code false}) are equal. Or they are both {@literal "<<ALL FILES>>"}.
|
||||
* <p>
|
||||
* When {@code jdk.io.permissionsUseCanonicalPath} is {@code false}, an
|
||||
* invalid {@code FilePermission} does not equal to any object except
|
||||
* for itself, even if they are created using the same invalid path.
|
||||
*
|
||||
* @param obj the object we are testing for equality with this object.
|
||||
* @return <code>true</code> if obj is a FilePermission, and has the same
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -79,7 +79,8 @@ class FdLibm {
|
||||
*/
|
||||
private static double __LO(double x, int low) {
|
||||
long transX = Double.doubleToRawLongBits(x);
|
||||
return Double.longBitsToDouble((transX & 0xFFFF_FFFF_0000_0000L)|low );
|
||||
return Double.longBitsToDouble((transX & 0xFFFF_FFFF_0000_0000L) |
|
||||
(low & 0x0000_0000_FFFF_FFFFL));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,7 +97,8 @@ class FdLibm {
|
||||
*/
|
||||
private static double __HI(double x, int high) {
|
||||
long transX = Double.doubleToRawLongBits(x);
|
||||
return Double.longBitsToDouble((transX & 0x0000_0000_FFFF_FFFFL)|( ((long)high)) << 32 );
|
||||
return Double.longBitsToDouble((transX & 0x0000_0000_FFFF_FFFFL) |
|
||||
( ((long)high)) << 32 );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -580,4 +582,152 @@ class FdLibm {
|
||||
return s * z;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the exponential of x.
|
||||
*
|
||||
* Method
|
||||
* 1. Argument reduction:
|
||||
* Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
|
||||
* Given x, find r and integer k such that
|
||||
*
|
||||
* x = k*ln2 + r, |r| <= 0.5*ln2.
|
||||
*
|
||||
* Here r will be represented as r = hi-lo for better
|
||||
* accuracy.
|
||||
*
|
||||
* 2. Approximation of exp(r) by a special rational function on
|
||||
* the interval [0,0.34658]:
|
||||
* Write
|
||||
* R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
|
||||
* We use a special Reme algorithm on [0,0.34658] to generate
|
||||
* a polynomial of degree 5 to approximate R. The maximum error
|
||||
* of this polynomial approximation is bounded by 2**-59. In
|
||||
* other words,
|
||||
* R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
|
||||
* (where z=r*r, and the values of P1 to P5 are listed below)
|
||||
* and
|
||||
* | 5 | -59
|
||||
* | 2.0+P1*z+...+P5*z - R(z) | <= 2
|
||||
* | |
|
||||
* The computation of exp(r) thus becomes
|
||||
* 2*r
|
||||
* exp(r) = 1 + -------
|
||||
* R - r
|
||||
* r*R1(r)
|
||||
* = 1 + r + ----------- (for better accuracy)
|
||||
* 2 - R1(r)
|
||||
* where
|
||||
* 2 4 10
|
||||
* R1(r) = r - (P1*r + P2*r + ... + P5*r ).
|
||||
*
|
||||
* 3. Scale back to obtain exp(x):
|
||||
* From step 1, we have
|
||||
* exp(x) = 2^k * exp(r)
|
||||
*
|
||||
* Special cases:
|
||||
* exp(INF) is INF, exp(NaN) is NaN;
|
||||
* exp(-INF) is 0, and
|
||||
* for finite argument, only exp(0)=1 is exact.
|
||||
*
|
||||
* Accuracy:
|
||||
* according to an error analysis, the error is always less than
|
||||
* 1 ulp (unit in the last place).
|
||||
*
|
||||
* Misc. info.
|
||||
* For IEEE double
|
||||
* if x > 7.09782712893383973096e+02 then exp(x) overflow
|
||||
* if x < -7.45133219101941108420e+02 then exp(x) underflow
|
||||
*
|
||||
* Constants:
|
||||
* The hexadecimal values are the intended ones for the following
|
||||
* constants. The decimal values may be used, provided that the
|
||||
* compiler will convert from decimal to binary accurately enough
|
||||
* to produce the hexadecimal values shown.
|
||||
*/
|
||||
static class Exp {
|
||||
private static final double one = 1.0;
|
||||
private static final double[] half = {0.5, -0.5,};
|
||||
private static final double huge = 1.0e+300;
|
||||
private static final double twom1000= 0x1.0p-1000; // 9.33263618503218878990e-302 = 2^-1000
|
||||
private static final double o_threshold= 0x1.62e42fefa39efp9; // 7.09782712893383973096e+02
|
||||
private static final double u_threshold= -0x1.74910d52d3051p9; // -7.45133219101941108420e+02;
|
||||
private static final double[] ln2HI ={ 0x1.62e42feep-1, // 6.93147180369123816490e-01
|
||||
-0x1.62e42feep-1}; // -6.93147180369123816490e-01
|
||||
private static final double[] ln2LO ={ 0x1.a39ef35793c76p-33, // 1.90821492927058770002e-10
|
||||
-0x1.a39ef35793c76p-33}; // -1.90821492927058770002e-10
|
||||
private static final double invln2 = 0x1.71547652b82fep0; // 1.44269504088896338700e+00
|
||||
|
||||
private static final double P1 = 0x1.555555555553ep-3; // 1.66666666666666019037e-01
|
||||
private static final double P2 = -0x1.6c16c16bebd93p-9; // -2.77777777770155933842e-03
|
||||
private static final double P3 = 0x1.1566aaf25de2cp-14; // 6.61375632143793436117e-05
|
||||
private static final double P4 = -0x1.bbd41c5d26bf1p-20; // -1.65339022054652515390e-06
|
||||
private static final double P5 = 0x1.6376972bea4d0p-25; // 4.13813679705723846039e-08
|
||||
|
||||
// should be able to forgo strictfp due to controlled over/underflow
|
||||
public static strictfp double compute(double x) {
|
||||
double y;
|
||||
double hi = 0.0;
|
||||
double lo = 0.0;
|
||||
double c;
|
||||
double t;
|
||||
int k = 0;
|
||||
int xsb;
|
||||
/*unsigned*/ int hx;
|
||||
|
||||
hx = __HI(x); /* high word of x */
|
||||
xsb = (hx >> 31) & 1; /* sign bit of x */
|
||||
hx &= 0x7fffffff; /* high word of |x| */
|
||||
|
||||
/* filter out non-finite argument */
|
||||
if (hx >= 0x40862E42) { /* if |x| >= 709.78... */
|
||||
if (hx >= 0x7ff00000) {
|
||||
if (((hx & 0xfffff) | __LO(x)) != 0)
|
||||
return x + x; /* NaN */
|
||||
else
|
||||
return (xsb == 0) ? x : 0.0; /* exp(+-inf) = {inf, 0} */
|
||||
}
|
||||
if (x > o_threshold)
|
||||
return huge * huge; /* overflow */
|
||||
if (x < u_threshold) // unsigned compare needed here?
|
||||
return twom1000 * twom1000; /* underflow */
|
||||
}
|
||||
|
||||
/* argument reduction */
|
||||
if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
|
||||
if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
|
||||
hi = x - ln2HI[xsb];
|
||||
lo=ln2LO[xsb];
|
||||
k = 1 - xsb - xsb;
|
||||
} else {
|
||||
k = (int)(invln2 * x + half[xsb]);
|
||||
t = k;
|
||||
hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */
|
||||
lo = t*ln2LO[0];
|
||||
}
|
||||
x = hi - lo;
|
||||
} else if (hx < 0x3e300000) { /* when |x|<2**-28 */
|
||||
if (huge + x > one)
|
||||
return one + x; /* trigger inexact */
|
||||
} else {
|
||||
k = 0;
|
||||
}
|
||||
|
||||
/* x is now in primary range */
|
||||
t = x * x;
|
||||
c = x - t*(P1 + t*(P2 + t*(P3 + t*(P4 + t*P5))));
|
||||
if (k == 0)
|
||||
return one - ((x*c)/(c - 2.0) - x);
|
||||
else
|
||||
y = one - ((lo - (x*c)/(2.0 - c)) - hi);
|
||||
|
||||
if(k >= -1021) {
|
||||
y = __HI(y, __HI(y) + (k << 20)); /* add k to y's exponent */
|
||||
return y;
|
||||
} else {
|
||||
y = __HI(y, __HI(y) + ((k + 1000) << 20)); /* add k to y's exponent */
|
||||
return y * twom1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,11 +26,13 @@
|
||||
package java.lang;
|
||||
|
||||
import jdk.internal.loader.BuiltinClassLoader;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.module.ModuleHashes;
|
||||
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;
|
||||
@ -51,12 +53,13 @@ import java.util.Set;
|
||||
* @author Josh Bloch
|
||||
*/
|
||||
public final class StackTraceElement implements java.io.Serializable {
|
||||
// This field is set to the compacted String representation used
|
||||
// by StackTraceElement::toString and stored in serial form.
|
||||
|
||||
// For Throwables and StackWalker, the VM initially sets this field to a
|
||||
// reference to the declaring Class. The Class reference is used to
|
||||
// construct the 'format' bitmap, and then is cleared.
|
||||
//
|
||||
// This field is of Object type. VM initially sets this field to
|
||||
// the Class object of the declaring class to build the compacted string.
|
||||
private Object classOrLoaderModuleClassName;
|
||||
// For STEs constructed using the public constructors, this field is not used.
|
||||
private transient Class<?> declaringClassObject;
|
||||
|
||||
// Normally initialized by VM
|
||||
private String classLoaderName;
|
||||
@ -66,6 +69,7 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
private String methodName;
|
||||
private String fileName;
|
||||
private int lineNumber;
|
||||
private byte format = 0; // Default to show all
|
||||
|
||||
/**
|
||||
* Creates a stack trace element representing the specified execution
|
||||
@ -256,9 +260,10 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this stack trace element. The
|
||||
* format of this string depends on the implementation, but the following
|
||||
* examples may be regarded as typical:
|
||||
* Returns a string representation of this stack trace element.
|
||||
*
|
||||
* @apiNote The format of this string depends on the implementation, but the
|
||||
* following examples may be regarded as typical:
|
||||
* <ul>
|
||||
* <li>
|
||||
* "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Main.java:101)}"
|
||||
@ -309,7 +314,7 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
* then the second element is omitted as shown in
|
||||
* "{@code com.foo.loader//com.foo.bar.App.run(App.java:12)}".
|
||||
*
|
||||
* If the class loader is a <a href="ClassLoader.html#builtinLoaders">
|
||||
* <p> If the class loader is a <a href="ClassLoader.html#builtinLoaders">
|
||||
* built-in class loader</a> or is not named then the first element
|
||||
* and its following {@code "/"} are omitted as shown in
|
||||
* "{@code acme@2.1/org.acme.Lib.test(Lib.java:80)}".
|
||||
@ -317,25 +322,30 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
* the second element and its following {@code "/"} are also omitted
|
||||
* as shown in "{@code MyClass.mash(MyClass.java:9)}".
|
||||
*
|
||||
* <p> The {@code toString} method may return two different values on two
|
||||
* {@code StackTraceElement} instances that are
|
||||
* {@linkplain #equals(Object) equal}, for example one created via the
|
||||
* constructor, and one obtained from {@link java.lang.Throwable} or
|
||||
* {@link java.lang.StackWalker.StackFrame}, where an implementation may
|
||||
* choose to omit some element in the returned string.
|
||||
*
|
||||
* @see Throwable#printStackTrace()
|
||||
*/
|
||||
public String toString() {
|
||||
String s = buildLoaderModuleClassName();
|
||||
if (s == null) {
|
||||
// all elements will be included
|
||||
s = "";
|
||||
if (classLoaderName != null && !classLoaderName.isEmpty()) {
|
||||
s += classLoaderName + "/";
|
||||
}
|
||||
if (moduleName != null && !moduleName.isEmpty()) {
|
||||
s += moduleName;
|
||||
|
||||
if (moduleVersion != null && !moduleVersion.isEmpty()) {
|
||||
s += "@" + moduleVersion;
|
||||
}
|
||||
}
|
||||
s = s.isEmpty() ? declaringClass : s + "/" + declaringClass;
|
||||
String s = "";
|
||||
if (!dropClassLoaderName() && classLoaderName != null &&
|
||||
!classLoaderName.isEmpty()) {
|
||||
s += classLoaderName + "/";
|
||||
}
|
||||
if (moduleName != null && !moduleName.isEmpty()) {
|
||||
s += moduleName;
|
||||
|
||||
if (!dropModuleVersion() && moduleVersion != null &&
|
||||
!moduleVersion.isEmpty()) {
|
||||
s += "@" + moduleVersion;
|
||||
}
|
||||
}
|
||||
s = s.isEmpty() ? declaringClass : s + "/" + declaringClass;
|
||||
|
||||
return s + "." + methodName + "(" +
|
||||
(isNativeMethod() ? "Native Method)" :
|
||||
@ -397,67 +407,53 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* Build the compacted String representation to be returned by
|
||||
* toString method from the declaring Class object.
|
||||
* Called from of() methods to set the 'format' bitmap using the Class
|
||||
* reference stored in declaringClassObject, and then clear the reference.
|
||||
*
|
||||
* <p>
|
||||
* If the module is a non-upgradeable JDK module, then set
|
||||
* JDK_NON_UPGRADEABLE_MODULE to omit its version string.
|
||||
* <p>
|
||||
* If the loader is one of the built-in loaders (`boot`, `platform`, or `app`)
|
||||
* then set BUILTIN_CLASS_LOADER to omit the first element (`<loader>/`).
|
||||
*/
|
||||
synchronized String buildLoaderModuleClassName() {
|
||||
if (classOrLoaderModuleClassName == null)
|
||||
return null;
|
||||
private synchronized void computeFormat() {
|
||||
try {
|
||||
Class<?> cls = (Class<?>) declaringClassObject;
|
||||
ClassLoader loader = cls.getClassLoader0();
|
||||
Module m = cls.getModule();
|
||||
byte bits = 0;
|
||||
|
||||
if (classOrLoaderModuleClassName instanceof Class) {
|
||||
Class<?> cls = (Class<?>)classOrLoaderModuleClassName;
|
||||
classOrLoaderModuleClassName = toLoaderModuleClassName(cls);
|
||||
// First element - class loader name
|
||||
// Call package-private ClassLoader::name method
|
||||
|
||||
if (loader instanceof BuiltinClassLoader) {
|
||||
bits |= BUILTIN_CLASS_LOADER;
|
||||
}
|
||||
|
||||
// Second element - module name and version
|
||||
|
||||
// Omit if is a JDK non-upgradeable module (recorded in the hashes
|
||||
// in java.base)
|
||||
if (isHashedInJavaBase(m)) {
|
||||
bits |= JDK_NON_UPGRADEABLE_MODULE;
|
||||
}
|
||||
format = bits;
|
||||
} finally {
|
||||
// Class reference no longer needed, clear it
|
||||
declaringClassObject = null;
|
||||
}
|
||||
return (String)classOrLoaderModuleClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <loader>/<module>/<fully-qualified-classname> string
|
||||
* representation of the given class.
|
||||
* <p>
|
||||
* If the module is a non-upgradeable JDK module then omit
|
||||
* its version string.
|
||||
* <p>
|
||||
* If the loader has no name, or if the loader is one of the built-in
|
||||
* loaders (`boot`, `platform`, or `app`) then drop the first element
|
||||
* (`<loader>/`).
|
||||
* <p>
|
||||
* If the first element has been dropped and the module is unnamed
|
||||
* then drop the second element (`<module>/`).
|
||||
* <p>
|
||||
* If the first element is not dropped and the module is unnamed
|
||||
* then drop `<module>`.
|
||||
*/
|
||||
private static String toLoaderModuleClassName(Class<?> cls) {
|
||||
ClassLoader loader = cls.getClassLoader0();
|
||||
Module m = cls.getModule();
|
||||
private static final byte BUILTIN_CLASS_LOADER = 0x1;
|
||||
private static final byte JDK_NON_UPGRADEABLE_MODULE = 0x2;
|
||||
|
||||
// First element - class loader name
|
||||
// Call package-private ClassLoader::name method
|
||||
String s = "";
|
||||
if (loader != null && loader.name() != null &&
|
||||
!(loader instanceof BuiltinClassLoader)) {
|
||||
s = loader.name() + "/";
|
||||
}
|
||||
private boolean dropClassLoaderName() {
|
||||
return (format & BUILTIN_CLASS_LOADER) == BUILTIN_CLASS_LOADER;
|
||||
}
|
||||
|
||||
// Second element - module name and version
|
||||
if (m != null && m.isNamed()) {
|
||||
s += m.getName();
|
||||
// Include version if it is a user module or upgradeable module
|
||||
//
|
||||
// If it is JDK non-upgradeable module which is recorded
|
||||
// in the hashes in java.base, omit the version.
|
||||
if (!isHashedInJavaBase(m)) {
|
||||
Optional<Version> ov = m.getDescriptor().version();
|
||||
if (ov.isPresent()) {
|
||||
String version = "@" + ov.get().toString();
|
||||
s += version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fully-qualified class name
|
||||
return s.isEmpty() ? cls.getName() : s + "/" + cls.getName();
|
||||
private boolean dropModuleVersion() {
|
||||
return (format & JDK_NON_UPGRADEABLE_MODULE) == JDK_NON_UPGRADEABLE_MODULE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -484,13 +480,16 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
static Set<String> HASHED_MODULES = hashedModules();
|
||||
|
||||
static Set<String> hashedModules() {
|
||||
Module javaBase = Layer.boot().findModule("java.base").get();
|
||||
Optional<ModuleHashes> ohashes =
|
||||
SharedSecrets.getJavaLangModuleAccess()
|
||||
.hashes(javaBase.getDescriptor());
|
||||
|
||||
if (ohashes.isPresent()) {
|
||||
Set<String> names = new HashSet<>(ohashes.get().names());
|
||||
Optional<ResolvedModule> resolvedModule = Layer.boot()
|
||||
.configuration()
|
||||
.findModule("java.base");
|
||||
assert resolvedModule.isPresent();
|
||||
ModuleReference mref = resolvedModule.get().reference();
|
||||
assert mref instanceof ModuleReferenceImpl;
|
||||
ModuleHashes hashes = ((ModuleReferenceImpl)mref).recordedHashes();
|
||||
if (hashes != null) {
|
||||
Set<String> names = new HashSet<>(hashes.names());
|
||||
names.add("java.base");
|
||||
return names;
|
||||
}
|
||||
@ -519,7 +518,7 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
|
||||
// ensure the proper StackTraceElement initialization
|
||||
for (StackTraceElement ste : stackTrace) {
|
||||
ste.buildLoaderModuleClassName();
|
||||
ste.computeFormat();
|
||||
}
|
||||
return stackTrace;
|
||||
}
|
||||
@ -531,7 +530,7 @@ public final class StackTraceElement implements java.io.Serializable {
|
||||
StackTraceElement ste = new StackTraceElement();
|
||||
initStackTraceElement(ste, sfi);
|
||||
|
||||
ste.buildLoaderModuleClassName();
|
||||
ste.computeFormat();
|
||||
return ste;
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,9 @@ public final class StrictMath {
|
||||
* @return the value <i>e</i><sup>{@code a}</sup>,
|
||||
* where <i>e</i> is the base of the natural logarithms.
|
||||
*/
|
||||
public static native double exp(double a);
|
||||
public static double exp(double a) {
|
||||
return FdLibm.Exp.compute(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the natural logarithm (base <i>e</i>) of a {@code double}
|
||||
|
@ -172,6 +172,7 @@ public class MethodHandles {
|
||||
* @throws IllegalAccessException if the access check specified above fails
|
||||
* @throws SecurityException if denied by the security manager
|
||||
* @since 9
|
||||
* @see Lookup#dropLookupMode
|
||||
*/
|
||||
public static Lookup privateLookupIn(Class<?> targetClass, Lookup lookup) throws IllegalAccessException {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
@ -691,10 +692,15 @@ public class MethodHandles {
|
||||
* A lookup object on a new lookup class
|
||||
* {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
|
||||
* may have some mode bits set to zero.
|
||||
* Mode bits can also be
|
||||
* {@linkplain java.lang.invoke.MethodHandles.Lookup#dropLookupMode directly cleared}.
|
||||
* Once cleared, mode bits cannot be restored from the downgraded lookup object.
|
||||
* The purpose of this is to restrict access via the new lookup object,
|
||||
* so that it can access only names which can be reached by the original
|
||||
* lookup object, and also by the new lookup class.
|
||||
* @return the lookup modes, which limit the kinds of access performed by this lookup object
|
||||
* @see #in
|
||||
* @see #dropLookupMode
|
||||
*/
|
||||
public int lookupModes() {
|
||||
return allowedModes & ALL_MODES;
|
||||
@ -748,7 +754,8 @@ public class MethodHandles {
|
||||
* which may change due to this operation.
|
||||
*
|
||||
* @param requestedLookupClass the desired lookup class for the new lookup object
|
||||
* @return a lookup object which reports the desired lookup class
|
||||
* @return a lookup object which reports the desired lookup class, or the same object
|
||||
* if there is no change
|
||||
* @throws NullPointerException if the argument is null
|
||||
*/
|
||||
public Lookup in(Class<?> requestedLookupClass) {
|
||||
@ -788,6 +795,40 @@ public class MethodHandles {
|
||||
return new Lookup(requestedLookupClass, newModes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a lookup on the same lookup class which this lookup object
|
||||
* finds members, but with a lookup mode that has lost the given lookup mode.
|
||||
* The lookup mode to drop is one of {@link #PUBLIC PUBLIC}, {@link #MODULE
|
||||
* MODULE}, {@link #PACKAGE PACKAGE}, {@link #PROTECTED PROTECTED} or {@link #PRIVATE PRIVATE}.
|
||||
* {@link #PROTECTED PROTECTED} is always dropped and so the resulting lookup
|
||||
* mode will never have this access capability. When dropping {@code PACKAGE}
|
||||
* then the resulting lookup will not have {@code PACKAGE} or {@code PRIVATE}
|
||||
* access. When dropping {@code MODULE} then the resulting lookup will not
|
||||
* have {@code MODULE}, {@code PACKAGE}, or {@code PRIVATE} access. If {@code
|
||||
* PUBLIC} is dropped then the resulting lookup has no access.
|
||||
* @param modeToDrop the lookup mode to drop
|
||||
* @return a lookup object which lacks the indicated mode, or the same object if there is no change
|
||||
* @throws IllegalArgumentException if {@code modeToDrop} is not one of {@code PUBLIC},
|
||||
* {@code MODULE}, {@code PACKAGE}, {@code PROTECTED} or {@code PRIVATE}
|
||||
* @since 9
|
||||
* @see MethodHandles#privateLookupIn
|
||||
*/
|
||||
public Lookup dropLookupMode(int modeToDrop) {
|
||||
int oldModes = lookupModes();
|
||||
int newModes = oldModes & ~(modeToDrop | PROTECTED);
|
||||
switch (modeToDrop) {
|
||||
case PUBLIC: newModes &= ~(ALL_MODES); break;
|
||||
case MODULE: newModes &= ~(PACKAGE | PRIVATE); break;
|
||||
case PACKAGE: newModes &= ~(PRIVATE); break;
|
||||
case PROTECTED:
|
||||
case PRIVATE: break;
|
||||
default: throw new IllegalArgumentException(modeToDrop + " is not a valid mode to drop");
|
||||
}
|
||||
if (newModes == oldModes) return this; // return self if no change
|
||||
return new Lookup(lookupClass(), newModes);
|
||||
}
|
||||
|
||||
// Make sure outer class is initialized first.
|
||||
static { IMPL_NAMES.getClass(); }
|
||||
|
||||
|
@ -29,7 +29,6 @@ import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
@ -38,7 +37,6 @@ import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@ -52,7 +50,7 @@ import static jdk.internal.module.Checks.*;
|
||||
import static java.util.Objects.*;
|
||||
|
||||
import jdk.internal.module.Checks;
|
||||
import jdk.internal.module.ModuleHashes;
|
||||
import jdk.internal.module.ModuleInfo;
|
||||
|
||||
|
||||
/**
|
||||
@ -123,8 +121,9 @@ public class ModuleDescriptor
|
||||
|
||||
private final Set<Modifier> mods;
|
||||
private final String name;
|
||||
private final Version compiledVersion;
|
||||
|
||||
private Requires(Set<Modifier> ms, String mn) {
|
||||
private Requires(Set<Modifier> ms, String mn, Version v) {
|
||||
if (ms.isEmpty()) {
|
||||
ms = Collections.emptySet();
|
||||
} else {
|
||||
@ -132,11 +131,13 @@ public class ModuleDescriptor
|
||||
}
|
||||
this.mods = ms;
|
||||
this.name = mn;
|
||||
this.compiledVersion = v;
|
||||
}
|
||||
|
||||
private Requires(Set<Modifier> ms, String mn, boolean unused) {
|
||||
private Requires(Set<Modifier> ms, String mn, Version v, boolean unused) {
|
||||
this.mods = ms;
|
||||
this.name = mn;
|
||||
this.compiledVersion = v;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,13 +158,27 @@ public class ModuleDescriptor
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version of the module if recorded at compile-time.
|
||||
*
|
||||
* @return The version of the module if recorded at compile-time
|
||||
*/
|
||||
public Optional<Version> compiledVersion() {
|
||||
return Optional.ofNullable(compiledVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this module dependence to another.
|
||||
*
|
||||
* <p> Two {@code Requires} objects are compared by comparing their
|
||||
* module name lexicographically. Where the module names are equal then
|
||||
* the sets of modifiers are compared based on a value computed from the
|
||||
* ordinal of each modifier. </p>
|
||||
* ordinal of each modifier. Where the module names are equal and the
|
||||
* set of modifiers are equal then the version of the modules recorded
|
||||
* at compile-time are compared. When comparing the versions recorded
|
||||
* at compile-time then a dependence that has a recorded version is
|
||||
* considered to succeed a dependence that does not have a recorded
|
||||
* version. </p>
|
||||
*
|
||||
* @return A negative integer, zero, or a positive integer if this module
|
||||
* dependence is less than, equal to, or greater than the given
|
||||
@ -174,8 +189,24 @@ public class ModuleDescriptor
|
||||
int c = this.name().compareTo(that.name());
|
||||
if (c != 0)
|
||||
return c;
|
||||
// same name, compare by modifiers
|
||||
return Long.compare(this.modsValue(), that.modsValue());
|
||||
|
||||
// modifiers
|
||||
c = Long.compare(this.modsValue(), that.modsValue());
|
||||
if (c != 0)
|
||||
return c;
|
||||
|
||||
// compiledVersion
|
||||
if (this.compiledVersion != null) {
|
||||
if (that.compiledVersion != null)
|
||||
c = this.compiledVersion.compareTo(that.compiledVersion);
|
||||
else
|
||||
c = 1;
|
||||
} else {
|
||||
if (that.compiledVersion != null)
|
||||
c = -1;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,7 +226,9 @@ public class ModuleDescriptor
|
||||
*
|
||||
* <p> If the given object is not a {@code Requires} then this method
|
||||
* returns {@code false}. Two module dependence objects are equal if
|
||||
* the module names are equal and set of modifiers are equal. </p>
|
||||
* the module names are equal, set of modifiers are equal, and the
|
||||
* compiled version of both modules is equal or not recorded for
|
||||
* both modules. </p>
|
||||
*
|
||||
* <p> This method satisfies the general contract of the {@link
|
||||
* java.lang.Object#equals(Object) Object.equals} method. </p>
|
||||
@ -211,21 +244,25 @@ public class ModuleDescriptor
|
||||
if (!(ob instanceof Requires))
|
||||
return false;
|
||||
Requires that = (Requires)ob;
|
||||
return (name.equals(that.name) && mods.equals(that.mods));
|
||||
return name.equals(that.name) && mods.equals(that.mods)
|
||||
&& Objects.equals(compiledVersion, that.compiledVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a hash code for this module dependence.
|
||||
*
|
||||
* <p> The hash code is based upon the module name and modifiers. It
|
||||
* satisfies the general contract of the {@link Object#hashCode
|
||||
* Object.hashCode} method. </p>
|
||||
* <p> The hash code is based upon the module name, modifiers, and the
|
||||
* module version if recorded at compile time. It satisfies the general
|
||||
* contract of the {@link Object#hashCode Object.hashCode} method. </p>
|
||||
*
|
||||
* @return The hash-code value for this module dependence
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode() * 43 + mods.hashCode();
|
||||
int hash = name.hashCode() * 43 + mods.hashCode();
|
||||
if (compiledVersion != null)
|
||||
hash = hash * 43 + compiledVersion.hashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -235,7 +272,13 @@ public class ModuleDescriptor
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return ModuleDescriptor.toString(mods, name);
|
||||
String what;
|
||||
if (compiledVersion != null) {
|
||||
what = name() + " (@" + compiledVersion + ")";
|
||||
} else {
|
||||
what = name();
|
||||
}
|
||||
return ModuleDescriptor.toString(mods, what);
|
||||
}
|
||||
}
|
||||
|
||||
@ -967,9 +1010,8 @@ public class ModuleDescriptor
|
||||
}
|
||||
|
||||
|
||||
|
||||
// From module declarations
|
||||
private final String name;
|
||||
private final Version version;
|
||||
private final boolean open;
|
||||
|
||||
// Indicates if synthesised for a JAR file found on the module path
|
||||
@ -984,17 +1026,16 @@ public class ModuleDescriptor
|
||||
private final Set<String> uses;
|
||||
private final Set<Provides> provides;
|
||||
|
||||
// "Extended" information, added post-compilation by tools
|
||||
private final Version version;
|
||||
// Added post-compilation by tools
|
||||
private final Set<String> packages;
|
||||
private final String mainClass;
|
||||
private final String osName;
|
||||
private final String osArch;
|
||||
private final String osVersion;
|
||||
private final Set<String> packages;
|
||||
private final ModuleHashes hashes;
|
||||
|
||||
|
||||
private ModuleDescriptor(String name,
|
||||
Version version,
|
||||
boolean open,
|
||||
boolean automatic,
|
||||
boolean synthetic,
|
||||
@ -1003,16 +1044,14 @@ public class ModuleDescriptor
|
||||
Set<Opens> opens,
|
||||
Set<String> uses,
|
||||
Set<Provides> provides,
|
||||
Version version,
|
||||
Set<String> packages,
|
||||
String mainClass,
|
||||
String osName,
|
||||
String osArch,
|
||||
String osVersion,
|
||||
Set<String> packages,
|
||||
ModuleHashes hashes)
|
||||
String osVersion)
|
||||
{
|
||||
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
this.open = open;
|
||||
this.automatic = automatic;
|
||||
this.synthetic = synthetic;
|
||||
@ -1020,18 +1059,16 @@ public class ModuleDescriptor
|
||||
assert (requires.stream().map(Requires::name).distinct().count()
|
||||
== requires.size());
|
||||
this.requires = emptyOrUnmodifiableSet(requires);
|
||||
|
||||
this.exports = emptyOrUnmodifiableSet(exports);
|
||||
this.opens = emptyOrUnmodifiableSet(opens);
|
||||
this.uses = emptyOrUnmodifiableSet(uses);
|
||||
this.provides = emptyOrUnmodifiableSet(provides);
|
||||
this.version = version;
|
||||
|
||||
this.packages = emptyOrUnmodifiableSet(packages);
|
||||
this.mainClass = mainClass;
|
||||
this.osName = osName;
|
||||
this.osArch = osArch;
|
||||
this.osVersion = osVersion;
|
||||
this.hashes = hashes;
|
||||
this.packages = emptyOrUnmodifiableSet(packages);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1039,6 +1076,7 @@ public class ModuleDescriptor
|
||||
*/
|
||||
ModuleDescriptor(ModuleDescriptor md, Set<String> pkgs) {
|
||||
this.name = md.name;
|
||||
this.version = md.version;
|
||||
this.open = md.open;
|
||||
this.automatic = md.automatic;
|
||||
this.synthetic = md.synthetic;
|
||||
@ -1049,16 +1087,14 @@ public class ModuleDescriptor
|
||||
this.uses = md.uses;
|
||||
this.provides = md.provides;
|
||||
|
||||
this.version = md.version;
|
||||
Set<String> packages = new HashSet<>(md.packages);
|
||||
packages.addAll(pkgs);
|
||||
this.packages = emptyOrUnmodifiableSet(packages);
|
||||
|
||||
this.mainClass = md.mainClass;
|
||||
this.osName = md.osName;
|
||||
this.osArch = md.osArch;
|
||||
this.osVersion = md.osVersion;
|
||||
this.hashes = null; // need to ignore
|
||||
|
||||
Set<String> packages = new HashSet<>(md.packages);
|
||||
packages.addAll(pkgs);
|
||||
this.packages = emptyOrUnmodifiableSet(packages);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1066,6 +1102,7 @@ public class ModuleDescriptor
|
||||
* The arguments are pre-validated and sets are unmodifiable sets.
|
||||
*/
|
||||
ModuleDescriptor(String name,
|
||||
Version version,
|
||||
boolean open,
|
||||
boolean automatic,
|
||||
boolean synthetic,
|
||||
@ -1074,16 +1111,15 @@ public class ModuleDescriptor
|
||||
Set<Opens> opens,
|
||||
Set<String> uses,
|
||||
Set<Provides> provides,
|
||||
Version version,
|
||||
Set<String> packages,
|
||||
String mainClass,
|
||||
String osName,
|
||||
String osArch,
|
||||
String osVersion,
|
||||
Set<String> packages,
|
||||
ModuleHashes hashes,
|
||||
int hashCode,
|
||||
boolean unused) {
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
this.open = open;
|
||||
this.automatic = automatic;
|
||||
this.synthetic = synthetic;
|
||||
@ -1093,12 +1129,10 @@ public class ModuleDescriptor
|
||||
this.uses = uses;
|
||||
this.provides = provides;
|
||||
this.packages = packages;
|
||||
this.version = version;
|
||||
this.mainClass = mainClass;
|
||||
this.osName = osName;
|
||||
this.osArch = osArch;
|
||||
this.osVersion = osVersion;
|
||||
this.hashes = hashes;
|
||||
this.hash = hashCode;
|
||||
}
|
||||
|
||||
@ -1284,13 +1318,6 @@ public class ModuleDescriptor
|
||||
return packages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object with the hashes of other modules
|
||||
*/
|
||||
Optional<ModuleHashes> hashes() {
|
||||
return Optional.ofNullable(hashes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A builder used for building {@link ModuleDescriptor} objects.
|
||||
@ -1317,15 +1344,13 @@ public class ModuleDescriptor
|
||||
public static final class Builder {
|
||||
final String name;
|
||||
final boolean strict; // true if module names are checked
|
||||
boolean open;
|
||||
final boolean open;
|
||||
final boolean synthetic;
|
||||
boolean automatic;
|
||||
boolean synthetic;
|
||||
final Map<String, Requires> requires = new HashMap<>();
|
||||
|
||||
final Map<String, Exports> exports = new HashMap<>();
|
||||
final Map<String, Opens> opens = new HashMap<>();
|
||||
final Set<String> concealedPackages = new HashSet<>();
|
||||
|
||||
final Set<String> uses = new HashSet<>();
|
||||
final Map<String, Provides> provides = new HashMap<>();
|
||||
Version version;
|
||||
@ -1333,7 +1358,6 @@ public class ModuleDescriptor
|
||||
String osArch;
|
||||
String osVersion;
|
||||
String mainClass;
|
||||
ModuleHashes hashes;
|
||||
|
||||
/**
|
||||
* Initializes a new builder with the given module name.
|
||||
@ -1341,14 +1365,11 @@ public class ModuleDescriptor
|
||||
* @param strict
|
||||
* Indicates whether module names are checked or not
|
||||
*/
|
||||
Builder(String name, boolean strict) {
|
||||
this.strict = strict;
|
||||
Builder(String name, boolean strict, boolean open, boolean synthetic) {
|
||||
this.name = (strict) ? requireModuleName(name) : name;
|
||||
}
|
||||
|
||||
/* package */ Builder open(boolean open) {
|
||||
this.strict = strict;
|
||||
this.open = open;
|
||||
return this;
|
||||
this.synthetic = synthetic;
|
||||
}
|
||||
|
||||
/* package */ Builder automatic(boolean automatic) {
|
||||
@ -1356,10 +1377,20 @@ public class ModuleDescriptor
|
||||
return this;
|
||||
}
|
||||
|
||||
/* package */ boolean isOpen() { return open; }
|
||||
/**
|
||||
* Returns the set of packages that are exported (unconditionally or
|
||||
* unconditionally).
|
||||
*/
|
||||
/* package */ Set<String> exportedPackages() {
|
||||
return exports.keySet();
|
||||
}
|
||||
|
||||
/* package */ boolean isAutomatic() {
|
||||
return automatic;
|
||||
/**
|
||||
* Returns the set of packages that are opened (unconditionally or
|
||||
* unconditionally).
|
||||
*/
|
||||
/* package */Set<String> openPackages() {
|
||||
return opens.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1387,6 +1418,36 @@ public class ModuleDescriptor
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dependence on a module with the given (and possibly empty)
|
||||
* set of modifiers. The dependence includes the version of the
|
||||
* module that that was recorded at compile-time.
|
||||
*
|
||||
* @param ms
|
||||
* The set of modifiers
|
||||
* @param mn
|
||||
* The module name
|
||||
* @param compiledVersion
|
||||
* The version of the module recorded at compile-time
|
||||
*
|
||||
* @return This builder
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If the module name is {@code null}, is not a legal Java
|
||||
* identifier, or is equal to the module name that this builder
|
||||
* was initialized to build
|
||||
* @throws IllegalStateException
|
||||
* If the dependence on the module has already been declared
|
||||
*/
|
||||
public Builder requires(Set<Requires.Modifier> ms,
|
||||
String mn,
|
||||
Version compiledVersion) {
|
||||
Objects.requireNonNull(compiledVersion);
|
||||
if (strict)
|
||||
mn = requireModuleName(mn);
|
||||
return requires(new Requires(ms, mn, compiledVersion));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dependence on a module with the given (and possibly empty)
|
||||
* set of modifiers.
|
||||
@ -1408,7 +1469,7 @@ public class ModuleDescriptor
|
||||
public Builder requires(Set<Requires.Modifier> ms, String mn) {
|
||||
if (strict)
|
||||
mn = requireModuleName(mn);
|
||||
return requires(new Requires(ms, mn));
|
||||
return requires(new Requires(ms, mn, null));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1705,17 +1766,6 @@ public class ModuleDescriptor
|
||||
return opens(Collections.emptySet(), pn);
|
||||
}
|
||||
|
||||
|
||||
// Used by ModuleInfo, after a packageFinder is invoked
|
||||
/* package */ Set<String> exportedAndOpenPackages() {
|
||||
if (opens.isEmpty())
|
||||
return exports.keySet();
|
||||
Set<String> result = new HashSet<>();
|
||||
result.addAll(exports.keySet());
|
||||
result.addAll(opens.keySet());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a service dependence.
|
||||
*
|
||||
@ -1789,7 +1839,6 @@ public class ModuleDescriptor
|
||||
if (providerNames.isEmpty())
|
||||
throw new IllegalArgumentException("Empty providers set");
|
||||
providerNames.forEach(Checks::requireServiceProviderName);
|
||||
|
||||
provides.put(service, p);
|
||||
return this;
|
||||
}
|
||||
@ -1914,7 +1963,7 @@ public class ModuleDescriptor
|
||||
* If {@code mainClass} is null or is not a legal Java identifier
|
||||
*/
|
||||
public Builder mainClass(String mc) {
|
||||
mainClass = requireJavaIdentifier("main class name", mc);
|
||||
mainClass = requireBinaryName("main class name", mc);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -1972,16 +2021,6 @@ public class ModuleDescriptor
|
||||
return this;
|
||||
}
|
||||
|
||||
/* package */ Builder hashes(ModuleHashes hashes) {
|
||||
this.hashes = hashes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/* package */ Builder synthetic(boolean v) {
|
||||
this.synthetic = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and returns a {@code ModuleDescriptor} from its components.
|
||||
*
|
||||
@ -1990,7 +2029,9 @@ public class ModuleDescriptor
|
||||
public ModuleDescriptor build() {
|
||||
Set<Requires> requires = new HashSet<>(this.requires.values());
|
||||
|
||||
Set<String> packages = new HashSet<>(exportedAndOpenPackages());
|
||||
Set<String> packages = new HashSet<>();
|
||||
packages.addAll(exports.keySet());
|
||||
packages.addAll(opens.keySet());
|
||||
packages.addAll(concealedPackages);
|
||||
|
||||
Set<Exports> exports = new HashSet<>(this.exports.values());
|
||||
@ -1999,6 +2040,7 @@ public class ModuleDescriptor
|
||||
Set<Provides> provides = new HashSet<>(this.provides.values());
|
||||
|
||||
return new ModuleDescriptor(name,
|
||||
version,
|
||||
open,
|
||||
automatic,
|
||||
synthetic,
|
||||
@ -2007,13 +2049,11 @@ public class ModuleDescriptor
|
||||
opens,
|
||||
uses,
|
||||
provides,
|
||||
version,
|
||||
packages,
|
||||
mainClass,
|
||||
osName,
|
||||
osArch,
|
||||
osVersion,
|
||||
packages,
|
||||
hashes);
|
||||
osVersion);
|
||||
}
|
||||
|
||||
}
|
||||
@ -2088,8 +2128,7 @@ public class ModuleDescriptor
|
||||
&& Objects.equals(osName, that.osName)
|
||||
&& Objects.equals(osArch, that.osArch)
|
||||
&& Objects.equals(osVersion, that.osVersion)
|
||||
&& Objects.equals(packages, that.packages)
|
||||
&& Objects.equals(hashes, that.hashes));
|
||||
&& Objects.equals(packages, that.packages));
|
||||
}
|
||||
|
||||
private transient int hash; // cached hash code
|
||||
@ -2122,7 +2161,6 @@ public class ModuleDescriptor
|
||||
hc = hc * 43 + Objects.hashCode(osArch);
|
||||
hc = hc * 43 + Objects.hashCode(osVersion);
|
||||
hc = hc * 43 + Objects.hashCode(packages);
|
||||
hc = hc * 43 + Objects.hashCode(hashes);
|
||||
if (hc == 0)
|
||||
hc = -1;
|
||||
hash = hc;
|
||||
@ -2145,7 +2183,7 @@ public class ModuleDescriptor
|
||||
if (!requires.isEmpty())
|
||||
sb.append(", ").append(requires);
|
||||
if (!uses.isEmpty())
|
||||
sb.append(", ").append(uses);
|
||||
sb.append(", uses: ").append(uses);
|
||||
if (!exports.isEmpty())
|
||||
sb.append(", exports: ").append(exports);
|
||||
if (!opens.isEmpty())
|
||||
@ -2171,7 +2209,7 @@ public class ModuleDescriptor
|
||||
* identifier
|
||||
*/
|
||||
public static Builder module(String name) {
|
||||
return new Builder(name, true);
|
||||
return new Builder(name, true, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2199,7 +2237,7 @@ public class ModuleDescriptor
|
||||
* identifier
|
||||
*/
|
||||
public static Builder openModule(String name) {
|
||||
return new Builder(name, true).open(true);
|
||||
return new Builder(name, true, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2221,7 +2259,7 @@ public class ModuleDescriptor
|
||||
* @see ModuleFinder#of(Path[])
|
||||
*/
|
||||
public static Builder automaticModule(String name) {
|
||||
return new Builder(name, true).automatic(true);
|
||||
return new Builder(name, true, false, false).automatic(true);
|
||||
}
|
||||
|
||||
|
||||
@ -2263,7 +2301,7 @@ public class ModuleDescriptor
|
||||
Supplier<Set<String>> packageFinder)
|
||||
throws IOException
|
||||
{
|
||||
return ModuleInfo.read(in, requireNonNull(packageFinder));
|
||||
return ModuleInfo.read(in, requireNonNull(packageFinder)).descriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2281,7 +2319,7 @@ public class ModuleDescriptor
|
||||
* If an I/O error occurs reading from the input stream
|
||||
*/
|
||||
public static ModuleDescriptor read(InputStream in) throws IOException {
|
||||
return ModuleInfo.read(in, null);
|
||||
return ModuleInfo.read(in, null).descriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2320,7 +2358,7 @@ public class ModuleDescriptor
|
||||
public static ModuleDescriptor read(ByteBuffer bb,
|
||||
Supplier<Set<String>> packageFinder)
|
||||
{
|
||||
return ModuleInfo.read(bb, requireNonNull(packageFinder));
|
||||
return ModuleInfo.read(bb, requireNonNull(packageFinder)).descriptor();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2336,7 +2374,7 @@ public class ModuleDescriptor
|
||||
* If an invalid module descriptor is detected
|
||||
*/
|
||||
public static ModuleDescriptor read(ByteBuffer bb) {
|
||||
return ModuleInfo.read(bb, null);
|
||||
return ModuleInfo.read(bb, null).descriptor();
|
||||
}
|
||||
|
||||
private static <K,V> Map<K,V> emptyOrUnmodifiableMap(Map<K,V> map) {
|
||||
@ -2377,18 +2415,26 @@ public class ModuleDescriptor
|
||||
jdk.internal.misc.SharedSecrets
|
||||
.setJavaLangModuleAccess(new jdk.internal.misc.JavaLangModuleAccess() {
|
||||
@Override
|
||||
public Builder newModuleBuilder(String mn, boolean strict) {
|
||||
return new Builder(mn, strict);
|
||||
public Builder newModuleBuilder(String mn,
|
||||
boolean strict,
|
||||
boolean open,
|
||||
boolean synthetic) {
|
||||
return new Builder(mn, strict, open, synthetic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder newOpenModuleBuilder(String mn, boolean strict) {
|
||||
return new Builder(mn, strict).open(true);
|
||||
public Set<String> exportedPackages(ModuleDescriptor.Builder builder) {
|
||||
return builder.exportedPackages();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Requires newRequires(Set<Requires.Modifier> ms, String mn) {
|
||||
return new Requires(ms, mn, true);
|
||||
public Set<String> openPackages(ModuleDescriptor.Builder builder) {
|
||||
return builder.openPackages();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Requires newRequires(Set<Requires.Modifier> ms, String mn, Version v) {
|
||||
return new Requires(ms, mn, v, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2433,6 +2479,7 @@ public class ModuleDescriptor
|
||||
|
||||
@Override
|
||||
public ModuleDescriptor newModuleDescriptor(String name,
|
||||
Version version,
|
||||
boolean open,
|
||||
boolean automatic,
|
||||
boolean synthetic,
|
||||
@ -2441,15 +2488,14 @@ public class ModuleDescriptor
|
||||
Set<Opens> opens,
|
||||
Set<String> uses,
|
||||
Set<Provides> provides,
|
||||
Version version,
|
||||
Set<String> packages,
|
||||
String mainClass,
|
||||
String osName,
|
||||
String osArch,
|
||||
String osVersion,
|
||||
Set<String> packages,
|
||||
ModuleHashes hashes,
|
||||
int hashCode) {
|
||||
return new ModuleDescriptor(name,
|
||||
version,
|
||||
open,
|
||||
automatic,
|
||||
synthetic,
|
||||
@ -2458,22 +2504,15 @@ public class ModuleDescriptor
|
||||
opens,
|
||||
uses,
|
||||
provides,
|
||||
version,
|
||||
packages,
|
||||
mainClass,
|
||||
osName,
|
||||
osArch,
|
||||
osVersion,
|
||||
packages,
|
||||
hashes,
|
||||
hashCode,
|
||||
false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ModuleHashes> hashes(ModuleDescriptor descriptor) {
|
||||
return descriptor.hashes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configuration resolveRequiresAndUses(ModuleFinder finder,
|
||||
Collection<String> roots,
|
||||
@ -2482,20 +2521,6 @@ public class ModuleDescriptor
|
||||
{
|
||||
return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleReference newPatchedModule(ModuleDescriptor descriptor,
|
||||
URI location,
|
||||
Supplier<ModuleReader> s) {
|
||||
return new ModuleReference(descriptor, location, s, true, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleFinder newModulePath(Runtime.Version version,
|
||||
boolean isLinkPhase,
|
||||
Path... entries) {
|
||||
return new ModulePath(version, isLinkPhase, entries);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,8 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.internal.module.ModulePath;
|
||||
import jdk.internal.module.SystemModuleFinder;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
@ -137,7 +139,7 @@ public interface ModuleFinder {
|
||||
|
||||
/**
|
||||
* Returns a module finder that locates the <em>system modules</em>. The
|
||||
* system modules are typically linked into the Java run-time image.
|
||||
* system modules are the modules in the Java run-time image.
|
||||
* The module finder will always find {@code java.base}.
|
||||
*
|
||||
* <p> If there is a security manager set then its {@link
|
||||
@ -166,7 +168,7 @@ public interface ModuleFinder {
|
||||
|
||||
Path modules = Paths.get(home, "lib", "modules");
|
||||
if (Files.isRegularFile(modules)) {
|
||||
return new SystemModuleFinder();
|
||||
return SystemModuleFinder.getInstance();
|
||||
} else {
|
||||
Path mlib = Paths.get(home, "modules");
|
||||
if (Files.isDirectory(mlib)) {
|
||||
|
@ -26,96 +26,42 @@
|
||||
package java.lang.module;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.URI;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import jdk.internal.module.ModuleHashes.HashSupplier;
|
||||
|
||||
|
||||
/**
|
||||
* A reference to a module's content.
|
||||
*
|
||||
* <p> A module reference contains the module's descriptor and its location, if
|
||||
* known. It also has the ability to create a {@link ModuleReader} in order to
|
||||
* access the module's content, which may be inside the Java run-time system
|
||||
* itself or in an artifact such as a modular JAR file.
|
||||
* <p> A module reference is a concrete implementation of this class that
|
||||
* implements the abstract methods defined by this class. It contains the
|
||||
* module's descriptor and its location, if known. It also has the ability to
|
||||
* create a {@link ModuleReader} in order to access the module's content, which
|
||||
* may be inside the Java run-time system itself or in an artifact such as a
|
||||
* modular JAR file.
|
||||
*
|
||||
* @see ModuleFinder
|
||||
* @see ModuleReader
|
||||
* @since 9
|
||||
*/
|
||||
|
||||
public final class ModuleReference {
|
||||
public abstract class ModuleReference {
|
||||
|
||||
private final ModuleDescriptor descriptor;
|
||||
private final URI location;
|
||||
private final Supplier<ModuleReader> readerSupplier;
|
||||
|
||||
// true if this is a reference to a patched module
|
||||
private boolean patched;
|
||||
|
||||
// the function that computes the hash of this module reference
|
||||
private final HashSupplier hasher;
|
||||
|
||||
// cached hash to avoid needing to compute it many times
|
||||
private byte[] cachedHash;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*/
|
||||
ModuleReference(ModuleDescriptor descriptor,
|
||||
URI location,
|
||||
Supplier<ModuleReader> readerSupplier,
|
||||
boolean patched,
|
||||
HashSupplier hasher)
|
||||
|
||||
{
|
||||
this.descriptor = Objects.requireNonNull(descriptor);
|
||||
this.location = location;
|
||||
this.readerSupplier = Objects.requireNonNull(readerSupplier);
|
||||
this.patched = patched;
|
||||
this.hasher = hasher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*/
|
||||
ModuleReference(ModuleDescriptor descriptor,
|
||||
URI location,
|
||||
Supplier<ModuleReader> readerSupplier,
|
||||
HashSupplier hasher)
|
||||
|
||||
{
|
||||
this(descriptor, location, readerSupplier, false, hasher);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*
|
||||
* <p> The {@code readSupplier} parameter is the supplier of the {@link
|
||||
* ModuleReader} that may be used to read the module content. Its {@link
|
||||
* Supplier#get() get()} method throws {@link UncheckedIOException} if an
|
||||
* I/O error occurs opening the module content. The {@code get()} method
|
||||
* throws {@link SecurityException} if opening the module is denied by the
|
||||
* security manager.
|
||||
*
|
||||
* @param descriptor
|
||||
* The module descriptor
|
||||
* @param location
|
||||
* The module location or {@code null} if not known
|
||||
* @param readerSupplier
|
||||
* The {@code Supplier} of the {@code ModuleReader}
|
||||
*/
|
||||
public ModuleReference(ModuleDescriptor descriptor,
|
||||
URI location,
|
||||
Supplier<ModuleReader> readerSupplier)
|
||||
{
|
||||
this(descriptor, location, readerSupplier, false, null);
|
||||
protected ModuleReference(ModuleDescriptor descriptor, URI location) {
|
||||
this.descriptor = Objects.requireNonNull(descriptor);
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,11 +69,10 @@ public final class ModuleReference {
|
||||
*
|
||||
* @return The module descriptor
|
||||
*/
|
||||
public ModuleDescriptor descriptor() {
|
||||
public final ModuleDescriptor descriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the location of this module's content, if known.
|
||||
*
|
||||
@ -139,18 +84,13 @@ public final class ModuleReference {
|
||||
*
|
||||
* @return The location or an empty {@code Optional} if not known
|
||||
*/
|
||||
public Optional<URI> location() {
|
||||
public final Optional<URI> location() {
|
||||
return Optional.ofNullable(location);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Opens the module content for reading.
|
||||
*
|
||||
* <p> This method opens the module content by invoking the {@link
|
||||
* Supplier#get() get()} method of the {@code readSupplier} specified at
|
||||
* construction time. </p>
|
||||
*
|
||||
* @return A {@code ModuleReader} to read the module
|
||||
*
|
||||
* @throws IOException
|
||||
@ -158,113 +98,5 @@ public final class ModuleReference {
|
||||
* @throws SecurityException
|
||||
* If denied by the security manager
|
||||
*/
|
||||
public ModuleReader open() throws IOException {
|
||||
try {
|
||||
return readerSupplier.get();
|
||||
} catch (UncheckedIOException e) {
|
||||
throw e.getCause();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this module has been patched via --patch-module.
|
||||
*/
|
||||
boolean isPatched() {
|
||||
return patched;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash supplier for this module.
|
||||
*/
|
||||
HashSupplier hasher() {
|
||||
return hasher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the hash of this module. Returns {@code null} if the hash
|
||||
* cannot be computed.
|
||||
*
|
||||
* @throws java.io.UncheckedIOException if an I/O error occurs
|
||||
*/
|
||||
byte[] computeHash(String algorithm) {
|
||||
byte[] result = cachedHash;
|
||||
if (result != null)
|
||||
return result;
|
||||
if (hasher == null)
|
||||
return null;
|
||||
cachedHash = result = hasher.generate(algorithm);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a hash code for this module reference.
|
||||
*
|
||||
* <p> The hash code is based upon the components of the reference, and
|
||||
* satisfies the general contract of the {@link Object#hashCode
|
||||
* Object.hashCode} method. </p>
|
||||
*
|
||||
* @return The hash-code value for this module reference
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hc = hash;
|
||||
if (hc == 0) {
|
||||
hc = descriptor.hashCode();
|
||||
hc = 43 * hc + readerSupplier.hashCode();
|
||||
hc = 43 * hc + Objects.hashCode(location);
|
||||
hc = 43 * hc + Objects.hashCode(hasher);
|
||||
hc = 43 * hc + Boolean.hashCode(patched);
|
||||
if (hc == 0)
|
||||
hc = -1;
|
||||
hash = hc;
|
||||
}
|
||||
return hc;
|
||||
}
|
||||
|
||||
private int hash;
|
||||
|
||||
/**
|
||||
* Tests this module reference for equality with the given object.
|
||||
*
|
||||
* <p> If the given object is not a {@code ModuleReference} then this
|
||||
* method returns {@code false}. Two module references are equal if their
|
||||
* module descriptors are equal, their locations are equal or both unknown,
|
||||
* and were created with equal supplier objects to access the module
|
||||
* content. </p>
|
||||
*
|
||||
* <p> This method satisfies the general contract of the {@link
|
||||
* java.lang.Object#equals(Object) Object.equals} method. </p>
|
||||
*
|
||||
* @param ob
|
||||
* the object to which this object is to be compared
|
||||
*
|
||||
* @return {@code true} if, and only if, the given object is a module
|
||||
* reference that is equal to this module reference
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object ob) {
|
||||
if (!(ob instanceof ModuleReference))
|
||||
return false;
|
||||
ModuleReference that = (ModuleReference)ob;
|
||||
|
||||
return Objects.equals(this.descriptor, that.descriptor)
|
||||
&& Objects.equals(this.location, that.location)
|
||||
&& Objects.equals(this.readerSupplier, that.readerSupplier)
|
||||
&& Objects.equals(this.hasher, that.hasher)
|
||||
&& this.patched == that.patched;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing this module reference.
|
||||
*
|
||||
* @return A string describing this module reference
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return ("[module " + descriptor().name()
|
||||
+ ", location=" + location + "]");
|
||||
}
|
||||
|
||||
public abstract ModuleReader open() throws IOException;
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jdk.internal.module.ModuleHashes;
|
||||
import jdk.internal.module.ModuleReferenceImpl;
|
||||
|
||||
/**
|
||||
* The resolver used by {@link Configuration#resolveRequires} and
|
||||
@ -438,24 +439,32 @@ final class Resolver {
|
||||
*/
|
||||
private void checkHashes() {
|
||||
for (ModuleReference mref : nameToReference.values()) {
|
||||
ModuleDescriptor descriptor = mref.descriptor();
|
||||
|
||||
// get map of module hashes
|
||||
Optional<ModuleHashes> ohashes = descriptor.hashes();
|
||||
if (!ohashes.isPresent())
|
||||
// get the recorded hashes, if any
|
||||
if (!(mref instanceof ModuleReferenceImpl))
|
||||
continue;
|
||||
ModuleHashes hashes = ((ModuleReferenceImpl)mref).recordedHashes();
|
||||
if (hashes == null)
|
||||
continue;
|
||||
ModuleHashes hashes = ohashes.get();
|
||||
|
||||
ModuleDescriptor descriptor = mref.descriptor();
|
||||
String algorithm = hashes.algorithm();
|
||||
for (String dn : hashes.names()) {
|
||||
ModuleReference other = nameToReference.get(dn);
|
||||
if (other == null) {
|
||||
ModuleReference mref2 = nameToReference.get(dn);
|
||||
if (mref2 == null) {
|
||||
ResolvedModule resolvedModule = findInParent(dn);
|
||||
if (resolvedModule != null)
|
||||
other = resolvedModule.reference();
|
||||
mref2 = resolvedModule.reference();
|
||||
}
|
||||
if (mref2 == null)
|
||||
continue;
|
||||
|
||||
if (!(mref2 instanceof ModuleReferenceImpl)) {
|
||||
fail("Unable to compute the hash of module %s", dn);
|
||||
}
|
||||
|
||||
// skip checking the hash if the module has been patched
|
||||
ModuleReferenceImpl other = (ModuleReferenceImpl)mref2;
|
||||
if (other != null && !other.isPatched()) {
|
||||
byte[] recordedHash = hashes.hashFor(dn);
|
||||
byte[] actualHash = other.computeHash(algorithm);
|
||||
|
@ -28,9 +28,11 @@ package java.lang.reflect;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.security.AccessController;
|
||||
|
||||
import jdk.internal.misc.VM;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import jdk.internal.reflect.ReflectionFactory;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* The AccessibleObject class is the base class for Field, Method and
|
||||
@ -172,8 +174,10 @@ public class AccessibleObject implements AnnotatedElement {
|
||||
|
||||
// package is open to caller
|
||||
String pn = packageName(declaringClass);
|
||||
if (declaringModule.isOpen(pn, callerModule))
|
||||
if (declaringModule.isOpen(pn, callerModule)) {
|
||||
printStackTraceIfOpenedReflectively(declaringModule, pn, callerModule);
|
||||
return;
|
||||
}
|
||||
|
||||
// package is exported to caller and class/member is public
|
||||
boolean isExported = declaringModule.isExported(pn, callerModule);
|
||||
@ -185,8 +189,10 @@ public class AccessibleObject implements AnnotatedElement {
|
||||
modifiers = ((Field) this).getModifiers();
|
||||
}
|
||||
boolean isMemberPublic = Modifier.isPublic(modifiers);
|
||||
if (isExported && isClassPublic && isMemberPublic)
|
||||
if (isExported && isClassPublic && isMemberPublic) {
|
||||
printStackTraceIfExportedReflectively(declaringModule, pn, callerModule);
|
||||
return;
|
||||
}
|
||||
|
||||
// not accessible
|
||||
String msg = "Unable to make ";
|
||||
@ -198,7 +204,44 @@ public class AccessibleObject implements AnnotatedElement {
|
||||
else
|
||||
msg += "opens";
|
||||
msg += " " + pn + "\" to " + callerModule;
|
||||
Reflection.throwInaccessibleObjectException(msg);
|
||||
InaccessibleObjectException e = new InaccessibleObjectException(msg);
|
||||
if (Reflection.printStackTraceWhenAccessFails()) {
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
private void printStackTraceIfOpenedReflectively(Module module,
|
||||
String pn,
|
||||
Module other) {
|
||||
printStackTraceIfExposedReflectively(module, pn, other, true);
|
||||
}
|
||||
|
||||
private void printStackTraceIfExportedReflectively(Module module,
|
||||
String pn,
|
||||
Module other) {
|
||||
printStackTraceIfExposedReflectively(module, pn, other, false);
|
||||
}
|
||||
|
||||
private void printStackTraceIfExposedReflectively(Module module,
|
||||
String pn,
|
||||
Module other,
|
||||
boolean open)
|
||||
{
|
||||
if (Reflection.printStackTraceWhenAccessSucceeds()
|
||||
&& !module.isStaticallyExportedOrOpen(pn, other, open))
|
||||
{
|
||||
String msg = other + " allowed to invoke setAccessible on ";
|
||||
if (this instanceof Field)
|
||||
msg += "field ";
|
||||
msg += this;
|
||||
new Exception(msg) {
|
||||
private static final long serialVersionUID = 42L;
|
||||
public String toString() {
|
||||
return "WARNING: " + getMessage();
|
||||
}
|
||||
}.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,7 +245,6 @@ public final class Layer {
|
||||
* @see Module#addOpens
|
||||
*/
|
||||
public Controller addOpens(Module source, String pn, Module target) {
|
||||
Objects.requireNonNull(source);
|
||||
Objects.requireNonNull(source);
|
||||
Objects.requireNonNull(target);
|
||||
ensureInLayer(source);
|
||||
@ -541,7 +540,7 @@ public final class Layer {
|
||||
* {@link ClassLoader#registerAsParallelCapable parallel-capable} so as to
|
||||
* avoid deadlocks during class loading. In addition, the entity creating
|
||||
* a new layer with this method should arrange that the class loaders are
|
||||
* ready to load from these module before there are any attempts to load
|
||||
* ready to load from these modules before there are any attempts to load
|
||||
* classes or resources.
|
||||
*
|
||||
* <p> Creating a {@code Layer} can fail for the following reasons: </p>
|
||||
|
@ -559,7 +559,7 @@ public final class Module implements AnnotatedElement {
|
||||
* Returns {@code true} if this module exports or opens a package to
|
||||
* the given module via its module declaration.
|
||||
*/
|
||||
private boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
|
||||
boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
|
||||
// package is open to everyone or <other>
|
||||
Map<String, Set<Module>> openPackages = this.openPackages;
|
||||
if (openPackages != null) {
|
||||
@ -643,6 +643,12 @@ public final class Module implements AnnotatedElement {
|
||||
* <em>open</em>) to the given module. It also has no effect if
|
||||
* invoked on an {@link ModuleDescriptor#isOpen open} module. </p>
|
||||
*
|
||||
* @apiNote As specified in section 5.4.3 of the <cite>The Java™
|
||||
* Virtual Machine Specification </cite>, if an attempt to resolve a
|
||||
* symbolic reference fails because of a linkage error, then subsequent
|
||||
* attempts to resolve the reference always fail with the same error that
|
||||
* was thrown as a result of the initial resolution attempt.
|
||||
*
|
||||
* @param pn
|
||||
* The package name
|
||||
* @param other
|
||||
@ -656,6 +662,7 @@ public final class Module implements AnnotatedElement {
|
||||
* @throws IllegalStateException
|
||||
* If this is a named module and the caller is not this module
|
||||
*
|
||||
* @jvms 5.4.3 Resolution
|
||||
* @see #isExported(String,Module)
|
||||
*/
|
||||
@CallerSensitive
|
||||
@ -676,8 +683,8 @@ public final class Module implements AnnotatedElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* If the caller's module is this module then update this module to
|
||||
* <em>open</em> the given package to the given module.
|
||||
* If this module has <em>opened</em> a package to at least the caller
|
||||
* module then update this module to open the package to the given module.
|
||||
* Opening a package with this method allows all types in the package,
|
||||
* and all their members, not just public types and their public members,
|
||||
* to be reflected on by the given module when using APIs that support
|
||||
@ -699,7 +706,8 @@ public final class Module implements AnnotatedElement {
|
||||
* If {@code pn} is {@code null}, or this is a named module and the
|
||||
* package {@code pn} is not a package in this module
|
||||
* @throws IllegalStateException
|
||||
* If this is a named module and the caller is not this module
|
||||
* If this is a named module and this module has not opened the
|
||||
* package to at least the caller
|
||||
*
|
||||
* @see #isOpen(String,Module)
|
||||
* @see AccessibleObject#setAccessible(boolean)
|
||||
@ -713,9 +721,8 @@ public final class Module implements AnnotatedElement {
|
||||
|
||||
if (isNamed() && !descriptor.isOpen()) {
|
||||
Module caller = Reflection.getCallerClass().getModule();
|
||||
if (caller != this) {
|
||||
throw new IllegalStateException(caller + " != " + this);
|
||||
}
|
||||
if (caller != this && !isOpen(pn, caller))
|
||||
throw new IllegalStateException(pn + " is not open to " + caller);
|
||||
implAddExportsOrOpens(pn, other, /*open*/true, /*syncVM*/true);
|
||||
}
|
||||
|
||||
@ -1568,6 +1575,10 @@ public final class Module implements AnnotatedElement {
|
||||
public Stream<Layer> layers(ClassLoader loader) {
|
||||
return Layer.layers(loader);
|
||||
}
|
||||
@Override
|
||||
public boolean isStaticallyExported(Module module, String pn, Module other) {
|
||||
return module.isStaticallyExportedOrOpen(pn, other, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -452,6 +452,10 @@ public abstract class Signature extends SignatureSpi {
|
||||
return this.provider;
|
||||
}
|
||||
|
||||
private String getProviderName() {
|
||||
return (provider == null) ? "(no provider)" : provider.getName();
|
||||
}
|
||||
|
||||
void chooseFirstProvider() {
|
||||
// empty, overridden in Delegate
|
||||
}
|
||||
@ -473,7 +477,7 @@ public abstract class Signature extends SignatureSpi {
|
||||
|
||||
if (!skipDebug && pdebug != null) {
|
||||
pdebug.println("Signature." + algorithm +
|
||||
" verification algorithm from: " + this.provider.getName());
|
||||
" verification algorithm from: " + getProviderName());
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,7 +526,7 @@ public abstract class Signature extends SignatureSpi {
|
||||
|
||||
if (!skipDebug && pdebug != null) {
|
||||
pdebug.println("Signature." + algorithm +
|
||||
" verification algorithm from: " + this.provider.getName());
|
||||
" verification algorithm from: " + getProviderName());
|
||||
}
|
||||
}
|
||||
|
||||
@ -543,7 +547,7 @@ public abstract class Signature extends SignatureSpi {
|
||||
|
||||
if (!skipDebug && pdebug != null) {
|
||||
pdebug.println("Signature." + algorithm +
|
||||
" signing algorithm from: " + this.provider.getName());
|
||||
" signing algorithm from: " + getProviderName());
|
||||
}
|
||||
}
|
||||
|
||||
@ -566,7 +570,7 @@ public abstract class Signature extends SignatureSpi {
|
||||
|
||||
if (!skipDebug && pdebug != null) {
|
||||
pdebug.println("Signature." + algorithm +
|
||||
" signing algorithm from: " + this.provider.getName());
|
||||
" signing algorithm from: " + getProviderName());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -73,11 +73,13 @@ import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
import java.time.DateTimeException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.TextStyle;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.time.temporal.TemporalField;
|
||||
import java.time.temporal.UnsupportedTemporalTypeException;
|
||||
import java.time.temporal.ValueRange;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import sun.util.calendar.CalendarDate;
|
||||
@ -125,8 +127,8 @@ public final class JapaneseEra
|
||||
*/
|
||||
public static final JapaneseEra HEISEI = new JapaneseEra(2, LocalDate.of(1989, 1, 8));
|
||||
|
||||
// the number of defined JapaneseEra constants.
|
||||
// There could be an extra era defined in its configuration.
|
||||
// The number of predefined JapaneseEra constants.
|
||||
// There may be a supplemental era defined by the property.
|
||||
private static final int N_ERA_CONSTANTS = HEISEI.getValue() + ERA_OFFSET;
|
||||
|
||||
/**
|
||||
@ -237,6 +239,32 @@ public final class JapaneseEra
|
||||
return Arrays.copyOf(KNOWN_ERAS, KNOWN_ERAS.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
@Override
|
||||
public String getDisplayName(TextStyle style, Locale locale) {
|
||||
// If this JapaneseEra is a supplemental one, obtain the name from
|
||||
// the era definition.
|
||||
if (getValue() > N_ERA_CONSTANTS - ERA_OFFSET) {
|
||||
Objects.requireNonNull(locale, "locale");
|
||||
return style.asNormal() == TextStyle.NARROW ? getAbbreviation() : getName();
|
||||
}
|
||||
return Era.super.getDisplayName(style, locale);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Obtains an instance of {@code JapaneseEra} from a date.
|
||||
@ -338,11 +366,7 @@ public final class JapaneseEra
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
String getAbbreviation() {
|
||||
int index = ordinal(getValue());
|
||||
if (index == 0) {
|
||||
return "";
|
||||
}
|
||||
return ERA_CONFIG[index].getAbbreviation();
|
||||
return ERA_CONFIG[ordinal(getValue())].getAbbreviation();
|
||||
}
|
||||
|
||||
String getName() {
|
||||
|
@ -1268,10 +1268,16 @@ public final class Collectors {
|
||||
* to a {@code Predicate}, and organizes them into a
|
||||
* {@code Map<Boolean, List<T>>}.
|
||||
*
|
||||
* The returned {@code Map} always contains mappings for both
|
||||
* {@code false} and {@code true} keys.
|
||||
* There are no guarantees on the type, mutability,
|
||||
* serializability, or thread-safety of the {@code Map} or {@code List}
|
||||
* returned.
|
||||
*
|
||||
* @apiNote
|
||||
* If a partition has no elements, its value in the result Map will be
|
||||
* an empty List.
|
||||
*
|
||||
* @param <T> the type of the input elements
|
||||
* @param predicate a predicate used for classifying input elements
|
||||
* @return a {@code Collector} implementing the partitioning operation
|
||||
@ -1290,9 +1296,17 @@ public final class Collectors {
|
||||
* {@code Map<Boolean, D>} whose values are the result of the downstream
|
||||
* reduction.
|
||||
*
|
||||
* <p>There are no guarantees on the type, mutability,
|
||||
* <p>
|
||||
* The returned {@code Map} always contains mappings for both
|
||||
* {@code false} and {@code true} keys.
|
||||
* There are no guarantees on the type, mutability,
|
||||
* serializability, or thread-safety of the {@code Map} returned.
|
||||
*
|
||||
* @apiNote
|
||||
* If a partition has no elements, its value in the result Map will be
|
||||
* obtained by calling the downstream collector's supplier function and then
|
||||
* applying the finisher function.
|
||||
*
|
||||
* @param <T> the type of the input elements
|
||||
* @param <A> the intermediate accumulation type of the downstream collector
|
||||
* @param <D> the result type of the downstream reduction
|
||||
|
@ -27,6 +27,8 @@ package javax.net.ssl;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ReadOnlyBufferException;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
|
||||
/**
|
||||
@ -1332,4 +1334,89 @@ public abstract class SSLEngine {
|
||||
public String getHandshakeApplicationProtocol() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback function that selects an application protocol
|
||||
* value for a SSL/TLS/DTLS handshake.
|
||||
* The function overrides any values set using
|
||||
* {@link SSLParameters#setApplicationProtocols
|
||||
* SSLParameters.setApplicationProtocols} and it supports the following
|
||||
* type parameters:
|
||||
* <blockquote>
|
||||
* <dl>
|
||||
* <dt> {@code SSLEngine}
|
||||
* <dd> The function's first argument allows the current {@code SSLEngine}
|
||||
* to be inspected, including the handshake session and configuration
|
||||
* settings.
|
||||
* <dt> {@code List<String>}
|
||||
* <dd> The function's second argument lists the application protocol names
|
||||
* advertised by the TLS peer.
|
||||
* <dt> {@code String}
|
||||
* <dd> The function's result is an application protocol name, or null to
|
||||
* indicate that none of the advertised names are acceptable.
|
||||
* If the return value is null (no value chosen) or is a value that
|
||||
* was not advertised by the peer, the underlying protocol will
|
||||
* determine what action to take. (For example, ALPN will send a
|
||||
* "no_application_protocol" alert and terminate the connection.)
|
||||
* </dl>
|
||||
* </blockquote>
|
||||
*
|
||||
* For example, the following call registers a callback function that
|
||||
* examines the TLS handshake parameters and selects an application protocol
|
||||
* name:
|
||||
* <pre>{@code
|
||||
* serverEngine.setHandshakeApplicationProtocolSelector(
|
||||
* (serverEngine, clientProtocols) -> {
|
||||
* SSLSession session = serverEngine.getHandshakeSession();
|
||||
* return chooseApplicationProtocol(
|
||||
* serverEngine,
|
||||
* clientProtocols,
|
||||
* session.getProtocol(),
|
||||
* session.getCipherSuite());
|
||||
* });
|
||||
* }</pre>
|
||||
*
|
||||
* @apiNote
|
||||
* This method should be called by TLS server applications before the TLS
|
||||
* handshake begins. Also, this {@code SSLEngine} should be configured with
|
||||
* parameters that are compatible with the application protocol selected by
|
||||
* the callback function. For example, enabling a poor choice of cipher
|
||||
* suites could result in no suitable application protocol.
|
||||
* See {@link SSLParameters}.
|
||||
*
|
||||
* @implSpec
|
||||
* The implementation in this class throws
|
||||
* {@code UnsupportedOperationException} and performs no other action.
|
||||
*
|
||||
* @param selector the callback function, or null to disable the callback
|
||||
* functionality.
|
||||
* @throws UnsupportedOperationException if the underlying provider
|
||||
* does not implement the operation.
|
||||
* @since 9
|
||||
*/
|
||||
public void setHandshakeApplicationProtocolSelector(
|
||||
BiFunction<SSLEngine, List<String>, String> selector) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the callback function that selects an application protocol
|
||||
* value during a SSL/TLS/DTLS handshake.
|
||||
* See {@link #setHandshakeApplicationProtocolSelector
|
||||
* setHandshakeApplicationProtocolSelector}
|
||||
* for the function's type parameters.
|
||||
*
|
||||
* @implSpec
|
||||
* The implementation in this class throws
|
||||
* {@code UnsupportedOperationException} and performs no other action.
|
||||
*
|
||||
* @return the callback function, or null if none has been set.
|
||||
* @throws UnsupportedOperationException if the underlying provider
|
||||
* does not implement the operation.
|
||||
* @since 9
|
||||
*/
|
||||
public BiFunction<SSLEngine, List<String>, String>
|
||||
getHandshakeApplicationProtocolSelector() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ package javax.net.ssl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* This class extends <code>Socket</code>s and provides secure
|
||||
@ -742,4 +744,89 @@ public abstract class SSLSocket extends Socket
|
||||
public String getHandshakeApplicationProtocol() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers a callback function that selects an application protocol
|
||||
* value for a SSL/TLS/DTLS handshake.
|
||||
* The function overrides any values set using
|
||||
* {@link SSLParameters#setApplicationProtocols
|
||||
* SSLParameters.setApplicationProtocols} and it supports the following
|
||||
* type parameters:
|
||||
* <blockquote>
|
||||
* <dl>
|
||||
* <dt> {@code SSLSocket}
|
||||
* <dd> The function's first argument allows the current {@code SSLSocket}
|
||||
* to be inspected, including the handshake session and configuration
|
||||
* settings.
|
||||
* <dt> {@code List<String>}
|
||||
* <dd> The function's second argument lists the application protocol names
|
||||
* advertised by the TLS peer.
|
||||
* <dt> {@code String}
|
||||
* <dd> The function's result is an application protocol name, or null to
|
||||
* indicate that none of the advertised names are acceptable.
|
||||
* If the return value is null (no value chosen) or is a value that
|
||||
* was not advertised by the peer, the underlying protocol will
|
||||
* determine what action to take. (For example, ALPN will send a
|
||||
* "no_application_protocol" alert and terminate the connection.)
|
||||
* </dl>
|
||||
* </blockquote>
|
||||
*
|
||||
* For example, the following call registers a callback function that
|
||||
* examines the TLS handshake parameters and selects an application protocol
|
||||
* name:
|
||||
* <pre>{@code
|
||||
* serverSocket.setHandshakeApplicationProtocolSelector(
|
||||
* (serverSocket, clientProtocols) -> {
|
||||
* SSLSession session = serverSocket.getHandshakeSession();
|
||||
* return chooseApplicationProtocol(
|
||||
* serverSocket,
|
||||
* clientProtocols,
|
||||
* session.getProtocol(),
|
||||
* session.getCipherSuite());
|
||||
* });
|
||||
* }</pre>
|
||||
*
|
||||
* @apiNote
|
||||
* This method should be called by TLS server applications before the TLS
|
||||
* handshake begins. Also, this {@code SSLSocket} should be configured with
|
||||
* parameters that are compatible with the application protocol selected by
|
||||
* the callback function. For example, enabling a poor choice of cipher
|
||||
* suites could result in no suitable application protocol.
|
||||
* See {@link SSLParameters}.
|
||||
*
|
||||
* @implSpec
|
||||
* The implementation in this class throws
|
||||
* {@code UnsupportedOperationException} and performs no other action.
|
||||
*
|
||||
* @param selector the callback function, or null to de-register.
|
||||
* @throws UnsupportedOperationException if the underlying provider
|
||||
* does not implement the operation.
|
||||
* @since 9
|
||||
*/
|
||||
public void setHandshakeApplicationProtocolSelector(
|
||||
BiFunction<SSLSocket, List<String>, String> selector) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the callback function that selects an application protocol
|
||||
* value during a SSL/TLS/DTLS handshake.
|
||||
* See {@link #setHandshakeApplicationProtocolSelector
|
||||
* setHandshakeApplicationProtocolSelector}
|
||||
* for the function's type parameters.
|
||||
*
|
||||
* @implSpec
|
||||
* The implementation in this class throws
|
||||
* {@code UnsupportedOperationException} and performs no other action.
|
||||
*
|
||||
* @return the callback function, or null if none has been set.
|
||||
* @throws UnsupportedOperationException if the underlying provider
|
||||
* does not implement the operation.
|
||||
* @since 9
|
||||
*/
|
||||
public BiFunction<SSLSocket, List<String>, String>
|
||||
getHandshakeApplicationProtocolSelector() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
@ -64,8 +64,10 @@ public class StringSharingDecompressor implements ResourceDecompressor {
|
||||
private static final int CONSTANT_MethodHandle = 15;
|
||||
private static final int CONSTANT_MethodType = 16;
|
||||
private static final int CONSTANT_InvokeDynamic = 18;
|
||||
private static final int CONSTANT_Module = 19;
|
||||
private static final int CONSTANT_Package = 20;
|
||||
|
||||
private static final int[] SIZES = new int[20];
|
||||
private static final int[] SIZES = new int[21];
|
||||
|
||||
static {
|
||||
|
||||
@ -83,6 +85,8 @@ public class StringSharingDecompressor implements ResourceDecompressor {
|
||||
SIZES[CONSTANT_MethodHandle] = 3;
|
||||
SIZES[CONSTANT_MethodType] = 2;
|
||||
SIZES[CONSTANT_InvokeDynamic] = 4;
|
||||
SIZES[CONSTANT_Module] = 2;
|
||||
SIZES[CONSTANT_Package] = 2;
|
||||
}
|
||||
|
||||
public static int[] getSizes() {
|
||||
|
@ -38,10 +38,8 @@ import java.lang.module.ModuleReader;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@ -59,21 +57,28 @@ public interface JavaLangModuleAccess {
|
||||
* @param strict
|
||||
* Indicates whether module names are checked or not
|
||||
*/
|
||||
ModuleDescriptor.Builder newModuleBuilder(String mn, boolean strict);
|
||||
ModuleDescriptor.Builder newModuleBuilder(String mn,
|
||||
boolean strict,
|
||||
boolean open,
|
||||
boolean synthetic);
|
||||
|
||||
/**
|
||||
* Creates a builder for building an open module with the given module name.
|
||||
*
|
||||
* @param strict
|
||||
* Indicates whether module names are checked or not
|
||||
* Returns the set of packages that are exported (unconditionally or
|
||||
* unconditionally).
|
||||
*/
|
||||
ModuleDescriptor.Builder newOpenModuleBuilder(String mn, boolean strict);
|
||||
Set<String> exportedPackages(ModuleDescriptor.Builder builder);
|
||||
|
||||
/**
|
||||
* Returns the set of packages that are opened (unconditionally or
|
||||
* unconditionally).
|
||||
*/
|
||||
Set<String> openPackages(ModuleDescriptor.Builder builder);
|
||||
|
||||
/**
|
||||
* Returns a {@code ModuleDescriptor.Requires} of the given modifiers
|
||||
* and module name.
|
||||
*/
|
||||
Requires newRequires(Set<Requires.Modifier> ms, String mn);
|
||||
Requires newRequires(Set<Requires.Modifier> ms, String mn, Version v);
|
||||
|
||||
/**
|
||||
* Returns an unqualified {@code ModuleDescriptor.Exports}
|
||||
@ -122,6 +127,7 @@ public interface JavaLangModuleAccess {
|
||||
* Returns a new {@code ModuleDescriptor} instance.
|
||||
*/
|
||||
ModuleDescriptor newModuleDescriptor(String name,
|
||||
Version version,
|
||||
boolean open,
|
||||
boolean automatic,
|
||||
boolean synthetic,
|
||||
@ -130,20 +136,13 @@ public interface JavaLangModuleAccess {
|
||||
Set<Opens> opens,
|
||||
Set<String> uses,
|
||||
Set<Provides> provides,
|
||||
Version version,
|
||||
Set<String> packages,
|
||||
String mainClass,
|
||||
String osName,
|
||||
String osArch,
|
||||
String osVersion,
|
||||
Set<String> packages,
|
||||
ModuleHashes hashes,
|
||||
int hashCode);
|
||||
|
||||
/**
|
||||
* Returns the object with the hashes of other modules
|
||||
*/
|
||||
Optional<ModuleHashes> hashes(ModuleDescriptor descriptor);
|
||||
|
||||
/**
|
||||
* Resolves a collection of root modules, with service binding
|
||||
* and the empty configuration as the parent. The post resolution
|
||||
@ -154,18 +153,4 @@ public interface JavaLangModuleAccess {
|
||||
boolean check,
|
||||
PrintStream traceOutput);
|
||||
|
||||
/**
|
||||
* Creates a ModuleReference to a "patched" module.
|
||||
*/
|
||||
ModuleReference newPatchedModule(ModuleDescriptor descriptor,
|
||||
URI location,
|
||||
Supplier<ModuleReader> readerSupplier);
|
||||
|
||||
/**
|
||||
* Creates a ModuleFinder for a module path.
|
||||
*/
|
||||
ModuleFinder newModulePath(Runtime.Version version,
|
||||
boolean isLinkPhase,
|
||||
Path... entries);
|
||||
|
||||
}
|
||||
|
@ -123,4 +123,12 @@ public interface JavaLangReflectModuleAccess {
|
||||
* given class loader.
|
||||
*/
|
||||
Stream<Layer> layers(ClassLoader loader);
|
||||
|
||||
/**
|
||||
* Tests if a module exports a package at least {@code other} via its
|
||||
* module declaration.
|
||||
*
|
||||
* @apiNote This is a temporary method for debugging features.
|
||||
*/
|
||||
boolean isStaticallyExported(Module module, String pn, Module other);
|
||||
}
|
@ -30,11 +30,8 @@ import java.lang.module.ModuleDescriptor.Opens;
|
||||
import java.lang.module.ModuleDescriptor.Provides;
|
||||
import java.lang.module.ModuleDescriptor.Requires;
|
||||
import java.lang.module.ModuleDescriptor.Version;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.internal.misc.JavaLangModuleAccess;
|
||||
@ -52,7 +49,7 @@ import jdk.internal.misc.SharedSecrets;
|
||||
* SystemModules should contain modules for the boot layer.
|
||||
*/
|
||||
final class Builder {
|
||||
private static final JavaLangModuleAccess jlma =
|
||||
private static final JavaLangModuleAccess JLMA =
|
||||
SharedSecrets.getJavaLangModuleAccess();
|
||||
|
||||
// Static cache of the most recently seen Version to cheaply deduplicate
|
||||
@ -60,13 +57,36 @@ final class Builder {
|
||||
static Version cachedVersion;
|
||||
|
||||
/**
|
||||
* Returns a {@link Requires} for a dependence on a module
|
||||
* with the given (and possibly empty) set of modifiers.
|
||||
* Returns a {@link Requires} for a dependence on a module with the given
|
||||
* (and possibly empty) set of modifiers, and optionally the version
|
||||
* recorded at compile time.
|
||||
*/
|
||||
public static Requires newRequires(Set<Requires.Modifier> mods,
|
||||
String mn,
|
||||
String compiledVersion)
|
||||
{
|
||||
Version version = null;
|
||||
if (compiledVersion != null) {
|
||||
// use the cached version if the same version string
|
||||
Version ver = cachedVersion;
|
||||
if (ver != null && compiledVersion.equals(ver.toString())) {
|
||||
version = ver;
|
||||
} else {
|
||||
version = Version.parse(compiledVersion);
|
||||
}
|
||||
}
|
||||
return JLMA.newRequires(mods, mn, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Requires} for a dependence on a module with the given
|
||||
* (and possibly empty) set of modifiers, and optionally the version
|
||||
* recorded at compile time.
|
||||
*/
|
||||
public static Requires newRequires(Set<Requires.Modifier> mods,
|
||||
String mn)
|
||||
{
|
||||
return jlma.newRequires(mods, mn);
|
||||
return newRequires(mods, mn, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,7 +97,7 @@ final class Builder {
|
||||
public static Exports newExports(Set<Exports.Modifier> ms,
|
||||
String pn,
|
||||
Set<String> targets) {
|
||||
return jlma.newExports(ms, pn, targets);
|
||||
return JLMA.newExports(ms, pn, targets);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,7 +105,7 @@ final class Builder {
|
||||
* modifiers.
|
||||
*/
|
||||
public static Opens newOpens(Set<Opens.Modifier> ms, String pn) {
|
||||
return jlma.newOpens(ms, pn);
|
||||
return JLMA.newOpens(ms, pn);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,7 +116,7 @@ final class Builder {
|
||||
public static Opens newOpens(Set<Opens.Modifier> ms,
|
||||
String pn,
|
||||
Set<String> targets) {
|
||||
return jlma.newOpens(ms, pn, targets);
|
||||
return JLMA.newOpens(ms, pn, targets);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -104,7 +124,7 @@ final class Builder {
|
||||
* of modifiers.
|
||||
*/
|
||||
public static Exports newExports(Set<Exports.Modifier> ms, String pn) {
|
||||
return jlma.newExports(ms, pn);
|
||||
return JLMA.newExports(ms, pn);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,7 +132,7 @@ final class Builder {
|
||||
* implementation classes.
|
||||
*/
|
||||
public static Provides newProvides(String st, List<String> pcs) {
|
||||
return jlma.newProvides(st, pcs);
|
||||
return JLMA.newProvides(st, pcs);
|
||||
}
|
||||
|
||||
final String name;
|
||||
@ -130,8 +150,6 @@ final class Builder {
|
||||
String osName;
|
||||
String osArch;
|
||||
String osVersion;
|
||||
String algorithm;
|
||||
Map<String, byte[]> hashes;
|
||||
|
||||
Builder(String name) {
|
||||
this.name = name;
|
||||
@ -274,35 +292,14 @@ final class Builder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the algorithm of the module hashes
|
||||
*/
|
||||
public Builder algorithm(String algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the module hash for the given module name
|
||||
*/
|
||||
public Builder moduleHash(String mn, byte[] hash) {
|
||||
if (hashes == null)
|
||||
hashes = new HashMap<>();
|
||||
|
||||
hashes.put(mn, hash);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@code ModuleDescriptor} from the components.
|
||||
*/
|
||||
public ModuleDescriptor build(int hashCode) {
|
||||
assert name != null;
|
||||
|
||||
ModuleHashes moduleHashes =
|
||||
hashes != null ? new ModuleHashes(algorithm, hashes) : null;
|
||||
|
||||
return jlma.newModuleDescriptor(name,
|
||||
return JLMA.newModuleDescriptor(name,
|
||||
version,
|
||||
open,
|
||||
automatic,
|
||||
synthetic,
|
||||
@ -311,13 +308,11 @@ final class Builder {
|
||||
opens,
|
||||
uses,
|
||||
provides,
|
||||
version,
|
||||
packages,
|
||||
mainClass,
|
||||
osName,
|
||||
osArch,
|
||||
osVersion,
|
||||
packages,
|
||||
moduleHashes,
|
||||
hashCode);
|
||||
}
|
||||
}
|
||||
|
@ -25,79 +25,200 @@
|
||||
|
||||
package jdk.internal.module;
|
||||
|
||||
/**
|
||||
* Utility class for checking module name and binary names.
|
||||
*/
|
||||
|
||||
public final class Checks {
|
||||
|
||||
private Checks() { }
|
||||
|
||||
private static void fail(String what, String id, int i) {
|
||||
throw new IllegalArgumentException(id
|
||||
+ ": Invalid " + what + ": "
|
||||
+ " Illegal character"
|
||||
+ " at index " + i);
|
||||
/**
|
||||
* Checks a name to ensure that it's a legal module name.
|
||||
*
|
||||
* @throws IllegalArgumentException if name is null or not a legal
|
||||
* module name
|
||||
*/
|
||||
public static String requireModuleName(String name) {
|
||||
if (name == null)
|
||||
throw new IllegalArgumentException("Null module name");
|
||||
int next;
|
||||
int off = 0;
|
||||
while ((next = name.indexOf('.', off)) != -1) {
|
||||
if (isJavaIdentifier(name, off, (next - off)) == -1) {
|
||||
String id = name.substring(off, next);
|
||||
throw new IllegalArgumentException(name + ": Invalid module name"
|
||||
+ ": '" + id + "' is not a Java identifier");
|
||||
}
|
||||
off = next+1;
|
||||
}
|
||||
int last = isJavaIdentifier(name, off, name.length() - off);
|
||||
if (last == -1) {
|
||||
String id = name.substring(off);
|
||||
throw new IllegalArgumentException(name + ": Invalid module name"
|
||||
+ ": '" + id + "' is not a Java identifier");
|
||||
}
|
||||
//if (!Character.isJavaIdentifierStart(last))
|
||||
// throw new IllegalArgumentException(name + ": Module name ends in digit");
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the given identifier is a legal Java identifier.
|
||||
* Returns {@code true} if the given name is a legal module name.
|
||||
*/
|
||||
public static boolean isJavaIdentifier(String id) {
|
||||
int n = id.length();
|
||||
if (n == 0)
|
||||
return false;
|
||||
if (!Character.isJavaIdentifierStart(id.codePointAt(0)))
|
||||
return false;
|
||||
int cp = id.codePointAt(0);
|
||||
int i = Character.charCount(cp);
|
||||
for (; i < n; i += Character.charCount(cp)) {
|
||||
cp = id.codePointAt(i);
|
||||
if (!Character.isJavaIdentifierPart(cp) && id.charAt(i) != '.')
|
||||
public static boolean isModuleName(String name) {
|
||||
int next;
|
||||
int off = 0;
|
||||
while ((next = name.indexOf('.', off)) != -1) {
|
||||
if (isJavaIdentifier(name, off, (next - off)) == -1)
|
||||
return false;
|
||||
off = next+1;
|
||||
}
|
||||
if (cp == '.')
|
||||
int last = isJavaIdentifier(name, off, name.length() - off);
|
||||
if (last == -1)
|
||||
return false;
|
||||
|
||||
//if (!Character.isJavaIdentifierStart(last))
|
||||
// return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given identifier is a legal Java identifier.
|
||||
* Checks a name to ensure that it's a legal package name.
|
||||
*
|
||||
* @throws IllegalArgumentException if name is null or not a legal
|
||||
* package name
|
||||
*/
|
||||
public static String requireJavaIdentifier(String what, String id) {
|
||||
if (id == null)
|
||||
throw new IllegalArgumentException("Null " + what);
|
||||
int n = id.length();
|
||||
if (n == 0)
|
||||
throw new IllegalArgumentException("Empty " + what);
|
||||
if (!Character.isJavaIdentifierStart(id.codePointAt(0)))
|
||||
fail(what, id, 0);
|
||||
int cp = id.codePointAt(0);
|
||||
int i = Character.charCount(cp);
|
||||
int last = 0;
|
||||
for (; i < n; i += Character.charCount(cp)) {
|
||||
cp = id.codePointAt(i);
|
||||
if (!Character.isJavaIdentifierPart(cp) && id.charAt(i) != '.')
|
||||
fail(what, id, i);
|
||||
last = i;
|
||||
public static String requirePackageName(String name) {
|
||||
return requireBinaryName("package name", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a name to ensure that it's a legal type name.
|
||||
*
|
||||
* @throws IllegalArgumentException if name is null or not a legal
|
||||
* type name
|
||||
*/
|
||||
public static String requireServiceTypeName(String name) {
|
||||
return requireBinaryName("service type name", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a name to ensure that it's a legal type name.
|
||||
*
|
||||
* @throws IllegalArgumentException if name is null or not a legal
|
||||
* type name
|
||||
*/
|
||||
public static String requireServiceProviderName(String name) {
|
||||
return requireBinaryName("service provider name", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the given name is a legal binary name.
|
||||
*/
|
||||
public static boolean isJavaIdentifier(String name) {
|
||||
return isBinaryName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the given name is a legal binary name.
|
||||
*/
|
||||
public static boolean isBinaryName(String name) {
|
||||
int next;
|
||||
int off = 0;
|
||||
while ((next = name.indexOf('.', off)) != -1) {
|
||||
if (isJavaIdentifier(name, off, (next - off)) == -1)
|
||||
return false;
|
||||
off = next+1;
|
||||
}
|
||||
if (cp == '.')
|
||||
fail(what, id, last);
|
||||
|
||||
return id;
|
||||
int count = name.length() - off;
|
||||
return (isJavaIdentifier(name, off, count) != -1);
|
||||
}
|
||||
|
||||
public static String requireModuleName(String id) {
|
||||
return requireJavaIdentifier("module name", id);
|
||||
/**
|
||||
* Checks if the given name is a legal binary name.
|
||||
*
|
||||
* @throws IllegalArgumentException if name is null or not a legal
|
||||
* binary name
|
||||
*/
|
||||
public static String requireBinaryName(String what, String name) {
|
||||
if (name == null)
|
||||
throw new IllegalArgumentException("Null " + what);
|
||||
int next;
|
||||
int off = 0;
|
||||
while ((next = name.indexOf('.', off)) != -1) {
|
||||
if (isJavaIdentifier(name, off, (next - off)) == -1) {
|
||||
String id = name.substring(off, next);
|
||||
throw new IllegalArgumentException(name + ": Invalid " + what
|
||||
+ ": '" + id + "' is not a Java identifier");
|
||||
}
|
||||
off = next + 1;
|
||||
}
|
||||
if (isJavaIdentifier(name, off, name.length() - off) == -1) {
|
||||
String id = name.substring(off, name.length());
|
||||
throw new IllegalArgumentException(name + ": Invalid " + what
|
||||
+ ": '" + id + "' is not a Java identifier");
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static String requirePackageName(String id) {
|
||||
return requireJavaIdentifier("package name", id);
|
||||
/**
|
||||
* Returns {@code true} if the last character of the given name is legal
|
||||
* as the last character of a module name.
|
||||
*
|
||||
* @throws IllegalArgumentException if name is empty
|
||||
*/
|
||||
public static boolean hasLegalModuleNameLastCharacter(String name) {
|
||||
if (name.isEmpty())
|
||||
throw new IllegalArgumentException("name is empty");
|
||||
int len = name.length();
|
||||
if (isASCIIString(name)) {
|
||||
char c = name.charAt(len-1);
|
||||
return Character.isJavaIdentifierStart(c);
|
||||
} else {
|
||||
int i = 0;
|
||||
int cp = -1;
|
||||
while (i < len) {
|
||||
cp = name.codePointAt(i);
|
||||
i += Character.charCount(cp);
|
||||
}
|
||||
return Character.isJavaIdentifierStart(cp);
|
||||
}
|
||||
}
|
||||
|
||||
public static String requireServiceTypeName(String id) {
|
||||
return requireJavaIdentifier("service type name", id);
|
||||
/**
|
||||
* Returns true if the given string only contains ASCII characters.
|
||||
*/
|
||||
private static boolean isASCIIString(String s) {
|
||||
int i = 0;
|
||||
while (i < s.length()) {
|
||||
int c = s.charAt(i);
|
||||
if (c > 0x7F)
|
||||
return false;
|
||||
i++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static String requireServiceProviderName(String id) {
|
||||
return requireJavaIdentifier("service provider name", id);
|
||||
}
|
||||
/**
|
||||
* Checks if a char sequence is a legal Java identifier, returning the code
|
||||
* point of the last character if legal or {@code -1} if not legal.
|
||||
*/
|
||||
private static int isJavaIdentifier(CharSequence cs, int offset, int count) {
|
||||
if (count == 0)
|
||||
return -1;
|
||||
int first = Character.codePointAt(cs, offset);
|
||||
if (!Character.isJavaIdentifierStart(first))
|
||||
return -1;
|
||||
|
||||
int cp = first;
|
||||
int i = Character.charCount(first);
|
||||
while (i < count) {
|
||||
cp = Character.codePointAt(cs, offset+i);
|
||||
if (!Character.isJavaIdentifierPart(cp))
|
||||
return -1;
|
||||
i += Character.charCount(cp);
|
||||
}
|
||||
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
@ -68,12 +68,18 @@ public final class ClassFileAttributes {
|
||||
= SharedSecrets.getJavaLangModuleAccess();
|
||||
|
||||
private ModuleDescriptor descriptor;
|
||||
private Version replacementVersion;
|
||||
|
||||
public ModuleAttribute(ModuleDescriptor descriptor) {
|
||||
super(MODULE);
|
||||
this.descriptor = descriptor;
|
||||
}
|
||||
|
||||
public ModuleAttribute(Version v) {
|
||||
super(MODULE);
|
||||
this.replacementVersion = v;
|
||||
}
|
||||
|
||||
public ModuleAttribute() {
|
||||
super(MODULE);
|
||||
}
|
||||
@ -86,46 +92,70 @@ public final class ClassFileAttributes {
|
||||
int codeOff,
|
||||
Label[] labels)
|
||||
{
|
||||
ModuleAttribute attr = new ModuleAttribute();
|
||||
|
||||
// module_name
|
||||
String mn = cr.readUTF8(off, buf).replace('/', '.');
|
||||
// module_name (CONSTANT_Module_info)
|
||||
String mn = cr.readModule(off, buf);
|
||||
off += 2;
|
||||
|
||||
// module_flags
|
||||
int module_flags = cr.readUnsignedShort(off);
|
||||
boolean open = ((module_flags & ACC_OPEN) != 0);
|
||||
boolean synthetic = ((module_flags & ACC_SYNTHETIC) != 0);
|
||||
off += 2;
|
||||
|
||||
ModuleDescriptor.Builder builder;
|
||||
if (open) {
|
||||
builder = JLMA.newOpenModuleBuilder(mn, false);
|
||||
} else {
|
||||
builder = JLMA.newModuleBuilder(mn, false);
|
||||
ModuleDescriptor.Builder builder = JLMA.newModuleBuilder(mn,
|
||||
false,
|
||||
open,
|
||||
synthetic);
|
||||
|
||||
// module_version
|
||||
String module_version = cr.readUTF8(off, buf);
|
||||
off += 2;
|
||||
if (replacementVersion != null) {
|
||||
builder.version(replacementVersion);
|
||||
} else if (module_version != null) {
|
||||
builder.version(module_version);
|
||||
}
|
||||
|
||||
// requires_count and requires[requires_count]
|
||||
int requires_count = cr.readUnsignedShort(off);
|
||||
off += 2;
|
||||
for (int i=0; i<requires_count; i++) {
|
||||
String dn = cr.readUTF8(off, buf).replace('/', '.');
|
||||
int flags = cr.readUnsignedShort(off + 2);
|
||||
// CONSTANT_Module_info
|
||||
String dn = cr.readModule(off, buf);
|
||||
off += 2;
|
||||
|
||||
// requires_flags
|
||||
int requires_flags = cr.readUnsignedShort(off);
|
||||
off += 2;
|
||||
Set<Requires.Modifier> mods;
|
||||
if (flags == 0) {
|
||||
if (requires_flags == 0) {
|
||||
mods = Collections.emptySet();
|
||||
} else {
|
||||
mods = new HashSet<>();
|
||||
if ((flags & ACC_TRANSITIVE) != 0)
|
||||
if ((requires_flags & ACC_TRANSITIVE) != 0)
|
||||
mods.add(Requires.Modifier.TRANSITIVE);
|
||||
if ((flags & ACC_STATIC_PHASE) != 0)
|
||||
if ((requires_flags & ACC_STATIC_PHASE) != 0)
|
||||
mods.add(Requires.Modifier.STATIC);
|
||||
if ((flags & ACC_SYNTHETIC) != 0)
|
||||
if ((requires_flags & ACC_SYNTHETIC) != 0)
|
||||
mods.add(Requires.Modifier.SYNTHETIC);
|
||||
if ((flags & ACC_MANDATED) != 0)
|
||||
if ((requires_flags & ACC_MANDATED) != 0)
|
||||
mods.add(Requires.Modifier.MANDATED);
|
||||
}
|
||||
builder.requires(mods, dn);
|
||||
off += 4;
|
||||
|
||||
|
||||
// requires_version
|
||||
Version compiledVersion = null;
|
||||
String requires_version = cr.readUTF8(off, buf);
|
||||
off += 2;
|
||||
if (requires_version != null) {
|
||||
compiledVersion = Version.parse(requires_version);
|
||||
}
|
||||
|
||||
if (compiledVersion == null) {
|
||||
builder.requires(mods, dn);
|
||||
} else {
|
||||
builder.requires(mods, dn, compiledVersion);
|
||||
}
|
||||
}
|
||||
|
||||
// exports_count and exports[exports_count]
|
||||
@ -133,19 +163,20 @@ public final class ClassFileAttributes {
|
||||
off += 2;
|
||||
if (exports_count > 0) {
|
||||
for (int i=0; i<exports_count; i++) {
|
||||
String pkg = cr.readUTF8(off, buf).replace('/', '.');
|
||||
// CONSTANT_Package_info
|
||||
String pkg = cr.readPackage(off, buf).replace('/', '.');
|
||||
off += 2;
|
||||
|
||||
int flags = cr.readUnsignedShort(off);
|
||||
int exports_flags = cr.readUnsignedShort(off);
|
||||
off += 2;
|
||||
Set<Exports.Modifier> mods;
|
||||
if (flags == 0) {
|
||||
if (exports_flags == 0) {
|
||||
mods = Collections.emptySet();
|
||||
} else {
|
||||
mods = new HashSet<>();
|
||||
if ((flags & ACC_SYNTHETIC) != 0)
|
||||
if ((exports_flags & ACC_SYNTHETIC) != 0)
|
||||
mods.add(Exports.Modifier.SYNTHETIC);
|
||||
if ((flags & ACC_MANDATED) != 0)
|
||||
if ((exports_flags & ACC_MANDATED) != 0)
|
||||
mods.add(Exports.Modifier.MANDATED);
|
||||
}
|
||||
|
||||
@ -154,7 +185,7 @@ public final class ClassFileAttributes {
|
||||
if (exports_to_count > 0) {
|
||||
Set<String> targets = new HashSet<>();
|
||||
for (int j=0; j<exports_to_count; j++) {
|
||||
String t = cr.readUTF8(off, buf).replace('/', '.');
|
||||
String t = cr.readModule(off, buf);
|
||||
off += 2;
|
||||
targets.add(t);
|
||||
}
|
||||
@ -170,19 +201,20 @@ public final class ClassFileAttributes {
|
||||
off += 2;
|
||||
if (open_count > 0) {
|
||||
for (int i=0; i<open_count; i++) {
|
||||
String pkg = cr.readUTF8(off, buf).replace('/', '.');
|
||||
// CONSTANT_Package_info
|
||||
String pkg = cr.readPackage(off, buf).replace('/', '.');
|
||||
off += 2;
|
||||
|
||||
int flags = cr.readUnsignedShort(off);
|
||||
int opens_flags = cr.readUnsignedShort(off);
|
||||
off += 2;
|
||||
Set<Opens.Modifier> mods;
|
||||
if (flags == 0) {
|
||||
if (opens_flags == 0) {
|
||||
mods = Collections.emptySet();
|
||||
} else {
|
||||
mods = new HashSet<>();
|
||||
if ((flags & ACC_SYNTHETIC) != 0)
|
||||
if ((opens_flags & ACC_SYNTHETIC) != 0)
|
||||
mods.add(Opens.Modifier.SYNTHETIC);
|
||||
if ((flags & ACC_MANDATED) != 0)
|
||||
if ((opens_flags & ACC_MANDATED) != 0)
|
||||
mods.add(Opens.Modifier.MANDATED);
|
||||
}
|
||||
|
||||
@ -191,7 +223,7 @@ public final class ClassFileAttributes {
|
||||
if (opens_to_count > 0) {
|
||||
Set<String> targets = new HashSet<>();
|
||||
for (int j=0; j<opens_to_count; j++) {
|
||||
String t = cr.readUTF8(off, buf).replace('/', '.');
|
||||
String t = cr.readModule(off, buf);
|
||||
off += 2;
|
||||
targets.add(t);
|
||||
}
|
||||
@ -232,8 +264,7 @@ public final class ClassFileAttributes {
|
||||
}
|
||||
}
|
||||
|
||||
attr.descriptor = builder.build();
|
||||
return attr;
|
||||
return new ModuleAttribute(builder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -248,7 +279,7 @@ public final class ClassFileAttributes {
|
||||
|
||||
// module_name
|
||||
String mn = descriptor.name();
|
||||
int module_name_index = cw.newUTF8(mn.replace('.', '/'));
|
||||
int module_name_index = cw.newModule(mn);
|
||||
attr.putShort(module_name_index);
|
||||
|
||||
// module_flags
|
||||
@ -259,66 +290,83 @@ public final class ClassFileAttributes {
|
||||
module_flags |= ACC_SYNTHETIC;
|
||||
attr.putShort(module_flags);
|
||||
|
||||
// module_version
|
||||
Version v = descriptor.version().orElse(null);
|
||||
if (v == null) {
|
||||
attr.putShort(0);
|
||||
} else {
|
||||
int module_version_index = cw.newUTF8(v.toString());
|
||||
attr.putShort(module_version_index);
|
||||
}
|
||||
|
||||
// requires_count
|
||||
attr.putShort(descriptor.requires().size());
|
||||
|
||||
// requires[requires_count]
|
||||
for (Requires md : descriptor.requires()) {
|
||||
String dn = md.name();
|
||||
int flags = 0;
|
||||
if (md.modifiers().contains(Requires.Modifier.TRANSITIVE))
|
||||
flags |= ACC_TRANSITIVE;
|
||||
if (md.modifiers().contains(Requires.Modifier.STATIC))
|
||||
flags |= ACC_STATIC_PHASE;
|
||||
if (md.modifiers().contains(Requires.Modifier.SYNTHETIC))
|
||||
flags |= ACC_SYNTHETIC;
|
||||
if (md.modifiers().contains(Requires.Modifier.MANDATED))
|
||||
flags |= ACC_MANDATED;
|
||||
int index = cw.newUTF8(dn.replace('.', '/'));
|
||||
attr.putShort(index);
|
||||
attr.putShort(flags);
|
||||
for (Requires r : descriptor.requires()) {
|
||||
int requires_index = cw.newModule(r.name());
|
||||
attr.putShort(requires_index);
|
||||
|
||||
int requires_flags = 0;
|
||||
if (r.modifiers().contains(Requires.Modifier.TRANSITIVE))
|
||||
requires_flags |= ACC_TRANSITIVE;
|
||||
if (r.modifiers().contains(Requires.Modifier.STATIC))
|
||||
requires_flags |= ACC_STATIC_PHASE;
|
||||
if (r.modifiers().contains(Requires.Modifier.SYNTHETIC))
|
||||
requires_flags |= ACC_SYNTHETIC;
|
||||
if (r.modifiers().contains(Requires.Modifier.MANDATED))
|
||||
requires_flags |= ACC_MANDATED;
|
||||
attr.putShort(requires_flags);
|
||||
|
||||
int requires_version_index;
|
||||
v = r.compiledVersion().orElse(null);
|
||||
if (v == null) {
|
||||
requires_version_index = 0;
|
||||
} else {
|
||||
requires_version_index = cw.newUTF8(v.toString());
|
||||
}
|
||||
attr.putShort(requires_version_index);
|
||||
}
|
||||
|
||||
// exports_count and exports[exports_count];
|
||||
attr.putShort(descriptor.exports().size());
|
||||
for (Exports e : descriptor.exports()) {
|
||||
String pkg = e.source().replace('.', '/');
|
||||
attr.putShort(cw.newUTF8(pkg));
|
||||
attr.putShort(cw.newPackage(pkg));
|
||||
|
||||
int flags = 0;
|
||||
int exports_flags = 0;
|
||||
if (e.modifiers().contains(Exports.Modifier.SYNTHETIC))
|
||||
flags |= ACC_SYNTHETIC;
|
||||
exports_flags |= ACC_SYNTHETIC;
|
||||
if (e.modifiers().contains(Exports.Modifier.MANDATED))
|
||||
flags |= ACC_MANDATED;
|
||||
attr.putShort(flags);
|
||||
exports_flags |= ACC_MANDATED;
|
||||
attr.putShort(exports_flags);
|
||||
|
||||
if (e.isQualified()) {
|
||||
Set<String> ts = e.targets();
|
||||
attr.putShort(ts.size());
|
||||
ts.forEach(t -> attr.putShort(cw.newUTF8(t.replace('.', '/'))));
|
||||
ts.forEach(target -> attr.putShort(cw.newModule(target)));
|
||||
} else {
|
||||
attr.putShort(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// opens_counts and opens[opens_counts]
|
||||
attr.putShort(descriptor.opens().size());
|
||||
for (Opens obj : descriptor.opens()) {
|
||||
String pkg = obj.source().replace('.', '/');
|
||||
attr.putShort(cw.newUTF8(pkg));
|
||||
attr.putShort(cw.newPackage(pkg));
|
||||
|
||||
int flags = 0;
|
||||
int opens_flags = 0;
|
||||
if (obj.modifiers().contains(Opens.Modifier.SYNTHETIC))
|
||||
flags |= ACC_SYNTHETIC;
|
||||
opens_flags |= ACC_SYNTHETIC;
|
||||
if (obj.modifiers().contains(Opens.Modifier.MANDATED))
|
||||
flags |= ACC_MANDATED;
|
||||
attr.putShort(flags);
|
||||
opens_flags |= ACC_MANDATED;
|
||||
attr.putShort(opens_flags);
|
||||
|
||||
if (obj.isQualified()) {
|
||||
Set<String> ts = obj.targets();
|
||||
attr.putShort(ts.size());
|
||||
ts.forEach(t -> attr.putShort(cw.newUTF8(t.replace('.', '/'))));
|
||||
ts.forEach(target -> attr.putShort(cw.newModule(target)));
|
||||
} else {
|
||||
attr.putShort(0);
|
||||
}
|
||||
@ -369,7 +417,7 @@ public final class ClassFileAttributes {
|
||||
*
|
||||
* // the number of entries in the packages table
|
||||
* u2 packages_count;
|
||||
* { // index to CONSTANT_CONSTANT_utf8_info structure with the package name
|
||||
* { // index to CONSTANT_Package_info structure with the package name
|
||||
* u2 package_index
|
||||
* } packages[package_count];
|
||||
*
|
||||
@ -402,7 +450,7 @@ public final class ClassFileAttributes {
|
||||
// packages
|
||||
Set<String> packages = new HashSet<>();
|
||||
for (int i=0; i<package_count; i++) {
|
||||
String pkg = cr.readUTF8(off, buf).replace('/', '.');
|
||||
String pkg = cr.readPackage(off, buf).replace('/', '.');
|
||||
packages.add(pkg);
|
||||
off += 2;
|
||||
}
|
||||
@ -427,68 +475,13 @@ public final class ClassFileAttributes {
|
||||
// packages
|
||||
packages.stream()
|
||||
.map(p -> p.replace('.', '/'))
|
||||
.forEach(p -> attr.putShort(cw.newUTF8(p)));
|
||||
.forEach(p -> attr.putShort(cw.newPackage(p)));
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ModuleVersion attribute.
|
||||
*
|
||||
* <pre> {@code
|
||||
*
|
||||
* ModuleVersion_attribute {
|
||||
* // index to CONSTANT_utf8_info structure in constant pool representing
|
||||
* // the string "ModuleVersion"
|
||||
* u2 attribute_name_index;
|
||||
* u4 attribute_length;
|
||||
*
|
||||
* // index to CONSTANT_CONSTANT_utf8_info structure with the version
|
||||
* u2 version_index;
|
||||
* }
|
||||
*
|
||||
* } </pre>
|
||||
*/
|
||||
public static class ModuleVersionAttribute extends Attribute {
|
||||
private final Version version;
|
||||
|
||||
public ModuleVersionAttribute(Version version) {
|
||||
super(MODULE_VERSION);
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public ModuleVersionAttribute() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Attribute read(ClassReader cr,
|
||||
int off,
|
||||
int len,
|
||||
char[] buf,
|
||||
int codeOff,
|
||||
Label[] labels)
|
||||
{
|
||||
String value = cr.readUTF8(off, buf);
|
||||
return new ModuleVersionAttribute(Version.parse(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ByteVector write(ClassWriter cw,
|
||||
byte[] code,
|
||||
int len,
|
||||
int maxStack,
|
||||
int maxLocals)
|
||||
{
|
||||
ByteVector attr = new ByteVector();
|
||||
int index = cw.newUTF8(version.toString());
|
||||
attr.putShort(index);
|
||||
return attr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ModuleMainClass attribute.
|
||||
*
|
||||
@ -526,7 +519,7 @@ public final class ClassFileAttributes {
|
||||
int codeOff,
|
||||
Label[] labels)
|
||||
{
|
||||
String value = cr.readClass(off, buf);
|
||||
String value = cr.readClass(off, buf).replace('/', '.');
|
||||
return new ModuleMainClassAttribute(value);
|
||||
}
|
||||
|
||||
@ -538,7 +531,7 @@ public final class ClassFileAttributes {
|
||||
int maxLocals)
|
||||
{
|
||||
ByteVector attr = new ByteVector();
|
||||
int index = cw.newClass(mainClass);
|
||||
int index = cw.newClass(mainClass.replace('.', '/'));
|
||||
attr.putShort(index);
|
||||
return attr;
|
||||
}
|
||||
@ -555,11 +548,11 @@ public final class ClassFileAttributes {
|
||||
* u2 attribute_name_index;
|
||||
* u4 attribute_length;
|
||||
*
|
||||
* // index to CONSTANT_CONSTANT_utf8_info structure with the OS name
|
||||
* // index to CONSTANT_utf8_info structure with the OS name
|
||||
* u2 os_name_index;
|
||||
* // index to CONSTANT_CONSTANT_utf8_info structure with the OS arch
|
||||
* // index to CONSTANT_utf8_info structure with the OS arch
|
||||
* u2 os_arch_index
|
||||
* // index to CONSTANT_CONSTANT_utf8_info structure with the OS version
|
||||
* // index to CONSTANT_utf8_info structure with the OS version
|
||||
* u2 os_version_index;
|
||||
* }
|
||||
*
|
||||
@ -656,7 +649,7 @@ public final class ClassFileAttributes {
|
||||
*
|
||||
* // the number of entries in the hashes table
|
||||
* u2 hashes_count;
|
||||
* { u2 module_name_index
|
||||
* { u2 module_name_index (index to CONSTANT_Module_info structure)
|
||||
* u2 hash_length;
|
||||
* u1 hash[hash_length];
|
||||
* } hashes[hashes_count];
|
||||
@ -691,7 +684,7 @@ public final class ClassFileAttributes {
|
||||
|
||||
Map<String, byte[]> map = new HashMap<>();
|
||||
for (int i=0; i<hashes_count; i++) {
|
||||
String mn = cr.readUTF8(off, buf).replace('/', '.');
|
||||
String mn = cr.readModule(off, buf);
|
||||
off += 2;
|
||||
|
||||
int hash_length = cr.readUnsignedShort(off);
|
||||
@ -728,7 +721,7 @@ public final class ClassFileAttributes {
|
||||
for (String mn : names) {
|
||||
byte[] hash = hashes.hashFor(mn);
|
||||
assert hash != null;
|
||||
attr.putShort(cw.newUTF8(mn.replace('.', '/')));
|
||||
attr.putShort(cw.newModule(mn));
|
||||
|
||||
attr.putShort(hash.length);
|
||||
for (byte b: hash) {
|
||||
@ -740,4 +733,58 @@ public final class ClassFileAttributes {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ModuleResolution_attribute {
|
||||
* u2 attribute_name_index; // "ModuleResolution"
|
||||
* u4 attribute_length; // 2
|
||||
* u2 resolution_flags;
|
||||
*
|
||||
* The value of the resolution_flags item is a mask of flags used to denote
|
||||
* properties of module resolution. The flags are as follows:
|
||||
*
|
||||
* // Optional
|
||||
* 0x0001 (DO_NOT_RESOLVE_BY_DEFAULT)
|
||||
*
|
||||
* // At most one of:
|
||||
* 0x0002 (WARN_DEPRECATED)
|
||||
* 0x0004 (WARN_DEPRECATED_FOR_REMOVAL)
|
||||
* 0x0008 (WARN_INCUBATING)
|
||||
*/
|
||||
static class ModuleResolutionAttribute extends Attribute {
|
||||
private final int value;
|
||||
|
||||
ModuleResolutionAttribute() {
|
||||
super(MODULE_RESOLUTION);
|
||||
value = 0;
|
||||
}
|
||||
|
||||
ModuleResolutionAttribute(int value) {
|
||||
super(MODULE_RESOLUTION);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Attribute read(ClassReader cr,
|
||||
int off,
|
||||
int len,
|
||||
char[] buf,
|
||||
int codeOff,
|
||||
Label[] labels)
|
||||
{
|
||||
int flags = cr.readUnsignedShort(off);
|
||||
return new ModuleResolutionAttribute(flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ByteVector write(ClassWriter cw,
|
||||
byte[] code,
|
||||
int len,
|
||||
int maxStack,
|
||||
int maxLocals)
|
||||
{
|
||||
ByteVector attr = new ByteVector();
|
||||
attr.putShort(value);
|
||||
return attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,10 +38,10 @@ public class ClassFileConstants {
|
||||
public static final String SDE = "SourceDebugExtension";
|
||||
|
||||
public static final String MODULE_PACKAGES = "ModulePackages";
|
||||
public static final String MODULE_VERSION = "ModuleVersion";
|
||||
public static final String MODULE_MAIN_CLASS = "ModuleMainClass";
|
||||
public static final String MODULE_TARGET = "ModuleTarget";
|
||||
public static final String MODULE_HASHES = "ModuleHashes";
|
||||
public static final String MODULE_RESOLUTION = "ModuleResolution";
|
||||
|
||||
// access, requires, exports, and opens flags
|
||||
public static final int ACC_MODULE = 0x8000;
|
||||
@ -51,4 +51,10 @@ public class ClassFileConstants {
|
||||
public static final int ACC_SYNTHETIC = 0x1000;
|
||||
public static final int ACC_MANDATED = 0x8000;
|
||||
|
||||
// ModuleResolution_attribute resolution flags
|
||||
public static final int DO_NOT_RESOLVE_BY_DEFAULT = 0x0001;
|
||||
public static final int WARN_DEPRECATED = 0x0002;
|
||||
public static final int WARN_DEPRECATED_FOR_REMOVAL = 0x0004;
|
||||
public static final int WARN_INCUBATING = 0x0008;
|
||||
|
||||
}
|
||||
|
@ -195,7 +195,9 @@ public final class ModuleBootstrap {
|
||||
// module is the unnamed module of the application class loader. This
|
||||
// is implemented by resolving "java.se" and all (non-java.*) modules
|
||||
// that export an API. If "java.se" is not observable then all java.*
|
||||
// modules are resolved.
|
||||
// modules are resolved. Modules that have the DO_NOT_RESOLVE_BY_DEFAULT
|
||||
// bit set in their ModuleResolution attribute flags are excluded from
|
||||
// the default set of roots.
|
||||
if (mainModule == null || addAllDefaultModules) {
|
||||
boolean hasJava = false;
|
||||
if (systemModules.find(JAVA_SE).isPresent()) {
|
||||
@ -212,6 +214,9 @@ public final class ModuleBootstrap {
|
||||
if (hasJava && mn.startsWith("java."))
|
||||
continue;
|
||||
|
||||
if (ModuleResolution.doNotResolveByDefault(mref))
|
||||
continue;
|
||||
|
||||
// add as root if observable and exports at least one package
|
||||
if ((finder == systemModules || finder.find(mn).isPresent())) {
|
||||
ModuleDescriptor descriptor = mref.descriptor();
|
||||
@ -231,6 +236,7 @@ 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
|
||||
@ -277,6 +283,8 @@ public final class ModuleBootstrap {
|
||||
// time to create configuration
|
||||
PerfCounters.resolveTime.addElapsedTimeFrom(t3);
|
||||
|
||||
// check module names and incubating status
|
||||
checkModuleNamesAndStatus(cf);
|
||||
|
||||
// mapping of modules to class loaders
|
||||
Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
|
||||
@ -508,12 +516,12 @@ public final class ModuleBootstrap {
|
||||
String key = e.getKey();
|
||||
String[] s = key.split("/");
|
||||
if (s.length != 2)
|
||||
fail("Unable to parse: " + key);
|
||||
fail("Unable to parse as <module>/<package>: " + key);
|
||||
|
||||
String mn = s[0];
|
||||
String pn = s[1];
|
||||
if (mn.isEmpty() || pn.isEmpty())
|
||||
fail("Module and package name must be specified:" + key);
|
||||
fail("Module and package name must be specified: " + key);
|
||||
|
||||
// The exporting module is in the boot layer
|
||||
Module m;
|
||||
@ -585,7 +593,7 @@ public final class ModuleBootstrap {
|
||||
|
||||
int pos = value.indexOf('=');
|
||||
if (pos == -1)
|
||||
fail("Unable to parse: " + value);
|
||||
fail("Unable to parse as <module>=<value>: " + value);
|
||||
if (pos == 0)
|
||||
fail("Missing module name in: " + value);
|
||||
|
||||
@ -594,7 +602,7 @@ public final class ModuleBootstrap {
|
||||
|
||||
String rhs = value.substring(pos+1);
|
||||
if (rhs.isEmpty())
|
||||
fail("Unable to parse: " + value);
|
||||
fail("Unable to parse as <module>=<value>: " + value);
|
||||
|
||||
// value is <module>(,<module>)* or <file>(<pathsep><file>)*
|
||||
if (!allowDuplicates && map.containsKey(key))
|
||||
@ -626,6 +634,33 @@ public final class ModuleBootstrap {
|
||||
return (String)System.getProperties().remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the names and resolution bit of each module in the configuration,
|
||||
* emitting warnings if needed.
|
||||
*/
|
||||
private static void checkModuleNamesAndStatus(Configuration cf) {
|
||||
String incubating = null;
|
||||
for (ResolvedModule rm : cf.modules()) {
|
||||
ModuleReference mref = rm.reference();
|
||||
String mn = mref.descriptor().name();
|
||||
|
||||
// emit warning if module name ends with a non-Java letter
|
||||
if (!Checks.hasLegalModuleNameLastCharacter(mn))
|
||||
warn("Module name \"" + mn + "\" may soon be illegal");
|
||||
|
||||
// emit warning if the WARN_INCUBATING module resolution bit set
|
||||
if (ModuleResolution.hasIncubatingWarning(mref)) {
|
||||
if (incubating == null) {
|
||||
incubating = mn;
|
||||
} else {
|
||||
incubating += ", " + mn;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (incubating != null)
|
||||
warn("Using incubator modules: " + incubating);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws a RuntimeException with the given message
|
||||
*/
|
||||
|
@ -35,6 +35,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -50,7 +51,6 @@ public final class ModuleHashes {
|
||||
byte[] generate(String algorithm);
|
||||
}
|
||||
|
||||
|
||||
private final String algorithm;
|
||||
private final Map<String, byte[]> nameToHash;
|
||||
|
||||
@ -142,4 +142,37 @@ public final class ModuleHashes {
|
||||
}
|
||||
return new ModuleHashes(algorithm, nameToHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used by jdk.internal.module.SystemModules class
|
||||
* generated at link time.
|
||||
*/
|
||||
public static class Builder {
|
||||
final String algorithm;
|
||||
final Map<String, byte[]> nameToHash;
|
||||
|
||||
Builder(String algorithm, int initialCapacity) {
|
||||
this.nameToHash = new HashMap<>(initialCapacity);
|
||||
this.algorithm = Objects.requireNonNull(algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the module hash for the given module name
|
||||
*/
|
||||
public Builder hashForModule(String mn, byte[] hash) {
|
||||
nameToHash.put(mn, hash);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@code ModuleHashes}.
|
||||
*/
|
||||
public ModuleHashes build() {
|
||||
if (!nameToHash.isEmpty()) {
|
||||
return new ModuleHashes(algorithm, nameToHash);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.module;
|
||||
package jdk.internal.module;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
@ -31,10 +31,13 @@ import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.InvalidModuleDescriptorException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleDescriptor.Builder;
|
||||
import java.lang.module.ModuleDescriptor.Requires;
|
||||
import java.lang.module.ModuleDescriptor.Exports;
|
||||
import java.lang.module.ModuleDescriptor.Opens;
|
||||
import java.lang.module.ModuleDescriptor.Version;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.BufferUnderflowException;
|
||||
import java.util.ArrayList;
|
||||
@ -46,7 +49,9 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import jdk.internal.module.ModuleHashes;
|
||||
import jdk.internal.misc.JavaLangModuleAccess;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.module.ModuleResolution;
|
||||
|
||||
import static jdk.internal.module.ClassFileConstants.*;
|
||||
|
||||
@ -58,7 +63,10 @@ import static jdk.internal.module.ClassFileConstants.*;
|
||||
* and fine control over the throwing of InvalidModuleDescriptorException.
|
||||
*/
|
||||
|
||||
final class ModuleInfo {
|
||||
public final class ModuleInfo {
|
||||
|
||||
private static final JavaLangModuleAccess JLMA
|
||||
= SharedSecrets.getJavaLangModuleAccess();
|
||||
|
||||
// supplies the set of packages when ModulePackages attribute not present
|
||||
private final Supplier<Set<String>> packageFinder;
|
||||
@ -75,14 +83,42 @@ final class ModuleInfo {
|
||||
this(pf, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* A holder class for the ModuleDescriptor that is created by reading the
|
||||
* Module and other standard class file attributes. It also holds the objects
|
||||
* that represent the non-standard class file attributes that are read from
|
||||
* the class file.
|
||||
*/
|
||||
public static final class Attributes {
|
||||
private final ModuleDescriptor descriptor;
|
||||
private final ModuleHashes recordedHashes;
|
||||
private final ModuleResolution moduleResolution;
|
||||
Attributes(ModuleDescriptor descriptor,
|
||||
ModuleHashes recordedHashes,
|
||||
ModuleResolution moduleResolution) {
|
||||
this.descriptor = descriptor;
|
||||
this.recordedHashes = recordedHashes;
|
||||
this.moduleResolution = moduleResolution;
|
||||
}
|
||||
public ModuleDescriptor descriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
public ModuleHashes recordedHashes() {
|
||||
return recordedHashes;
|
||||
}
|
||||
public ModuleResolution moduleResolution() {
|
||||
return moduleResolution;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads a {@code module-info.class} from the given input stream.
|
||||
*
|
||||
* @throws InvalidModuleDescriptorException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static ModuleDescriptor read(InputStream in,
|
||||
Supplier<Set<String>> pf)
|
||||
public static Attributes read(InputStream in, Supplier<Set<String>> pf)
|
||||
throws IOException
|
||||
{
|
||||
try {
|
||||
@ -100,9 +136,7 @@ final class ModuleInfo {
|
||||
* @throws InvalidModuleDescriptorException
|
||||
* @throws UncheckedIOException
|
||||
*/
|
||||
public static ModuleDescriptor read(ByteBuffer bb,
|
||||
Supplier<Set<String>> pf)
|
||||
{
|
||||
public static Attributes read(ByteBuffer bb, Supplier<Set<String>> pf) {
|
||||
try {
|
||||
return new ModuleInfo(pf).doRead(new DataInputWrapper(bb));
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
@ -121,9 +155,7 @@ final class ModuleInfo {
|
||||
* @throws InvalidModuleDescriptorException
|
||||
* @throws UncheckedIOException
|
||||
*/
|
||||
static ModuleDescriptor readIgnoringHashes(ByteBuffer bb,
|
||||
Supplier<Set<String>> pf)
|
||||
{
|
||||
public static Attributes readIgnoringHashes(ByteBuffer bb, Supplier<Set<String>> pf) {
|
||||
try {
|
||||
return new ModuleInfo(pf, false).doRead(new DataInputWrapper(bb));
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
@ -144,7 +176,7 @@ final class ModuleInfo {
|
||||
* because an identifier is not a legal Java identifier, duplicate
|
||||
* exports, and many other reasons
|
||||
*/
|
||||
private ModuleDescriptor doRead(DataInput in) throws IOException {
|
||||
private Attributes doRead(DataInput in) throws IOException {
|
||||
|
||||
int magic = in.readInt();
|
||||
if (magic != 0xCAFEBABE)
|
||||
@ -163,8 +195,9 @@ final class ModuleInfo {
|
||||
throw invalidModuleDescriptor("access_flags should be ACC_MODULE");
|
||||
|
||||
int this_class = in.readUnsignedShort();
|
||||
if (this_class != 0)
|
||||
throw invalidModuleDescriptor("this_class must be 0");
|
||||
String mn = cpool.getClassName(this_class);
|
||||
if (!"module-info".equals(mn))
|
||||
throw invalidModuleDescriptor("this_class should be module-info");
|
||||
|
||||
int super_class = in.readUnsignedShort();
|
||||
if (super_class > 0)
|
||||
@ -189,10 +222,10 @@ final class ModuleInfo {
|
||||
|
||||
Builder builder = null;
|
||||
Set<String> packages = null;
|
||||
String version = null;
|
||||
String mainClass = null;
|
||||
String[] osValues = null;
|
||||
ModuleHashes hashes = null;
|
||||
ModuleResolution moduleResolution = null;
|
||||
|
||||
for (int i = 0; i < attributes_count ; i++) {
|
||||
int name_index = in.readUnsignedShort();
|
||||
@ -215,10 +248,6 @@ final class ModuleInfo {
|
||||
packages = readModulePackagesAttribute(in, cpool);
|
||||
break;
|
||||
|
||||
case MODULE_VERSION :
|
||||
version = readModuleVersionAttribute(in, cpool);
|
||||
break;
|
||||
|
||||
case MODULE_MAIN_CLASS :
|
||||
mainClass = readModuleMainClassAttribute(in, cpool);
|
||||
break;
|
||||
@ -235,6 +264,10 @@ final class ModuleInfo {
|
||||
}
|
||||
break;
|
||||
|
||||
case MODULE_RESOLUTION :
|
||||
moduleResolution = readModuleResolution(in, cpool);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isAttributeDisallowed(attribute_name)) {
|
||||
throw invalidModuleDescriptor(attribute_name
|
||||
@ -263,23 +296,33 @@ final class ModuleInfo {
|
||||
usedPackageFinder = true;
|
||||
}
|
||||
if (packages != null) {
|
||||
for (String pn : builder.exportedAndOpenPackages()) {
|
||||
if (!packages.contains(pn)) {
|
||||
String tail;
|
||||
if (usedPackageFinder) {
|
||||
tail = " not found by package finder";
|
||||
} else {
|
||||
tail = " missing from ModulePackages attribute";
|
||||
Set<String> exportedPackages = JLMA.exportedPackages(builder);
|
||||
Set<String> openPackages = JLMA.openPackages(builder);
|
||||
if (packages.containsAll(exportedPackages)
|
||||
&& packages.containsAll(openPackages)) {
|
||||
packages.removeAll(exportedPackages);
|
||||
packages.removeAll(openPackages);
|
||||
} else {
|
||||
// the set of packages is not complete
|
||||
Set<String> exportedAndOpenPackages = new HashSet<>();
|
||||
exportedAndOpenPackages.addAll(exportedPackages);
|
||||
exportedAndOpenPackages.addAll(openPackages);
|
||||
for (String pn : exportedAndOpenPackages) {
|
||||
if (!packages.contains(pn)) {
|
||||
String tail;
|
||||
if (usedPackageFinder) {
|
||||
tail = " not found by package finder";
|
||||
} else {
|
||||
tail = " missing from ModulePackages attribute";
|
||||
}
|
||||
throw invalidModuleDescriptor("Package " + pn + tail);
|
||||
}
|
||||
throw invalidModuleDescriptor("Package " + pn + tail);
|
||||
}
|
||||
packages.remove(pn);
|
||||
assert false; // should not get here
|
||||
}
|
||||
builder.contains(packages);
|
||||
}
|
||||
|
||||
if (version != null)
|
||||
builder.version(version);
|
||||
if (mainClass != null)
|
||||
builder.mainClass(mainClass);
|
||||
if (osValues != null) {
|
||||
@ -287,10 +330,9 @@ final class ModuleInfo {
|
||||
if (osValues[1] != null) builder.osArch(osValues[1]);
|
||||
if (osValues[2] != null) builder.osVersion(osValues[2]);
|
||||
}
|
||||
if (hashes != null)
|
||||
builder.hashes(hashes);
|
||||
|
||||
return builder.build();
|
||||
ModuleDescriptor descriptor = builder.build();
|
||||
return new Attributes(descriptor, hashes, moduleResolution);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -302,38 +344,55 @@ final class ModuleInfo {
|
||||
{
|
||||
// module_name
|
||||
int module_name_index = in.readUnsignedShort();
|
||||
String mn = cpool.getUtf8AsBinaryName(module_name_index);
|
||||
|
||||
Builder builder = new ModuleDescriptor.Builder(mn, /*strict*/ false);
|
||||
String mn = cpool.getModuleName(module_name_index);
|
||||
|
||||
int module_flags = in.readUnsignedShort();
|
||||
boolean open = ((module_flags & ACC_OPEN) != 0);
|
||||
if (open)
|
||||
builder.open(true);
|
||||
if ((module_flags & ACC_SYNTHETIC) != 0)
|
||||
builder.synthetic(true);
|
||||
boolean synthetic = ((module_flags & ACC_SYNTHETIC) != 0);
|
||||
|
||||
Builder builder = JLMA.newModuleBuilder(mn, false, open, synthetic);
|
||||
|
||||
int module_version_index = in.readUnsignedShort();
|
||||
if (module_version_index != 0) {
|
||||
String vs = cpool.getUtf8(module_version_index);
|
||||
builder.version(vs);
|
||||
}
|
||||
|
||||
int requires_count = in.readUnsignedShort();
|
||||
boolean requiresJavaBase = false;
|
||||
for (int i=0; i<requires_count; i++) {
|
||||
int index = in.readUnsignedShort();
|
||||
int flags = in.readUnsignedShort();
|
||||
String dn = cpool.getUtf8AsBinaryName(index);
|
||||
int requires_index = in.readUnsignedShort();
|
||||
String dn = cpool.getModuleName(requires_index);
|
||||
|
||||
int requires_flags = in.readUnsignedShort();
|
||||
Set<Requires.Modifier> mods;
|
||||
if (flags == 0) {
|
||||
if (requires_flags == 0) {
|
||||
mods = Collections.emptySet();
|
||||
} else {
|
||||
mods = new HashSet<>();
|
||||
if ((flags & ACC_TRANSITIVE) != 0)
|
||||
if ((requires_flags & ACC_TRANSITIVE) != 0)
|
||||
mods.add(Requires.Modifier.TRANSITIVE);
|
||||
if ((flags & ACC_STATIC_PHASE) != 0)
|
||||
if ((requires_flags & ACC_STATIC_PHASE) != 0)
|
||||
mods.add(Requires.Modifier.STATIC);
|
||||
if ((flags & ACC_SYNTHETIC) != 0)
|
||||
if ((requires_flags & ACC_SYNTHETIC) != 0)
|
||||
mods.add(Requires.Modifier.SYNTHETIC);
|
||||
if ((flags & ACC_MANDATED) != 0)
|
||||
if ((requires_flags & ACC_MANDATED) != 0)
|
||||
mods.add(Requires.Modifier.MANDATED);
|
||||
}
|
||||
builder.requires(mods, dn);
|
||||
|
||||
int requires_version_index = in.readUnsignedShort();
|
||||
Version compiledVersion = null;
|
||||
if (requires_version_index != 0) {
|
||||
String vs = cpool.getUtf8(requires_version_index);
|
||||
compiledVersion = Version.parse(vs);
|
||||
}
|
||||
|
||||
if (compiledVersion == null) {
|
||||
builder.requires(mods, dn);
|
||||
} else {
|
||||
builder.requires(mods, dn, compiledVersion);
|
||||
}
|
||||
|
||||
if (dn.equals("java.base"))
|
||||
requiresJavaBase = true;
|
||||
}
|
||||
@ -350,18 +409,18 @@ final class ModuleInfo {
|
||||
int exports_count = in.readUnsignedShort();
|
||||
if (exports_count > 0) {
|
||||
for (int i=0; i<exports_count; i++) {
|
||||
int index = in.readUnsignedShort();
|
||||
String pkg = cpool.getUtf8AsBinaryName(index);
|
||||
int exports_index = in.readUnsignedShort();
|
||||
String pkg = cpool.getPackageName(exports_index);
|
||||
|
||||
Set<Exports.Modifier> mods;
|
||||
int flags = in.readUnsignedShort();
|
||||
if (flags == 0) {
|
||||
int exports_flags = in.readUnsignedShort();
|
||||
if (exports_flags == 0) {
|
||||
mods = Collections.emptySet();
|
||||
} else {
|
||||
mods = new HashSet<>();
|
||||
if ((flags & ACC_SYNTHETIC) != 0)
|
||||
if ((exports_flags & ACC_SYNTHETIC) != 0)
|
||||
mods.add(Exports.Modifier.SYNTHETIC);
|
||||
if ((flags & ACC_MANDATED) != 0)
|
||||
if ((exports_flags & ACC_MANDATED) != 0)
|
||||
mods.add(Exports.Modifier.MANDATED);
|
||||
}
|
||||
|
||||
@ -370,7 +429,7 @@ final class ModuleInfo {
|
||||
Set<String> targets = new HashSet<>(exports_to_count);
|
||||
for (int j=0; j<exports_to_count; j++) {
|
||||
int exports_to_index = in.readUnsignedShort();
|
||||
targets.add(cpool.getUtf8AsBinaryName(exports_to_index));
|
||||
targets.add(cpool.getModuleName(exports_to_index));
|
||||
}
|
||||
builder.exports(mods, pkg, targets);
|
||||
} else {
|
||||
@ -386,18 +445,18 @@ final class ModuleInfo {
|
||||
+ " module must be 0 length");
|
||||
}
|
||||
for (int i=0; i<opens_count; i++) {
|
||||
int index = in.readUnsignedShort();
|
||||
String pkg = cpool.getUtf8AsBinaryName(index);
|
||||
int opens_index = in.readUnsignedShort();
|
||||
String pkg = cpool.getPackageName(opens_index);
|
||||
|
||||
Set<Opens.Modifier> mods;
|
||||
int flags = in.readUnsignedShort();
|
||||
if (flags == 0) {
|
||||
int opens_flags = in.readUnsignedShort();
|
||||
if (opens_flags == 0) {
|
||||
mods = Collections.emptySet();
|
||||
} else {
|
||||
mods = new HashSet<>();
|
||||
if ((flags & ACC_SYNTHETIC) != 0)
|
||||
if ((opens_flags & ACC_SYNTHETIC) != 0)
|
||||
mods.add(Opens.Modifier.SYNTHETIC);
|
||||
if ((flags & ACC_MANDATED) != 0)
|
||||
if ((opens_flags & ACC_MANDATED) != 0)
|
||||
mods.add(Opens.Modifier.MANDATED);
|
||||
}
|
||||
|
||||
@ -406,7 +465,7 @@ final class ModuleInfo {
|
||||
Set<String> targets = new HashSet<>(open_to_count);
|
||||
for (int j=0; j<open_to_count; j++) {
|
||||
int opens_to_index = in.readUnsignedShort();
|
||||
targets.add(cpool.getUtf8AsBinaryName(opens_to_index));
|
||||
targets.add(cpool.getModuleName(opens_to_index));
|
||||
}
|
||||
builder.opens(mods, pkg, targets);
|
||||
} else {
|
||||
@ -419,7 +478,7 @@ final class ModuleInfo {
|
||||
if (uses_count > 0) {
|
||||
for (int i=0; i<uses_count; i++) {
|
||||
int index = in.readUnsignedShort();
|
||||
String sn = cpool.getClassNameAsBinaryName(index);
|
||||
String sn = cpool.getClassName(index);
|
||||
builder.uses(sn);
|
||||
}
|
||||
}
|
||||
@ -428,12 +487,12 @@ final class ModuleInfo {
|
||||
if (provides_count > 0) {
|
||||
for (int i=0; i<provides_count; i++) {
|
||||
int index = in.readUnsignedShort();
|
||||
String sn = cpool.getClassNameAsBinaryName(index);
|
||||
String sn = cpool.getClassName(index);
|
||||
int with_count = in.readUnsignedShort();
|
||||
List<String> providers = new ArrayList<>(with_count);
|
||||
for (int j=0; j<with_count; j++) {
|
||||
index = in.readUnsignedShort();
|
||||
String pn = cpool.getClassNameAsBinaryName(index);
|
||||
String pn = cpool.getClassName(index);
|
||||
providers.add(pn);
|
||||
}
|
||||
builder.provides(sn, providers);
|
||||
@ -453,22 +512,16 @@ final class ModuleInfo {
|
||||
Set<String> packages = new HashSet<>(package_count);
|
||||
for (int i=0; i<package_count; i++) {
|
||||
int index = in.readUnsignedShort();
|
||||
String pn = cpool.getUtf8AsBinaryName(index);
|
||||
packages.add(pn);
|
||||
String pn = cpool.getPackageName(index);
|
||||
boolean added = packages.add(pn);
|
||||
if (!added) {
|
||||
throw invalidModuleDescriptor("Package " + pn + " in ModulePackages"
|
||||
+ "attribute more than once");
|
||||
}
|
||||
}
|
||||
return packages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the ModuleVersion attribute
|
||||
*/
|
||||
private String readModuleVersionAttribute(DataInput in, ConstantPool cpool)
|
||||
throws IOException
|
||||
{
|
||||
int index = in.readUnsignedShort();
|
||||
return cpool.getUtf8(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the ModuleMainClass attribute
|
||||
*/
|
||||
@ -476,7 +529,7 @@ final class ModuleInfo {
|
||||
throws IOException
|
||||
{
|
||||
int index = in.readUnsignedShort();
|
||||
return cpool.getClassNameAsBinaryName(index);
|
||||
return cpool.getClassName(index);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -516,7 +569,7 @@ final class ModuleInfo {
|
||||
Map<String, byte[]> map = new HashMap<>(hash_count);
|
||||
for (int i=0; i<hash_count; i++) {
|
||||
int module_name_index = in.readUnsignedShort();
|
||||
String mn = cpool.getUtf8AsBinaryName(module_name_index);
|
||||
String mn = cpool.getModuleName(module_name_index);
|
||||
int hash_length = in.readUnsignedShort();
|
||||
if (hash_length == 0) {
|
||||
throw invalidModuleDescriptor("hash_length == 0");
|
||||
@ -529,6 +582,31 @@ final class ModuleInfo {
|
||||
return new ModuleHashes(algorithm, map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the ModuleResolution attribute.
|
||||
*/
|
||||
private ModuleResolution readModuleResolution(DataInput in,
|
||||
ConstantPool cpool)
|
||||
throws IOException
|
||||
{
|
||||
int flags = in.readUnsignedShort();
|
||||
|
||||
int reason = 0;
|
||||
if ((flags & WARN_DEPRECATED) != 0)
|
||||
reason = WARN_DEPRECATED;
|
||||
if ((flags & WARN_DEPRECATED_FOR_REMOVAL) != 0) {
|
||||
if (reason != 0)
|
||||
throw invalidModuleDescriptor("Bad module resolution flags:" + flags);
|
||||
reason = WARN_DEPRECATED_FOR_REMOVAL;
|
||||
}
|
||||
if ((flags & WARN_INCUBATING) != 0) {
|
||||
if (reason != 0)
|
||||
throw invalidModuleDescriptor("Bad module resolution flags:" + flags);
|
||||
}
|
||||
|
||||
return new ModuleResolution(flags);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the given attribute can be present at most once
|
||||
@ -540,10 +618,10 @@ final class ModuleInfo {
|
||||
name.equals(SOURCE_FILE) ||
|
||||
name.equals(SDE) ||
|
||||
name.equals(MODULE_PACKAGES) ||
|
||||
name.equals(MODULE_VERSION) ||
|
||||
name.equals(MODULE_MAIN_CLASS) ||
|
||||
name.equals(MODULE_TARGET) ||
|
||||
name.equals(MODULE_HASHES))
|
||||
name.equals(MODULE_HASHES) ||
|
||||
name.equals(MODULE_RESOLUTION))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -604,6 +682,8 @@ final class ModuleInfo {
|
||||
static final int CONSTANT_MethodHandle = 15;
|
||||
static final int CONSTANT_MethodType = 16;
|
||||
static final int CONSTANT_InvokeDynamic = 18;
|
||||
static final int CONSTANT_Module = 19;
|
||||
static final int CONSTANT_Package = 20;
|
||||
|
||||
private static class Entry {
|
||||
protected Entry(int tag) {
|
||||
@ -653,6 +733,8 @@ final class ModuleInfo {
|
||||
break;
|
||||
|
||||
case CONSTANT_Class:
|
||||
case CONSTANT_Package:
|
||||
case CONSTANT_Module:
|
||||
case CONSTANT_String:
|
||||
int index = in.readUnsignedShort();
|
||||
pool[i] = new IndexEntry(tag, index);
|
||||
@ -715,14 +797,34 @@ final class ModuleInfo {
|
||||
throw invalidModuleDescriptor("CONSTANT_Class expected at entry: "
|
||||
+ index);
|
||||
}
|
||||
return getUtf8(((IndexEntry) e).index);
|
||||
String value = getUtf8(((IndexEntry) e).index);
|
||||
checkUnqualifiedName("CONSTANT_Class", index, value);
|
||||
return value.replace('/', '.'); // internal form -> binary name
|
||||
}
|
||||
|
||||
String getClassNameAsBinaryName(int index) {
|
||||
String value = getClassName(index);
|
||||
String getPackageName(int index) {
|
||||
checkIndex(index);
|
||||
Entry e = pool[index];
|
||||
if (e.tag != CONSTANT_Package) {
|
||||
throw invalidModuleDescriptor("CONSTANT_Package expected at entry: "
|
||||
+ index);
|
||||
}
|
||||
String value = getUtf8(((IndexEntry) e).index);
|
||||
checkUnqualifiedName("CONSTANT_Package", index, value);
|
||||
return value.replace('/', '.'); // internal form -> binary name
|
||||
}
|
||||
|
||||
String getModuleName(int index) {
|
||||
checkIndex(index);
|
||||
Entry e = pool[index];
|
||||
if (e.tag != CONSTANT_Module) {
|
||||
throw invalidModuleDescriptor("CONSTANT_Module expected at entry: "
|
||||
+ index);
|
||||
}
|
||||
String value = getUtf8(((IndexEntry) e).index);
|
||||
return decodeModuleName(index, value);
|
||||
}
|
||||
|
||||
String getUtf8(int index) {
|
||||
checkIndex(index);
|
||||
Entry e = pool[index];
|
||||
@ -733,15 +835,103 @@ final class ModuleInfo {
|
||||
return (String) (((ValueEntry) e).value);
|
||||
}
|
||||
|
||||
String getUtf8AsBinaryName(int index) {
|
||||
String value = getUtf8(index);
|
||||
return value.replace('/', '.'); // internal -> binary name
|
||||
}
|
||||
|
||||
void checkIndex(int index) {
|
||||
if (index < 1 || index >= pool.length)
|
||||
throw invalidModuleDescriptor("Index into constant pool out of range");
|
||||
}
|
||||
|
||||
void checkUnqualifiedName(String what, int index, String value) {
|
||||
int len = value.length();
|
||||
if (len == 0) {
|
||||
throw invalidModuleDescriptor(what + " at entry " + index
|
||||
+ " has zero length");
|
||||
}
|
||||
for (int i=0; i<len; i++) {
|
||||
char c = value.charAt(i);
|
||||
if (c == '.' || c == ';' || c == '[') {
|
||||
throw invalidModuleDescriptor(what + " at entry " + index
|
||||
+ " has illegal character: '"
|
||||
+ c + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* "Decode" a module name that has been read from the constant pool.
|
||||
*/
|
||||
String decodeModuleName(int index, String value) {
|
||||
int len = value.length();
|
||||
if (len == 0) {
|
||||
throw invalidModuleDescriptor("CONSTANT_Module at entry "
|
||||
+ index + " is zero length");
|
||||
}
|
||||
int i = 0;
|
||||
while (i < len) {
|
||||
int cp = value.codePointAt(i);
|
||||
if (cp == ':' || cp == '@' || cp < 0x20) {
|
||||
throw invalidModuleDescriptor("CONSTANT_Module at entry "
|
||||
+ index + " has illegal character: "
|
||||
+ Character.getName(cp));
|
||||
}
|
||||
|
||||
// blackslash is the escape character
|
||||
if (cp == '\\')
|
||||
return decodeModuleName(index, i, value);
|
||||
|
||||
i += Character.charCount(cp);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Decode" a module name that has been read from the constant pool and
|
||||
* partly checked for illegal characters (up to position {@code i}).
|
||||
*/
|
||||
String decodeModuleName(int index, int i, String value) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
// copy the code points that have been checked
|
||||
int j = 0;
|
||||
while (j < i) {
|
||||
int cp = value.codePointAt(j);
|
||||
sb.appendCodePoint(cp);
|
||||
j += Character.charCount(cp);
|
||||
}
|
||||
|
||||
// decode from position {@code i} to end
|
||||
int len = value.length();
|
||||
while (i < len) {
|
||||
int cp = value.codePointAt(i);
|
||||
if (cp == ':' || cp == '@' || cp < 0x20) {
|
||||
throw invalidModuleDescriptor("CONSTANT_Module at entry "
|
||||
+ index + " has illegal character: "
|
||||
+ Character.getName(cp));
|
||||
}
|
||||
|
||||
// blackslash is the escape character
|
||||
if (cp == '\\') {
|
||||
j = i + Character.charCount(cp);
|
||||
if (j >= len) {
|
||||
throw invalidModuleDescriptor("CONSTANT_Module at entry "
|
||||
+ index + " has illegal "
|
||||
+ "escape sequence");
|
||||
}
|
||||
int next = value.codePointAt(j);
|
||||
if (next != '\\' && next != ':' && next != '@') {
|
||||
throw invalidModuleDescriptor("CONSTANT_Module at entry "
|
||||
+ index + " has illegal "
|
||||
+ "escape sequence");
|
||||
}
|
||||
sb.appendCodePoint(next);
|
||||
i += Character.charCount(next);
|
||||
} else {
|
||||
sb.appendCodePoint(cp);
|
||||
}
|
||||
|
||||
i += Character.charCount(cp);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
@ -70,6 +70,9 @@ public final class ModuleInfoExtender {
|
||||
// the hashes for the Hashes attribute
|
||||
private ModuleHashes hashes;
|
||||
|
||||
// the value of the ModuleResolution attribute
|
||||
private ModuleResolution moduleResolution;
|
||||
|
||||
private ModuleInfoExtender(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
@ -120,6 +123,14 @@ public final class ModuleInfoExtender {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for the ModuleResolution attribute.
|
||||
*/
|
||||
public ModuleInfoExtender moduleResolution(ModuleResolution mres) {
|
||||
this.moduleResolution = mres;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A ClassVisitor that supports adding class file attributes. If an
|
||||
* attribute already exists then the first occurence of the attribute
|
||||
@ -183,21 +194,20 @@ public final class ModuleInfoExtender {
|
||||
|
||||
if (packages != null)
|
||||
cv.addAttribute(new ModulePackagesAttribute(packages));
|
||||
if (version != null)
|
||||
cv.addAttribute(new ModuleVersionAttribute(version));
|
||||
if (mainClass != null)
|
||||
cv.addAttribute(new ModuleMainClassAttribute(mainClass));
|
||||
if (osName != null || osArch != null || osVersion != null)
|
||||
cv.addAttribute(new ModuleTargetAttribute(osName, osArch, osVersion));
|
||||
if (hashes != null)
|
||||
cv.addAttribute(new ModuleHashesAttribute(hashes));
|
||||
if (moduleResolution != null)
|
||||
cv.addAttribute(new ModuleResolutionAttribute(moduleResolution.value()));
|
||||
|
||||
List<Attribute> attrs = new ArrayList<>();
|
||||
|
||||
// prototypes of attributes that should be parsed
|
||||
attrs.add(new ModuleAttribute());
|
||||
attrs.add(new ModuleAttribute(version));
|
||||
attrs.add(new ModulePackagesAttribute());
|
||||
attrs.add(new ModuleVersionAttribute());
|
||||
attrs.add(new ModuleMainClassAttribute());
|
||||
attrs.add(new ModuleTargetAttribute());
|
||||
attrs.add(new ModuleHashesAttribute());
|
||||
|
@ -49,13 +49,12 @@ public final class ModuleInfoWriter {
|
||||
* returning it in a byte array.
|
||||
*/
|
||||
private static byte[] toModuleInfo(ModuleDescriptor md) {
|
||||
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
cw.visit(Opcodes.V1_9, ACC_MODULE, null, null, null, null);
|
||||
cw.visit(Opcodes.V1_9, ACC_MODULE, "module-info", null, null, null);
|
||||
cw.visitAttribute(new ModuleAttribute(md));
|
||||
|
||||
// for tests: write the Packages attribute when there are packages that
|
||||
// aren't exported or open
|
||||
// for tests: write the ModulePackages attribute when there are packages
|
||||
// that aren't exported or open
|
||||
Stream<String> exported = md.exports().stream()
|
||||
.map(ModuleDescriptor.Exports::source);
|
||||
Stream<String> open = md.opens().stream()
|
||||
@ -64,10 +63,10 @@ public final class ModuleInfoWriter {
|
||||
if (md.packages().size() > exportedOrOpen)
|
||||
cw.visitAttribute(new ModulePackagesAttribute(md.packages()));
|
||||
|
||||
md.version().ifPresent(v -> cw.visitAttribute(new ModuleVersionAttribute(v)));
|
||||
// write ModuleMainClass if the module has a main class
|
||||
md.mainClass().ifPresent(mc -> cw.visitAttribute(new ModuleMainClassAttribute(mc)));
|
||||
|
||||
// write the TargetPlatform attribute if have any of OS name/arch/version
|
||||
// write ModuleTarget attribute if have any of OS name/arch/version
|
||||
String osName = md.osName().orElse(null);
|
||||
String osArch = md.osArch().orElse(null);
|
||||
String osVersion = md.osVersion().orElse(null);
|
||||
@ -76,7 +75,6 @@ public final class ModuleInfoWriter {
|
||||
}
|
||||
|
||||
cw.visitEnd();
|
||||
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
|
@ -149,9 +149,22 @@ public final class ModulePatcher {
|
||||
|
||||
// return a module reference to the patched module
|
||||
URI location = mref.location().orElse(null);
|
||||
return JLMA.newPatchedModule(descriptor,
|
||||
location,
|
||||
() -> new PatchedModuleReader(paths, mref));
|
||||
|
||||
ModuleHashes recordedHashes = null;
|
||||
ModuleResolution mres = null;
|
||||
if (mref instanceof ModuleReferenceImpl) {
|
||||
ModuleReferenceImpl impl = (ModuleReferenceImpl)mref;
|
||||
recordedHashes = impl.recordedHashes();
|
||||
mres = impl.moduleResolution();
|
||||
}
|
||||
|
||||
return new ModuleReferenceImpl(descriptor,
|
||||
location,
|
||||
() -> new PatchedModuleReader(paths, mref),
|
||||
this,
|
||||
recordedHashes,
|
||||
null,
|
||||
mres);
|
||||
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.module;
|
||||
package jdk.internal.module;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
@ -32,7 +32,12 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.FindException;
|
||||
import java.lang.module.InvalidModuleDescriptorException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleDescriptor.Requires;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.net.URI;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
@ -59,7 +64,6 @@ import java.util.zip.ZipFile;
|
||||
|
||||
import jdk.internal.jmod.JmodFile;
|
||||
import jdk.internal.jmod.JmodFile.Section;
|
||||
import jdk.internal.module.Checks;
|
||||
import jdk.internal.perf.PerfCounter;
|
||||
import jdk.internal.util.jar.VersionedStream;
|
||||
|
||||
@ -74,7 +78,7 @@ import jdk.internal.util.jar.VersionedStream;
|
||||
* modules in JMOD files.
|
||||
*/
|
||||
|
||||
class ModulePath implements ModuleFinder {
|
||||
public class ModulePath implements ModuleFinder {
|
||||
private static final String MODULE_INFO = "module-info.class";
|
||||
|
||||
// the version to use for multi-release modular JARs
|
||||
@ -90,7 +94,7 @@ class ModulePath implements ModuleFinder {
|
||||
// map of module name to module reference map for modules already located
|
||||
private final Map<String, ModuleReference> cachedModules = new HashMap<>();
|
||||
|
||||
ModulePath(Runtime.Version version, boolean isLinkPhase, Path... entries) {
|
||||
public ModulePath(Runtime.Version version, boolean isLinkPhase, Path... entries) {
|
||||
this.releaseVersion = version;
|
||||
this.isLinkPhase = isLinkPhase;
|
||||
this.entries = entries.clone();
|
||||
@ -99,7 +103,7 @@ class ModulePath implements ModuleFinder {
|
||||
}
|
||||
}
|
||||
|
||||
ModulePath(Path... entries) {
|
||||
public ModulePath(Path... entries) {
|
||||
this(JarFile.runtimeVersion(), false, entries);
|
||||
}
|
||||
|
||||
@ -343,11 +347,11 @@ class ModulePath implements ModuleFinder {
|
||||
*/
|
||||
private ModuleReference readJMod(Path file) throws IOException {
|
||||
try (JmodFile jf = new JmodFile(file)) {
|
||||
ModuleDescriptor md;
|
||||
ModuleInfo.Attributes attrs;
|
||||
try (InputStream in = jf.getInputStream(Section.CLASSES, MODULE_INFO)) {
|
||||
md = ModuleDescriptor.read(in, () -> jmodPackages(jf));
|
||||
attrs = ModuleInfo.read(in, () -> jmodPackages(jf));
|
||||
}
|
||||
return ModuleReferences.newJModModule(md, file);
|
||||
return ModuleReferences.newJModModule(attrs, file);
|
||||
}
|
||||
}
|
||||
|
||||
@ -557,13 +561,14 @@ class ModulePath implements ModuleFinder {
|
||||
ZipFile.OPEN_READ,
|
||||
releaseVersion))
|
||||
{
|
||||
ModuleDescriptor md;
|
||||
ModuleInfo.Attributes attrs;
|
||||
JarEntry entry = jf.getJarEntry(MODULE_INFO);
|
||||
if (entry == null) {
|
||||
|
||||
// no module-info.class so treat it as automatic module
|
||||
try {
|
||||
md = deriveModuleDescriptor(jf);
|
||||
ModuleDescriptor md = deriveModuleDescriptor(jf);
|
||||
attrs = new ModuleInfo.Attributes(md, null, null);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new FindException(
|
||||
"Unable to derive module descriptor for: "
|
||||
@ -571,11 +576,11 @@ class ModulePath implements ModuleFinder {
|
||||
}
|
||||
|
||||
} else {
|
||||
md = ModuleDescriptor.read(jf.getInputStream(entry),
|
||||
() -> jarPackages(jf));
|
||||
attrs = ModuleInfo.read(jf.getInputStream(entry),
|
||||
() -> jarPackages(jf));
|
||||
}
|
||||
|
||||
return ModuleReferences.newJarModule(md, file);
|
||||
return ModuleReferences.newJarModule(attrs, file);
|
||||
}
|
||||
}
|
||||
|
||||
@ -604,15 +609,15 @@ class ModulePath implements ModuleFinder {
|
||||
*/
|
||||
private ModuleReference readExplodedModule(Path dir) throws IOException {
|
||||
Path mi = dir.resolve(MODULE_INFO);
|
||||
ModuleDescriptor md;
|
||||
ModuleInfo.Attributes attrs;
|
||||
try (InputStream in = Files.newInputStream(mi)) {
|
||||
md = ModuleDescriptor.read(new BufferedInputStream(in),
|
||||
() -> explodedPackages(dir));
|
||||
attrs = ModuleInfo.read(new BufferedInputStream(in),
|
||||
() -> explodedPackages(dir));
|
||||
} catch (NoSuchFileException e) {
|
||||
// for now
|
||||
return null;
|
||||
}
|
||||
return ModuleReferences.newExplodedModule(md, dir);
|
||||
return ModuleReferences.newExplodedModule(attrs, dir);
|
||||
}
|
||||
|
||||
/**
|
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (c) 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.module;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleReader;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.net.URI;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* A ModuleReference implementation that supports referencing a module that
|
||||
* is patched and/or can be tied to other modules by means of hashes.
|
||||
*/
|
||||
|
||||
public class ModuleReferenceImpl extends ModuleReference {
|
||||
|
||||
private final Supplier<ModuleReader> readerSupplier;
|
||||
|
||||
// non-null if the module is patched
|
||||
private final ModulePatcher patcher;
|
||||
|
||||
// the hashes of other modules recorded in this module
|
||||
private final ModuleHashes recordedHashes;
|
||||
|
||||
// the function that computes the hash of this module
|
||||
private final ModuleHashes.HashSupplier hasher;
|
||||
|
||||
// ModuleResolution flags
|
||||
private final ModuleResolution moduleResolution;
|
||||
|
||||
// cached hash of this module to avoid needing to compute it many times
|
||||
private byte[] cachedHash;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of this class.
|
||||
*/
|
||||
ModuleReferenceImpl(ModuleDescriptor descriptor,
|
||||
URI location,
|
||||
Supplier<ModuleReader> readerSupplier,
|
||||
ModulePatcher patcher,
|
||||
ModuleHashes recordedHashes,
|
||||
ModuleHashes.HashSupplier hasher,
|
||||
ModuleResolution moduleResolution)
|
||||
{
|
||||
super(descriptor, Objects.requireNonNull(location));
|
||||
this.readerSupplier = readerSupplier;
|
||||
this.patcher = patcher;
|
||||
this.recordedHashes = recordedHashes;
|
||||
this.hasher = hasher;
|
||||
this.moduleResolution = moduleResolution;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleReader open() throws IOException {
|
||||
try {
|
||||
return readerSupplier.get();
|
||||
} catch (UncheckedIOException e) {
|
||||
throw e.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this module has been patched via --patch-module.
|
||||
*/
|
||||
public boolean isPatched() {
|
||||
return (patcher != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hashes recorded in this module or {@code null} if there
|
||||
* are no hashes recorded.
|
||||
*/
|
||||
public ModuleHashes recordedHashes() {
|
||||
return recordedHashes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the supplier that computes the hash of this module.
|
||||
*/
|
||||
ModuleHashes.HashSupplier hasher() {
|
||||
return hasher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ModuleResolution flags.
|
||||
*/
|
||||
public ModuleResolution moduleResolution() {
|
||||
return moduleResolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the hash of this module. Returns {@code null} if the hash
|
||||
* cannot be computed.
|
||||
*
|
||||
* @throws java.io.UncheckedIOException if an I/O error occurs
|
||||
*/
|
||||
public byte[] computeHash(String algorithm) {
|
||||
byte[] result = cachedHash;
|
||||
if (result != null)
|
||||
return result;
|
||||
if (hasher == null)
|
||||
return null;
|
||||
cachedHash = result = hasher.generate(algorithm);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hc = hash;
|
||||
if (hc == 0) {
|
||||
hc = descriptor().hashCode();
|
||||
hc = 43 * hc + Objects.hashCode(location());
|
||||
hc = 43 * hc + Objects.hashCode(patcher);
|
||||
if (hc == 0)
|
||||
hc = -1;
|
||||
hash = hc;
|
||||
}
|
||||
return hc;
|
||||
}
|
||||
|
||||
private int hash;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object ob) {
|
||||
if (!(ob instanceof ModuleReferenceImpl))
|
||||
return false;
|
||||
ModuleReferenceImpl that = (ModuleReferenceImpl)ob;
|
||||
|
||||
// assume module content, recorded hashes, etc. are the same
|
||||
// when the modules have equal module descriptors, are at the
|
||||
// same location, and are patched by the same patcher.
|
||||
return Objects.equals(this.descriptor(), that.descriptor())
|
||||
&& Objects.equals(this.location(), that.location())
|
||||
&& Objects.equals(this.patcher, that.patcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
}
|
@ -23,13 +23,15 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.module;
|
||||
package jdk.internal.module;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOError;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.ModuleReader;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Files;
|
||||
@ -51,10 +53,7 @@ import java.util.zip.ZipFile;
|
||||
import jdk.internal.jmod.JmodFile;
|
||||
import jdk.internal.misc.JavaLangAccess;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.module.ModuleBootstrap;
|
||||
import jdk.internal.module.ModuleHashes;
|
||||
import jdk.internal.module.ModuleHashes.HashSupplier;
|
||||
import jdk.internal.module.ModulePatcher;
|
||||
import jdk.internal.util.jar.VersionedStream;
|
||||
import sun.net.www.ParseUtil;
|
||||
|
||||
@ -75,12 +74,18 @@ class ModuleReferences {
|
||||
* Creates a ModuleReference to a module or to patched module when
|
||||
* creating modules for the boot Layer and --patch-module is specified.
|
||||
*/
|
||||
private static ModuleReference newModule(ModuleDescriptor md,
|
||||
private static ModuleReference newModule(ModuleInfo.Attributes attrs,
|
||||
URI uri,
|
||||
Supplier<ModuleReader> supplier,
|
||||
HashSupplier hasher) {
|
||||
|
||||
ModuleReference mref = new ModuleReference(md, uri, supplier, hasher);
|
||||
ModuleReference mref = new ModuleReferenceImpl(attrs.descriptor(),
|
||||
uri,
|
||||
supplier,
|
||||
null,
|
||||
attrs.recordedHashes(),
|
||||
hasher,
|
||||
attrs.moduleResolution());
|
||||
if (JLA.getBootLayer() == null)
|
||||
mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
|
||||
|
||||
@ -90,29 +95,29 @@ class ModuleReferences {
|
||||
/**
|
||||
* Creates a ModuleReference to a module packaged as a modular JAR.
|
||||
*/
|
||||
static ModuleReference newJarModule(ModuleDescriptor md, Path file) {
|
||||
static ModuleReference newJarModule(ModuleInfo.Attributes attrs, Path file) {
|
||||
URI uri = file.toUri();
|
||||
Supplier<ModuleReader> supplier = () -> new JarModuleReader(file, uri);
|
||||
HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
|
||||
return newModule(md, uri, supplier, hasher);
|
||||
return newModule(attrs, uri, supplier, hasher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ModuleReference to a module packaged as a JMOD.
|
||||
*/
|
||||
static ModuleReference newJModModule(ModuleDescriptor md, Path file) {
|
||||
static ModuleReference newJModModule(ModuleInfo.Attributes attrs, Path file) {
|
||||
URI uri = file.toUri();
|
||||
Supplier<ModuleReader> supplier = () -> new JModModuleReader(file, uri);
|
||||
HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
|
||||
return newModule(md, file.toUri(), supplier, hasher);
|
||||
return newModule(attrs, uri, supplier, hasher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ModuleReference to an exploded module.
|
||||
*/
|
||||
static ModuleReference newExplodedModule(ModuleDescriptor md, Path dir) {
|
||||
static ModuleReference newExplodedModule(ModuleInfo.Attributes attrs, Path dir) {
|
||||
Supplier<ModuleReader> supplier = () -> new ExplodedModuleReader(dir);
|
||||
return newModule(md, dir.toUri(), supplier, null);
|
||||
return newModule(attrs, dir.toUri(), supplier, null);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 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.module;
|
||||
|
||||
import java.lang.module.ModuleReference;
|
||||
import static jdk.internal.module.ClassFileConstants.*;
|
||||
|
||||
/**
|
||||
* Represents the Module Resolution flags.
|
||||
*/
|
||||
public final class ModuleResolution {
|
||||
|
||||
final int value;
|
||||
|
||||
ModuleResolution(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static ModuleResolution empty() {
|
||||
return new ModuleResolution(0);
|
||||
}
|
||||
|
||||
public boolean doNotResolveByDefault() {
|
||||
return (value & DO_NOT_RESOLVE_BY_DEFAULT) != 0;
|
||||
}
|
||||
|
||||
public boolean hasDeprecatedWarning() {
|
||||
return (value & WARN_DEPRECATED) != 0;
|
||||
}
|
||||
|
||||
public boolean hasDeprecatedForRemovalWarning() {
|
||||
return (value & WARN_DEPRECATED_FOR_REMOVAL) != 0;
|
||||
}
|
||||
|
||||
public boolean hasIncubatingWarning() {
|
||||
return (value & WARN_INCUBATING) != 0;
|
||||
}
|
||||
|
||||
public ModuleResolution withDoNotResolveByDefault() {
|
||||
return new ModuleResolution(value | DO_NOT_RESOLVE_BY_DEFAULT);
|
||||
}
|
||||
|
||||
public ModuleResolution withDeprecated() {
|
||||
if ((value & (WARN_DEPRECATED_FOR_REMOVAL | WARN_INCUBATING)) != 0)
|
||||
throw new InternalError("cannot add deprecated to " + value);
|
||||
return new ModuleResolution(value | WARN_DEPRECATED);
|
||||
}
|
||||
|
||||
public ModuleResolution withDeprecatedForRemoval() {
|
||||
if ((value & (WARN_DEPRECATED | WARN_INCUBATING)) != 0)
|
||||
throw new InternalError("cannot add deprecated for removal to " + value);
|
||||
return new ModuleResolution(value | WARN_DEPRECATED_FOR_REMOVAL);
|
||||
}
|
||||
public ModuleResolution withIncubating() {
|
||||
if ((value & (WARN_DEPRECATED | WARN_DEPRECATED_FOR_REMOVAL)) != 0)
|
||||
throw new InternalError("cannot add incubating to " + value);
|
||||
return new ModuleResolution(value | WARN_INCUBATING);
|
||||
}
|
||||
|
||||
public int value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static boolean doNotResolveByDefault(ModuleReference mref) {
|
||||
// get the DO_NOT_RESOLVE_BY_DEFAULT flag, if any
|
||||
if (!(mref instanceof ModuleReferenceImpl))
|
||||
return false;
|
||||
|
||||
ModuleResolution mres = ((ModuleReferenceImpl)mref).moduleResolution();
|
||||
if (mres != null)
|
||||
return mres.doNotResolveByDefault();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasIncubatingWarning(ModuleReference mref) {
|
||||
if (!(mref instanceof ModuleReferenceImpl))
|
||||
return false;
|
||||
|
||||
ModuleResolution mres = ((ModuleReferenceImpl)mref).moduleResolution();
|
||||
if (mres != null)
|
||||
return mres.hasIncubatingWarning();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + "[value=" + value + "]";
|
||||
}
|
||||
}
|
@ -23,12 +23,16 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.module;
|
||||
package jdk.internal.module;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReader;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.net.URI;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -36,7 +40,6 @@ import java.util.ArrayDeque;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@ -54,11 +57,7 @@ import jdk.internal.jimage.ImageReader;
|
||||
import jdk.internal.jimage.ImageReaderFactory;
|
||||
import jdk.internal.misc.JavaNetUriAccess;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.module.ModuleBootstrap;
|
||||
import jdk.internal.module.ModuleHashes;
|
||||
import jdk.internal.module.ModuleHashes.HashSupplier;
|
||||
import jdk.internal.module.SystemModules;
|
||||
import jdk.internal.module.ModulePatcher;
|
||||
import jdk.internal.perf.PerfCounter;
|
||||
|
||||
/**
|
||||
@ -69,7 +68,7 @@ import jdk.internal.perf.PerfCounter;
|
||||
* Packages attribute.
|
||||
*/
|
||||
|
||||
class SystemModuleFinder implements ModuleFinder {
|
||||
public class SystemModuleFinder implements ModuleFinder {
|
||||
|
||||
private static final JavaNetUriAccess JNUA = SharedSecrets.getJavaNetUriAccess();
|
||||
|
||||
@ -84,11 +83,12 @@ class SystemModuleFinder implements ModuleFinder {
|
||||
// ImageReader used to access all modules in the image
|
||||
private static final ImageReader imageReader;
|
||||
|
||||
// the set of modules in the run-time image
|
||||
private static final Set<ModuleReference> modules;
|
||||
// singleton finder to find modules in the run-time images
|
||||
private static final SystemModuleFinder INSTANCE;
|
||||
|
||||
// maps module name to module reference
|
||||
private static final Map<String, ModuleReference> nameToModule;
|
||||
public static SystemModuleFinder getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* For now, the module references are created eagerly on the assumption
|
||||
@ -98,72 +98,11 @@ class SystemModuleFinder implements ModuleFinder {
|
||||
long t0 = System.nanoTime();
|
||||
imageReader = ImageReaderFactory.getImageReader();
|
||||
|
||||
String[] names = moduleNames();
|
||||
ModuleDescriptor[] descriptors = descriptors(names);
|
||||
|
||||
int n = names.length;
|
||||
moduleCount.add(n);
|
||||
|
||||
ModuleReference[] mods = new ModuleReference[n];
|
||||
|
||||
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
||||
Entry<String, ModuleReference>[] map
|
||||
= (Entry<String, ModuleReference>[])new Entry[n];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
ModuleDescriptor md = descriptors[i];
|
||||
|
||||
// create the ModuleReference
|
||||
ModuleReference mref = toModuleReference(md, hashSupplier(i, names[i]));
|
||||
|
||||
mods[i] = mref;
|
||||
map[i] = Map.entry(names[i], mref);
|
||||
|
||||
// counters
|
||||
packageCount.add(md.packages().size());
|
||||
exportsCount.add(md.exports().size());
|
||||
}
|
||||
|
||||
modules = Set.of(mods);
|
||||
nameToModule = Map.ofEntries(map);
|
||||
INSTANCE = new SystemModuleFinder();
|
||||
|
||||
initTime.addElapsedTimeFrom(t0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns an array of ModuleDescriptor of the given module names.
|
||||
*
|
||||
* This obtains ModuleDescriptors from SystemModules class that is generated
|
||||
* from the jlink system-modules plugin. ModuleDescriptors have already
|
||||
* been validated at link time.
|
||||
*
|
||||
* If java.base is patched, or fastpath is disabled for troubleshooting
|
||||
* purpose, it will fall back to find system modules via jrt file system.
|
||||
*/
|
||||
private static ModuleDescriptor[] descriptors(String[] names) {
|
||||
// fastpath is enabled by default.
|
||||
// It can be disabled for troubleshooting purpose.
|
||||
boolean disabled =
|
||||
System.getProperty("jdk.system.module.finder.disabledFastPath") != null;
|
||||
|
||||
// fast loading of ModuleDescriptor of system modules
|
||||
if (isFastPathSupported() && !disabled)
|
||||
return SystemModules.modules();
|
||||
|
||||
// if fast loading of ModuleDescriptors is disabled
|
||||
// fallback to read module-info.class
|
||||
ModuleDescriptor[] descriptors = new ModuleDescriptor[names.length];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
String mn = names[i];
|
||||
ImageLocation loc = imageReader.findLocation(mn, "module-info.class");
|
||||
descriptors[i] = ModuleDescriptor.read(imageReader.getResourceBuffer(loc));
|
||||
|
||||
// add the recorded hashes of tied modules
|
||||
Hashes.add(descriptors[i]);
|
||||
}
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
private static boolean isFastPathSupported() {
|
||||
return SystemModules.MODULE_NAMES.length > 0;
|
||||
}
|
||||
@ -178,69 +117,95 @@ class SystemModuleFinder implements ModuleFinder {
|
||||
return imageReader.getModuleNames();
|
||||
}
|
||||
|
||||
private static ModuleReference toModuleReference(ModuleDescriptor md,
|
||||
HashSupplier hash)
|
||||
{
|
||||
String mn = md.name();
|
||||
URI uri = JNUA.create("jrt", "/".concat(mn));
|
||||
// the set of modules in the run-time image
|
||||
private final Set<ModuleReference> modules;
|
||||
|
||||
Supplier<ModuleReader> readerSupplier = new Supplier<>() {
|
||||
@Override
|
||||
public ModuleReader get() {
|
||||
return new ImageModuleReader(mn, uri);
|
||||
}
|
||||
};
|
||||
// maps module name to module reference
|
||||
private final Map<String, ModuleReference> nameToModule;
|
||||
|
||||
ModuleReference mref =
|
||||
new ModuleReference(md, uri, readerSupplier, hash);
|
||||
// module name to hashes
|
||||
private final Map<String, byte[]> hashes;
|
||||
|
||||
// may need a reference to a patched module if --patch-module specified
|
||||
mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
|
||||
private SystemModuleFinder() {
|
||||
String[] names = moduleNames();
|
||||
int n = names.length;
|
||||
moduleCount.add(n);
|
||||
|
||||
return mref;
|
||||
}
|
||||
// fastpath is enabled by default.
|
||||
// It can be disabled for troubleshooting purpose.
|
||||
boolean disabled =
|
||||
System.getProperty("jdk.system.module.finder.disabledFastPath") != null;
|
||||
|
||||
private static HashSupplier hashSupplier(int index, String name) {
|
||||
if (isFastPathSupported()) {
|
||||
return new HashSupplier() {
|
||||
@Override
|
||||
public byte[] generate(String algorithm) {
|
||||
return SystemModules.MODULES_TO_HASH[index];
|
||||
}
|
||||
};
|
||||
ModuleDescriptor[] descriptors;
|
||||
ModuleHashes[] recordedHashes;
|
||||
ModuleResolution[] moduleResolutions;
|
||||
|
||||
// fast loading of ModuleDescriptor of system modules
|
||||
if (isFastPathSupported() && !disabled) {
|
||||
descriptors = SystemModules.descriptors();
|
||||
recordedHashes = SystemModules.hashes();
|
||||
moduleResolutions = SystemModules.moduleResolutions();
|
||||
} else {
|
||||
return Hashes.hashFor(name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This helper class is only used when SystemModules is patched.
|
||||
* It will get the recorded hashes from module-info.class.
|
||||
*/
|
||||
private static class Hashes {
|
||||
static Map<String, byte[]> hashes = new HashMap<>();
|
||||
|
||||
static void add(ModuleDescriptor descriptor) {
|
||||
Optional<ModuleHashes> ohashes = descriptor.hashes();
|
||||
if (ohashes.isPresent()) {
|
||||
hashes.putAll(ohashes.get().hashes());
|
||||
// if fast loading of ModuleDescriptors is disabled
|
||||
// fallback to read module-info.class
|
||||
descriptors = new ModuleDescriptor[n];
|
||||
recordedHashes = new ModuleHashes[n];
|
||||
moduleResolutions = new ModuleResolution[n];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
String mn = names[i];
|
||||
ImageLocation loc = imageReader.findLocation(mn, "module-info.class");
|
||||
ModuleInfo.Attributes attrs =
|
||||
ModuleInfo.read(imageReader.getResourceBuffer(loc), null);
|
||||
descriptors[i] = attrs.descriptor();
|
||||
recordedHashes[i] = attrs.recordedHashes();
|
||||
moduleResolutions[i] = attrs.moduleResolution();
|
||||
}
|
||||
}
|
||||
|
||||
static HashSupplier hashFor(String name) {
|
||||
if (!hashes.containsKey(name))
|
||||
return null;
|
||||
|
||||
return new HashSupplier() {
|
||||
@Override
|
||||
public byte[] generate(String algorithm) {
|
||||
return hashes.get(name);
|
||||
Map<String, byte[]> hashes = null;
|
||||
boolean secondSeen = false;
|
||||
// record the hashes to build HashSupplier
|
||||
for (ModuleHashes mh : recordedHashes) {
|
||||
if (mh != null) {
|
||||
// if only one module contain ModuleHashes, use it
|
||||
if (hashes == null) {
|
||||
hashes = mh.hashes();
|
||||
} else {
|
||||
if (!secondSeen) {
|
||||
hashes = new HashMap<>(hashes);
|
||||
secondSeen = true;
|
||||
}
|
||||
hashes.putAll(mh.hashes());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
this.hashes = (hashes == null) ? Map.of() : hashes;
|
||||
|
||||
SystemModuleFinder() { }
|
||||
ModuleReference[] mods = new ModuleReference[n];
|
||||
|
||||
@SuppressWarnings(value = {"rawtypes", "unchecked"})
|
||||
Entry<String, ModuleReference>[] map
|
||||
= (Entry<String, ModuleReference>[])new Entry[n];
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
ModuleDescriptor md = descriptors[i];
|
||||
|
||||
// create the ModuleReference
|
||||
ModuleReference mref = toModuleReference(md,
|
||||
recordedHashes[i],
|
||||
hashSupplier(names[i]),
|
||||
moduleResolutions[i]);
|
||||
mods[i] = mref;
|
||||
map[i] = Map.entry(names[i], mref);
|
||||
|
||||
// counters
|
||||
packageCount.add(md.packages().size());
|
||||
exportsCount.add(md.exports().size());
|
||||
}
|
||||
|
||||
modules = Set.of(mods);
|
||||
nameToModule = Map.ofEntries(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ModuleReference> find(String name) {
|
||||
@ -253,6 +218,41 @@ class SystemModuleFinder implements ModuleFinder {
|
||||
return modules;
|
||||
}
|
||||
|
||||
private ModuleReference toModuleReference(ModuleDescriptor md,
|
||||
ModuleHashes recordedHashes,
|
||||
HashSupplier hasher,
|
||||
ModuleResolution mres) {
|
||||
String mn = md.name();
|
||||
URI uri = JNUA.create("jrt", "/".concat(mn));
|
||||
|
||||
Supplier<ModuleReader> readerSupplier = new Supplier<>() {
|
||||
@Override
|
||||
public ModuleReader get() {
|
||||
return new ImageModuleReader(mn, uri);
|
||||
}
|
||||
};
|
||||
|
||||
ModuleReference mref =
|
||||
new ModuleReferenceImpl(md, uri, readerSupplier, null,
|
||||
recordedHashes, hasher, mres);
|
||||
|
||||
// may need a reference to a patched module if --patch-module specified
|
||||
mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
|
||||
|
||||
return mref;
|
||||
}
|
||||
|
||||
private HashSupplier hashSupplier(String name) {
|
||||
if (!hashes.containsKey(name))
|
||||
return null;
|
||||
|
||||
return new HashSupplier() {
|
||||
@Override
|
||||
public byte[] generate(String algorithm) {
|
||||
return hashes.get(name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A ModuleReader for reading resources from a module linked into the
|
@ -29,14 +29,14 @@ import java.lang.module.ModuleDescriptor;
|
||||
|
||||
/*
|
||||
* SystemModules class will be generated at link time to create
|
||||
* ModuleDescriptor for the installed modules directly to improve
|
||||
* ModuleDescriptor for the system modules directly to improve
|
||||
* the module descriptor reconstitution time.
|
||||
*
|
||||
* This will skip parsing of module-info.class file and validating
|
||||
* names such as module name, package name, service and provider type names.
|
||||
* It also avoids taking a defensive copy of any collection.
|
||||
*
|
||||
* @see jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin
|
||||
* @see jdk.tools.jlink.internal.plugins.SystemModulesPlugin
|
||||
*/
|
||||
public final class SystemModules {
|
||||
/**
|
||||
@ -48,11 +48,6 @@ public final class SystemModules {
|
||||
*/
|
||||
public static final String[] MODULE_NAMES = new String[0];
|
||||
|
||||
/**
|
||||
* Hash of system modules.
|
||||
*/
|
||||
public static byte[][] MODULES_TO_HASH = new byte[0][];
|
||||
|
||||
/**
|
||||
* Number of packages in the boot layer from the installed modules.
|
||||
*
|
||||
@ -66,8 +61,24 @@ public final class SystemModules {
|
||||
*
|
||||
* When running an exploded image it returns an empty array.
|
||||
*/
|
||||
public static ModuleDescriptor[] modules() {
|
||||
throw new InternalError("should not reach here");
|
||||
public static ModuleDescriptor[] descriptors() {
|
||||
throw new InternalError("expected to be overridden at link time");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a non-empty array of ModuleHashes recorded in each module
|
||||
* in the run-time image.
|
||||
*
|
||||
* When running an exploded image it returns an empty array.
|
||||
*/
|
||||
public static ModuleHashes[] hashes() {
|
||||
throw new InternalError("expected to be overridden at link time");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a non-empty array of ModuleResolutions in the run-time image.
|
||||
*/
|
||||
public static ModuleResolution[] moduleResolutions() {
|
||||
throw new InternalError("expected to be overridden at link time");
|
||||
}
|
||||
}
|
||||
|
@ -2490,6 +2490,40 @@ public class ClassReader {
|
||||
return readUTF8(items[readUnsignedShort(index)], buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a CONSTANT_Module_info item in {@code b}. This method is intended
|
||||
* for {@link Attribute} sub classes, and is normally not needed by class
|
||||
* generators or adapters.</i>
|
||||
*
|
||||
* @param index
|
||||
* the start index of an unsigned short value in {@link #b b},
|
||||
* whose value is the index of a module constant pool item.
|
||||
* @param buf
|
||||
* buffer to be used to read the item. This buffer must be
|
||||
* sufficiently large. It is not automatically resized.
|
||||
* @return the String corresponding to the specified module item.
|
||||
*/
|
||||
public String readModule(int index, char[] buf) {
|
||||
return readUTF8(items[readUnsignedShort(index)], buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a CONSTANT_Pakcage_info item in {@code b}. This method is
|
||||
* intended for {@link Attribute} sub slasses, and is normally not needed
|
||||
* by class generators or adapters.</i>
|
||||
*
|
||||
* @param index
|
||||
* the start index of an unsigned short value in {@link #b b},
|
||||
* whose value is the index of a package constant pool item.
|
||||
* @param buf
|
||||
* buffer to be used to read the item. This buffer must be
|
||||
* sufficiently large. It is not automatically resized.
|
||||
* @return the String corresponding to the specified package item.
|
||||
*/
|
||||
public String readPackage(int index, char[] buf) {
|
||||
return readUTF8(items[readUnsignedShort(index)], buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a numeric or string constant pool item in {@link #b b}. <i>This
|
||||
* method is intended for {@link Attribute} sub classes, and is normally not
|
||||
@ -2516,6 +2550,8 @@ public class ClassReader {
|
||||
case ClassWriter.DOUBLE:
|
||||
return Double.longBitsToDouble(readLong(index));
|
||||
case ClassWriter.CLASS:
|
||||
case ClassWriter.MODULE:
|
||||
case ClassWriter.PACKAGE:
|
||||
return Type.getObjectType(readUTF8(index, buf));
|
||||
case ClassWriter.STR:
|
||||
return readUTF8(index, buf);
|
||||
|
@ -271,6 +271,16 @@ public class ClassWriter extends ClassVisitor {
|
||||
*/
|
||||
static final int INDY = 18;
|
||||
|
||||
/**
|
||||
* The type of CONSTANT_Module constant pool items.
|
||||
*/
|
||||
static final int MODULE = 19;
|
||||
|
||||
/**
|
||||
* The type of CONSTANT_Package constant pool items.
|
||||
*/
|
||||
static final int PACKAGE = 20;
|
||||
|
||||
/**
|
||||
* The base value for all CONSTANT_MethodHandle constant pool items.
|
||||
* Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
|
||||
@ -1160,6 +1170,50 @@ public class ClassWriter extends ClassVisitor {
|
||||
return newClassItem(value).index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a module name to the constant pool.
|
||||
*
|
||||
* Does nothing if the constant pool already contains a similar item.
|
||||
* <i>This method is intended for {@link Attribute} sub classes, and is
|
||||
* normally not needed by class generators or adapters.</i>
|
||||
*
|
||||
* @param value
|
||||
* the module name
|
||||
* @return the index of a new or already existing module reference item.
|
||||
*/
|
||||
public int newModule(String value) {
|
||||
key2.set(MODULE, value, null, null);
|
||||
Item result = get(key2);
|
||||
if (result == null) {
|
||||
pool.put12(MODULE, newUTF8(value));
|
||||
result = new Item(index++, key2);
|
||||
put(result);
|
||||
}
|
||||
return result.index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a package name to the constant pool.
|
||||
*
|
||||
* Does nothing if the constant pool already contains a similar item.
|
||||
* <i>This method is intended for {@link Attribute} sub classes, and is
|
||||
* normally not needed by class generators or adapters.</i>
|
||||
*
|
||||
* @param value
|
||||
* the internal name of the package.
|
||||
* @return the index of a new or already existing package reference item.
|
||||
*/
|
||||
public int newPackage(String value) {
|
||||
key2.set(PACKAGE, value, null, null);
|
||||
Item result = get(key2);
|
||||
if (result == null) {
|
||||
pool.put12(PACKAGE, newUTF8(value));
|
||||
result = new Item(index++, key2);
|
||||
put(result);
|
||||
}
|
||||
return result.index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a method type reference to the constant pool of the class being
|
||||
* build. Does nothing if the constant pool already contains a similar item.
|
||||
|
@ -239,6 +239,8 @@ final class Item {
|
||||
this.strVal3 = strVal3;
|
||||
switch (type) {
|
||||
case ClassWriter.CLASS:
|
||||
case ClassWriter.MODULE:
|
||||
case ClassWriter.PACKAGE:
|
||||
this.intVal = 0; // intVal of a class must be zero, see visitInnerClass
|
||||
case ClassWriter.UTF8:
|
||||
case ClassWriter.STR:
|
||||
@ -311,6 +313,8 @@ final class Item {
|
||||
case ClassWriter.UTF8:
|
||||
case ClassWriter.STR:
|
||||
case ClassWriter.CLASS:
|
||||
case ClassWriter.MODULE:
|
||||
case ClassWriter.PACKAGE:
|
||||
case ClassWriter.MTYPE:
|
||||
case ClassWriter.TYPE_NORMAL:
|
||||
return i.strVal1.equals(strVal1);
|
||||
|
@ -58,7 +58,6 @@ import java.security.PrivilegedAction;
|
||||
|
||||
public class Cleaner
|
||||
extends PhantomReference<Object>
|
||||
implements Runnable
|
||||
{
|
||||
|
||||
// Dummy reference queue, needed because the PhantomReference constructor
|
||||
@ -153,12 +152,4 @@ public class Cleaner
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void run() {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null)
|
||||
security.checkPackageAccess("jdk.internal.ref");
|
||||
this.clean();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.misc.SharedSecrets;
|
||||
import jdk.internal.misc.VM;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
@ -218,8 +219,16 @@ public class Reflection {
|
||||
if (c.isPrimitive())
|
||||
return true;
|
||||
|
||||
// check that memberModule exports the package to currentModule
|
||||
return memberModule.isExported(c.getPackageName(), currentModule);
|
||||
String pkg = c.getPackageName();
|
||||
boolean allowed = memberModule.isExported(pkg, currentModule);
|
||||
if (allowed && memberModule.isNamed() && printStackTraceWhenAccessSucceeds()) {
|
||||
if (!SharedSecrets.getJavaLangReflectModuleAccess()
|
||||
.isStaticallyExported(memberModule, pkg, currentModule)) {
|
||||
String msg = currentModule + " allowed access to member of " + memberClass;
|
||||
new Exception(msg).printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
return allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -348,25 +357,43 @@ public class Reflection {
|
||||
}
|
||||
|
||||
|
||||
// true to print a stack trace when IAE is thrown
|
||||
// true to print a stack trace when access fails
|
||||
private static volatile boolean printStackWhenAccessFails;
|
||||
|
||||
// true if printStackWhenAccessFails has been initialized
|
||||
private static volatile boolean printStackWhenAccessFailsSet;
|
||||
// true to print a stack trace when access succeeds
|
||||
private static volatile boolean printStackWhenAccessSucceeds;
|
||||
|
||||
private static void printStackTraceIfNeeded(Throwable e) {
|
||||
if (!printStackWhenAccessFailsSet && VM.initLevel() >= 1) {
|
||||
// true if printStack* values are initialized
|
||||
private static volatile boolean printStackPropertiesSet;
|
||||
|
||||
private static void ensurePrintStackPropertiesSet() {
|
||||
if (!printStackPropertiesSet && VM.initLevel() >= 1) {
|
||||
String s = GetPropertyAction.privilegedGetProperty(
|
||||
"sun.reflect.debugModuleAccessChecks");
|
||||
printStackWhenAccessFails =
|
||||
(s != null && !s.equalsIgnoreCase("false"));
|
||||
printStackWhenAccessFailsSet = true;
|
||||
}
|
||||
if (printStackWhenAccessFails) {
|
||||
e.printStackTrace();
|
||||
if (s != null) {
|
||||
printStackWhenAccessFails = !s.equalsIgnoreCase("false");
|
||||
printStackWhenAccessSucceeds = s.equalsIgnoreCase("access");
|
||||
}
|
||||
printStackPropertiesSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void enableStackTraces() {
|
||||
printStackWhenAccessFails = true;
|
||||
printStackWhenAccessSucceeds = true;
|
||||
printStackPropertiesSet = true;
|
||||
}
|
||||
|
||||
public static boolean printStackTraceWhenAccessFails() {
|
||||
ensurePrintStackPropertiesSet();
|
||||
return printStackWhenAccessFails;
|
||||
}
|
||||
|
||||
public static boolean printStackTraceWhenAccessSucceeds() {
|
||||
ensurePrintStackPropertiesSet();
|
||||
return printStackWhenAccessSucceeds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws IllegalAccessException with the an exception message based on
|
||||
* the access that is denied.
|
||||
@ -416,17 +443,10 @@ public class Reflection {
|
||||
throws IllegalAccessException
|
||||
{
|
||||
IllegalAccessException e = new IllegalAccessException(msg);
|
||||
printStackTraceIfNeeded(e);
|
||||
ensurePrintStackPropertiesSet();
|
||||
if (printStackWhenAccessFails) {
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws InaccessibleObjectException with the given exception message.
|
||||
*/
|
||||
public static void throwInaccessibleObjectException(String msg) {
|
||||
InaccessibleObjectException e = new InaccessibleObjectException(msg);
|
||||
printStackTraceIfNeeded(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -180,7 +180,8 @@ module java.base {
|
||||
java.management,
|
||||
jdk.jvmstat;
|
||||
exports jdk.internal.ref to
|
||||
java.desktop;
|
||||
java.desktop,
|
||||
jdk.unsupported;
|
||||
exports jdk.internal.reflect to
|
||||
java.corba,
|
||||
java.logging,
|
||||
@ -218,8 +219,9 @@ module java.base {
|
||||
java.security.jgss;
|
||||
exports sun.nio.ch to
|
||||
java.management,
|
||||
jdk.crypto.pkcs11,
|
||||
jdk.sctp;
|
||||
jdk.crypto.token,
|
||||
jdk.sctp,
|
||||
jdk.unsupported;
|
||||
exports sun.nio.cs to
|
||||
java.desktop,
|
||||
jdk.charsets;
|
||||
@ -242,14 +244,14 @@ module java.base {
|
||||
java.desktop,
|
||||
java.security.jgss;
|
||||
exports sun.security.internal.interfaces to
|
||||
jdk.crypto.pkcs11;
|
||||
jdk.crypto.token;
|
||||
exports sun.security.internal.spec to
|
||||
jdk.crypto.pkcs11;
|
||||
jdk.crypto.token;
|
||||
exports sun.security.jca to
|
||||
java.smartcardio,
|
||||
java.xml.crypto,
|
||||
jdk.crypto.ec,
|
||||
jdk.crypto.pkcs11,
|
||||
jdk.crypto.token,
|
||||
jdk.naming.dns;
|
||||
exports sun.security.pkcs to
|
||||
jdk.crypto.ec,
|
||||
@ -257,13 +259,13 @@ module java.base {
|
||||
exports sun.security.provider to
|
||||
java.rmi,
|
||||
java.security.jgss,
|
||||
jdk.crypto.pkcs11,
|
||||
jdk.crypto.token,
|
||||
jdk.policytool,
|
||||
jdk.security.auth;
|
||||
exports sun.security.provider.certpath to
|
||||
java.naming;
|
||||
exports sun.security.rsa to
|
||||
jdk.crypto.pkcs11;
|
||||
jdk.crypto.token;
|
||||
exports sun.security.ssl to
|
||||
java.security.jgss;
|
||||
exports sun.security.timestamp to
|
||||
@ -278,14 +280,14 @@ module java.base {
|
||||
java.security.sasl,
|
||||
java.smartcardio,
|
||||
jdk.crypto.ec,
|
||||
jdk.crypto.pkcs11,
|
||||
jdk.crypto.token,
|
||||
jdk.jartool,
|
||||
jdk.policytool,
|
||||
jdk.security.auth,
|
||||
jdk.security.jgss;
|
||||
exports sun.security.x509 to
|
||||
jdk.crypto.ec,
|
||||
jdk.crypto.pkcs11,
|
||||
jdk.crypto.token,
|
||||
jdk.jartool,
|
||||
jdk.security.auth;
|
||||
exports sun.text.resources to
|
||||
|
@ -48,7 +48,9 @@ public abstract class Negotiator {
|
||||
Class<?> clazz;
|
||||
Constructor<?> c;
|
||||
try {
|
||||
clazz = Class.forName("sun.net.www.protocol.http.spnego.NegotiatorImpl", true, null);
|
||||
clazz = Class.forName("sun.net.www.protocol.http.spnego.NegotiatorImpl",
|
||||
true,
|
||||
ClassLoader.getPlatformClassLoader());
|
||||
c = clazz.getConstructor(HttpCallerInfo.class);
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
finest(cnfe);
|
||||
|
@ -157,6 +157,9 @@ class ISO_8859_1
|
||||
// Method possible replaced with a compiler intrinsic.
|
||||
private static int encodeISOArray(char[] sa, int sp,
|
||||
byte[] da, int dp, int len) {
|
||||
if (len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
encodeISOArrayCheck(sa, sp, da, dp, len);
|
||||
return implEncodeISOArray(sa, sp, da, dp, len);
|
||||
}
|
||||
@ -177,10 +180,6 @@ class ISO_8859_1
|
||||
|
||||
private static void encodeISOArrayCheck(char[] sa, int sp,
|
||||
byte[] da, int dp, int len) {
|
||||
if (len <= 0) {
|
||||
return; // not an error because encodeISOArrayImpl won't execute if len <= 0
|
||||
}
|
||||
|
||||
Objects.requireNonNull(sa);
|
||||
Objects.requireNonNull(da);
|
||||
|
||||
|
@ -36,6 +36,7 @@ import java.security.AlgorithmConstraints;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
@ -122,6 +123,14 @@ abstract class Handshaker {
|
||||
// Negotiated ALPN value
|
||||
String applicationProtocol = null;
|
||||
|
||||
// Application protocol callback function (for SSLEngine)
|
||||
BiFunction<SSLEngine,List<String>,String>
|
||||
appProtocolSelectorSSLEngine = null;
|
||||
|
||||
// Application protocol callback function (for SSLSocket)
|
||||
BiFunction<SSLSocket,List<String>,String>
|
||||
appProtocolSelectorSSLSocket = null;
|
||||
|
||||
// The maximum expected network packet size for SSL/TLS/DTLS records.
|
||||
int maximumPacketSize = 0;
|
||||
|
||||
@ -500,6 +509,22 @@ abstract class Handshaker {
|
||||
return applicationProtocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Application Protocol selector function for SSLEngine.
|
||||
*/
|
||||
void setApplicationProtocolSelectorSSLEngine(
|
||||
BiFunction<SSLEngine,List<String>,String> selector) {
|
||||
this.appProtocolSelectorSSLEngine = selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Application Protocol selector function for SSLSocket.
|
||||
*/
|
||||
void setApplicationProtocolSelectorSSLSocket(
|
||||
BiFunction<SSLSocket,List<String>,String> selector) {
|
||||
this.appProtocolSelectorSSLSocket = selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cipher suites preference.
|
||||
*/
|
||||
|
@ -27,8 +27,9 @@ package sun.security.ssl;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
import java.util.*;
|
||||
import java.security.*;
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
|
||||
@ -206,6 +207,10 @@ public final class SSLEngineImpl extends SSLEngine {
|
||||
// The value under negotiation will be obtained from handshaker.
|
||||
String applicationProtocol = null;
|
||||
|
||||
// Callback function that selects the application protocol value during
|
||||
// the SSL/TLS handshake.
|
||||
BiFunction<SSLEngine, List<String>, String> applicationProtocolSelector;
|
||||
|
||||
// Have we been told whether we're client or server?
|
||||
private boolean serverModeSet = false;
|
||||
private boolean roleIsServer;
|
||||
@ -442,6 +447,8 @@ public final class SSLEngineImpl extends SSLEngine {
|
||||
handshaker.setEnabledCipherSuites(enabledCipherSuites);
|
||||
handshaker.setEnableSessionCreation(enableSessionCreation);
|
||||
handshaker.setApplicationProtocols(applicationProtocols);
|
||||
handshaker.setApplicationProtocolSelectorSSLEngine(
|
||||
applicationProtocolSelector);
|
||||
|
||||
outputRecord.initHandshaker();
|
||||
}
|
||||
@ -2264,6 +2271,21 @@ public final class SSLEngineImpl extends SSLEngine {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setHandshakeApplicationProtocolSelector(
|
||||
BiFunction<SSLEngine, List<String>, String> selector) {
|
||||
applicationProtocolSelector = selector;
|
||||
if ((handshaker != null) && !handshaker.activated()) {
|
||||
handshaker.setApplicationProtocolSelectorSSLEngine(selector);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized BiFunction<SSLEngine, List<String>, String>
|
||||
getHandshakeApplicationProtocolSelector() {
|
||||
return this.applicationProtocolSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of this end of the connection.
|
||||
*/
|
||||
|
@ -37,6 +37,7 @@ import java.security.AlgorithmConstraints;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.net.ssl.*;
|
||||
@ -223,6 +224,10 @@ public final class SSLSocketImpl extends BaseSSLSocketImpl {
|
||||
// The value under negotiation will be obtained from handshaker.
|
||||
String applicationProtocol = null;
|
||||
|
||||
// Callback function that selects the application protocol value during
|
||||
// the SSL/TLS handshake.
|
||||
BiFunction<SSLSocket, List<String>, String> applicationProtocolSelector;
|
||||
|
||||
/*
|
||||
* READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
|
||||
* IMPORTANT STUFF TO UNDERSTANDING THE SYNCHRONIZATION ISSUES.
|
||||
@ -1370,6 +1375,8 @@ public final class SSLSocketImpl extends BaseSSLSocketImpl {
|
||||
handshaker.setEnabledCipherSuites(enabledCipherSuites);
|
||||
handshaker.setEnableSessionCreation(enableSessionCreation);
|
||||
handshaker.setApplicationProtocols(applicationProtocols);
|
||||
handshaker.setApplicationProtocolSelectorSSLSocket(
|
||||
applicationProtocolSelector);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2658,6 +2665,21 @@ public final class SSLSocketImpl extends BaseSSLSocketImpl {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setHandshakeApplicationProtocolSelector(
|
||||
BiFunction<SSLSocket, List<String>, String> selector) {
|
||||
applicationProtocolSelector = selector;
|
||||
if ((handshaker != null) && !handshaker.activated()) {
|
||||
handshaker.setApplicationProtocolSelectorSSLSocket(selector);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized BiFunction<SSLSocket, List<String>, String>
|
||||
getHandshakeApplicationProtocolSelector() {
|
||||
return this.applicationProtocolSelector;
|
||||
}
|
||||
|
||||
//
|
||||
// We allocate a separate thread to deliver handshake completion
|
||||
// events. This ensures that the notifications don't block the
|
||||
|
@ -34,6 +34,7 @@ import java.security.cert.*;
|
||||
import java.security.interfaces.*;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.math.BigInteger;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.net.ssl.*;
|
||||
@ -532,31 +533,39 @@ final class ServerHandshaker extends Handshaker {
|
||||
ALPNExtension clientHelloALPN = (ALPNExtension)
|
||||
mesg.extensions.get(ExtensionType.EXT_ALPN);
|
||||
|
||||
if ((clientHelloALPN != null) && (localApl.length > 0)) {
|
||||
// Use the application protocol callback when provided.
|
||||
// Otherwise use the local list of application protocols.
|
||||
boolean hasAPCallback =
|
||||
((engine != null && appProtocolSelectorSSLEngine != null) ||
|
||||
(conn != null && appProtocolSelectorSSLSocket != null));
|
||||
|
||||
// Intersect the requested and the locally supported,
|
||||
// and save for later.
|
||||
String negotiatedValue = null;
|
||||
List<String> protocols = clientHelloALPN.getPeerAPs();
|
||||
if (!hasAPCallback) {
|
||||
if ((clientHelloALPN != null) && (localApl.length > 0)) {
|
||||
|
||||
// Use server preference order
|
||||
for (String ap : localApl) {
|
||||
if (protocols.contains(ap)) {
|
||||
negotiatedValue = ap;
|
||||
break;
|
||||
// Intersect the requested and the locally supported,
|
||||
// and save for later.
|
||||
String negotiatedValue = null;
|
||||
List<String> protocols = clientHelloALPN.getPeerAPs();
|
||||
|
||||
// Use server preference order
|
||||
for (String ap : localApl) {
|
||||
if (protocols.contains(ap)) {
|
||||
negotiatedValue = ap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (negotiatedValue == null) {
|
||||
fatalSE(Alerts.alert_no_application_protocol,
|
||||
new SSLHandshakeException(
|
||||
"No matching ALPN values"));
|
||||
}
|
||||
applicationProtocol = negotiatedValue;
|
||||
if (negotiatedValue == null) {
|
||||
fatalSE(Alerts.alert_no_application_protocol,
|
||||
new SSLHandshakeException(
|
||||
"No matching ALPN values"));
|
||||
}
|
||||
applicationProtocol = negotiatedValue;
|
||||
|
||||
} else {
|
||||
applicationProtocol = "";
|
||||
}
|
||||
} else {
|
||||
applicationProtocol = "";
|
||||
}
|
||||
} // Otherwise, applicationProtocol will be set by the callback.
|
||||
|
||||
session = null; // forget about the current session
|
||||
//
|
||||
@ -892,8 +901,36 @@ final class ServerHandshaker extends Handshaker {
|
||||
}
|
||||
|
||||
// Prepare the ALPN response
|
||||
if (applicationProtocol != null && !applicationProtocol.isEmpty()) {
|
||||
m1.extensions.add(new ALPNExtension(applicationProtocol));
|
||||
if (clientHelloALPN != null) {
|
||||
List<String> peerAPs = clientHelloALPN.getPeerAPs();
|
||||
|
||||
// check for a callback function
|
||||
if (hasAPCallback) {
|
||||
if (conn != null) {
|
||||
applicationProtocol =
|
||||
appProtocolSelectorSSLSocket.apply(conn, peerAPs);
|
||||
} else {
|
||||
applicationProtocol =
|
||||
appProtocolSelectorSSLEngine.apply(engine, peerAPs);
|
||||
}
|
||||
}
|
||||
|
||||
// check for no-match and that the selected name was also proposed
|
||||
// by the TLS peer
|
||||
if (applicationProtocol == null ||
|
||||
(!applicationProtocol.isEmpty() &&
|
||||
!peerAPs.contains(applicationProtocol))) {
|
||||
|
||||
fatalSE(Alerts.alert_no_application_protocol,
|
||||
new SSLHandshakeException(
|
||||
"No matching ALPN values"));
|
||||
|
||||
} else if (!applicationProtocol.isEmpty()) {
|
||||
m1.extensions.add(new ALPNExtension(applicationProtocol));
|
||||
}
|
||||
} else {
|
||||
// Nothing was negotiated, returned at end of the handshake
|
||||
applicationProtocol = "";
|
||||
}
|
||||
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
|
@ -1024,7 +1024,7 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
// Values from SP800-57 part 1 rev 3 tables 2 and three
|
||||
// Values from SP800-57 part 1 rev 4 tables 2 and 3
|
||||
private static String ecStrength (int bitLength) {
|
||||
if (bitLength >= 512) { // 256 bits of strength
|
||||
return "SHA512";
|
||||
@ -1035,7 +1035,7 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
// same values for RSA and DSA
|
||||
// Same values for RSA and DSA
|
||||
private static String ifcFfcStrength (int bitLength) {
|
||||
if (bitLength > 7680) { // 256 bits
|
||||
return "SHA512";
|
||||
|
@ -125,7 +125,7 @@ grant codeBase "jrt:/jdk.crypto.ec" {
|
||||
permission java.security.SecurityPermission "removeProviderProperty.SunEC";
|
||||
};
|
||||
|
||||
grant codeBase "jrt:/jdk.crypto.pkcs11" {
|
||||
grant codeBase "jrt:/jdk.crypto.token" {
|
||||
permission java.lang.RuntimePermission
|
||||
"accessClassInPackage.sun.security.*";
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 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
|
||||
@ -64,12 +64,6 @@ Java_java_lang_StrictMath_atan(JNIEnv *env, jclass unused, jdouble d)
|
||||
return (jdouble) jatan((double)d);
|
||||
}
|
||||
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_java_lang_StrictMath_exp(JNIEnv *env, jclass unused, jdouble d)
|
||||
{
|
||||
return (jdouble) jexp((double)d);
|
||||
}
|
||||
|
||||
JNIEXPORT jdouble JNICALL
|
||||
Java_java_lang_StrictMath_log(JNIEnv *env, jclass unused, jdouble d)
|
||||
{
|
||||
|
@ -181,7 +181,7 @@ void ImageDecompressor::decompress_resource(u1* compressed, u1* uncompressed,
|
||||
}
|
||||
} while (has_header);
|
||||
memcpy(uncompressed, decompressed_resource, (size_t) uncompressed_size);
|
||||
delete decompressed_resource;
|
||||
delete[] decompressed_resource;
|
||||
}
|
||||
|
||||
// Zip decompressor
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -109,13 +109,9 @@ final class ProcessImpl extends Process {
|
||||
private String helperPath(String javahome, String osArch) {
|
||||
switch (this) {
|
||||
case SOLARIS:
|
||||
if (osArch.equals("x86")) { osArch = "i386"; }
|
||||
else if (osArch.equals("x86_64")) { osArch = "amd64"; }
|
||||
// fall through...
|
||||
case LINUX:
|
||||
case AIX:
|
||||
return javahome + "/lib/" + osArch + "/jspawnhelper";
|
||||
|
||||
case BSD:
|
||||
return javahome + "/lib/jspawnhelper";
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 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
|
||||
@ -23,16 +23,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.url.iiopname;
|
||||
// jdk.vm.compiler uses Unsafe and VM classes from jdk.internal.misc
|
||||
exports jdk.internal.misc to jdk.vm.compiler;
|
||||
opens jdk.internal.misc to jdk.vm.compiler;
|
||||
|
||||
import com.sun.jndi.url.iiop.iiopURLContextFactory;
|
||||
// jdk.vm.compiler uses com.sun.crypto.provider to generate crypto intrinsics
|
||||
opens com.sun.crypto.provider to jdk.vm.compiler;
|
||||
|
||||
/**
|
||||
* An iiopname URL context factory.
|
||||
* It just uses the iiop URL context factory but is needed here
|
||||
* so that NamingManager.getURLContext() will find it.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
final public class iiopnameURLContextFactory extends iiopURLContextFactory {
|
||||
}
|
||||
exports jdk.internal.module to jdk.vm.compiler;
|
||||
|
||||
// AOT uses jdk.internal.misc.Unsafe
|
||||
exports jdk.internal.misc to jdk.aot;
|
@ -54,10 +54,8 @@ char *FindExecName(char *program);
|
||||
const char *SetExecname(char **argv);
|
||||
const char *GetExecName();
|
||||
static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
|
||||
char *jvmpath, jint jvmpathsize, const char * arch,
|
||||
int bitsWanted);
|
||||
static jboolean GetJREPath(char *path, jint pathsize, const char * arch,
|
||||
jboolean speculative);
|
||||
char *jvmpath, jint jvmpathsize, int bitsWanted);
|
||||
static jboolean GetJREPath(char *path, jint pathsize, jboolean speculative);
|
||||
|
||||
#if defined(_AIX)
|
||||
#include "java_md_aix.h"
|
||||
|
@ -52,9 +52,6 @@
|
||||
#endif
|
||||
|
||||
#ifdef __solaris__
|
||||
# ifndef LIBARCHNAME
|
||||
# error "The macro LIBARCHNAME was not defined on the compile line"
|
||||
# endif
|
||||
# include <sys/systeminfo.h>
|
||||
# include <sys/elf.h>
|
||||
# include <stdio.h>
|
||||
@ -188,12 +185,13 @@ JvmExists(const char *path) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
/*
|
||||
* contains a lib/$LIBARCHNAME/{server,client}/libjvm.so ?
|
||||
* contains a lib/{server,client}/libjvm.so ?
|
||||
*/
|
||||
static jboolean
|
||||
ContainsLibJVM(const char *env) {
|
||||
char clientPattern[PATH_MAX + 1];
|
||||
char serverPattern[PATH_MAX + 1];
|
||||
/* the usual suspects */
|
||||
char clientPattern[] = "lib/client";
|
||||
char serverPattern[] = "lib/server";
|
||||
char *envpath;
|
||||
char *path;
|
||||
jboolean clientPatternFound;
|
||||
@ -204,10 +202,6 @@ ContainsLibJVM(const char *env) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
/* the usual suspects */
|
||||
JLI_Snprintf(clientPattern, PATH_MAX, "lib/%s/client", LIBARCHNAME);
|
||||
JLI_Snprintf(serverPattern, PATH_MAX, "lib/%s/server", LIBARCHNAME);
|
||||
|
||||
/* to optimize for time, test if any of our usual suspects are present. */
|
||||
clientPatternFound = JLI_StrStr(env, clientPattern) != NULL;
|
||||
serverPatternFound = JLI_StrStr(env, serverPattern) != NULL;
|
||||
@ -322,7 +316,6 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
|
||||
/* Check data model flags, and exec process, if needed */
|
||||
{
|
||||
char *arch = LIBARCHNAME; /* like sparc or sparcv9 */
|
||||
char * jvmtype = NULL;
|
||||
int argc = *pargc;
|
||||
char **argv = *pargv;
|
||||
@ -408,12 +401,12 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
jvmpath does not exist */
|
||||
if (wanted == running) {
|
||||
/* Find out where the JRE is that we will be using. */
|
||||
if (!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) {
|
||||
if (!GetJREPath(jrepath, so_jrepath, JNI_FALSE) ) {
|
||||
JLI_ReportErrorMessage(JRE_ERROR1);
|
||||
exit(2);
|
||||
}
|
||||
JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg",
|
||||
jrepath, FILESEP, FILESEP, arch, FILESEP);
|
||||
JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%sjvm.cfg",
|
||||
jrepath, FILESEP, FILESEP, FILESEP);
|
||||
/* Find the specified JVM type */
|
||||
if (ReadKnownVMs(jvmcfg, JNI_FALSE) < 1) {
|
||||
JLI_ReportErrorMessage(CFG_ERROR7);
|
||||
@ -427,7 +420,7 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
exit(4);
|
||||
}
|
||||
|
||||
if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, arch, 0 )) {
|
||||
if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, 0 )) {
|
||||
JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath);
|
||||
exit(4);
|
||||
}
|
||||
@ -444,21 +437,21 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
return;
|
||||
}
|
||||
#else
|
||||
JLI_MemFree(newargv);
|
||||
return;
|
||||
JLI_MemFree(newargv);
|
||||
return;
|
||||
#endif /* SETENV_REQUIRED */
|
||||
} else { /* do the same speculatively or exit */
|
||||
} else { /* do the same speculatively or exit */
|
||||
JLI_ReportErrorMessage(JRE_ERROR2, wanted);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#ifdef SETENV_REQUIRED
|
||||
if (mustsetenv) {
|
||||
/*
|
||||
* We will set the LD_LIBRARY_PATH as follows:
|
||||
*
|
||||
* o $JVMPATH (directory portion only)
|
||||
* o $JRE/lib/$LIBARCHNAME
|
||||
* o $JRE/../lib/$LIBARCHNAME
|
||||
* o $JRE/lib
|
||||
* o $JRE/../lib
|
||||
*
|
||||
* followed by the user's previous effective LD_LIBRARY_PATH, if
|
||||
* any.
|
||||
@ -515,43 +508,44 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
#endif /* __solaris__ */
|
||||
|
||||
/* runpath contains current effective LD_LIBRARY_PATH setting */
|
||||
|
||||
jvmpath = JLI_StringDup(jvmpath);
|
||||
new_runpath_size = ((runpath != NULL) ? JLI_StrLen(runpath) : 0) +
|
||||
2 * JLI_StrLen(jrepath) + 2 * JLI_StrLen(arch) +
|
||||
{ /* New scope to declare local variable */
|
||||
char *new_jvmpath = JLI_StringDup(jvmpath);
|
||||
new_runpath_size = ((runpath != NULL) ? JLI_StrLen(runpath) : 0) +
|
||||
2 * JLI_StrLen(jrepath) +
|
||||
#ifdef AIX
|
||||
/* On AIX we additionally need 'jli' in the path because ld doesn't support $ORIGIN. */
|
||||
JLI_StrLen(jrepath) + JLI_StrLen(arch) + JLI_StrLen("/lib//jli:") +
|
||||
/* On AIX we additionally need 'jli' in the path because ld doesn't support $ORIGIN. */
|
||||
JLI_StrLen(jrepath) + JLI_StrLen("/lib//jli:") +
|
||||
#endif
|
||||
JLI_StrLen(jvmpath) + 52;
|
||||
new_runpath = JLI_MemAlloc(new_runpath_size);
|
||||
newpath = new_runpath + JLI_StrLen(LD_LIBRARY_PATH "=");
|
||||
JLI_StrLen(new_jvmpath) + 52;
|
||||
new_runpath = JLI_MemAlloc(new_runpath_size);
|
||||
newpath = new_runpath + JLI_StrLen(LD_LIBRARY_PATH "=");
|
||||
|
||||
|
||||
/*
|
||||
* Create desired LD_LIBRARY_PATH value for target data model.
|
||||
*/
|
||||
{
|
||||
/*
|
||||
* Create desired LD_LIBRARY_PATH value for target data model.
|
||||
*/
|
||||
{
|
||||
/* remove the name of the .so from the JVM path */
|
||||
lastslash = JLI_StrRChr(jvmpath, '/');
|
||||
lastslash = JLI_StrRChr(new_jvmpath, '/');
|
||||
if (lastslash)
|
||||
*lastslash = '\0';
|
||||
|
||||
sprintf(new_runpath, LD_LIBRARY_PATH "="
|
||||
"%s:"
|
||||
"%s/lib/%s:"
|
||||
"%s/lib:"
|
||||
#ifdef AIX
|
||||
"%s/lib/%s/jli:" /* Needed on AIX because ld doesn't support $ORIGIN. */
|
||||
"%s/lib/jli:" /* Needed on AIX because ld doesn't support $ORIGIN. */
|
||||
#endif
|
||||
"%s/../lib/%s",
|
||||
jvmpath,
|
||||
jrepath, arch,
|
||||
"%s/../lib",
|
||||
new_jvmpath,
|
||||
jrepath,
|
||||
#ifdef AIX
|
||||
jrepath, arch,
|
||||
jrepath,
|
||||
#endif
|
||||
jrepath, arch
|
||||
jrepath
|
||||
);
|
||||
|
||||
JLI_MemFree(new_jvmpath);
|
||||
|
||||
/*
|
||||
* Check to make sure that the prefix of the current path is the
|
||||
@ -571,6 +565,7 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
JLI_MemFree(new_runpath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -638,14 +633,14 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
*/
|
||||
static jboolean
|
||||
GetJVMPath(const char *jrepath, const char *jvmtype,
|
||||
char *jvmpath, jint jvmpathsize, const char * arch, int bitsWanted)
|
||||
char *jvmpath, jint jvmpathsize, int bitsWanted)
|
||||
{
|
||||
struct stat s;
|
||||
|
||||
if (JLI_StrChr(jvmtype, '/')) {
|
||||
JLI_Snprintf(jvmpath, jvmpathsize, "%s/" JVM_DLL, jvmtype);
|
||||
} else {
|
||||
JLI_Snprintf(jvmpath, jvmpathsize, "%s/lib/%s/%s/" JVM_DLL, jrepath, arch, jvmtype);
|
||||
JLI_Snprintf(jvmpath, jvmpathsize, "%s/lib/%s/" JVM_DLL, jrepath, jvmtype);
|
||||
}
|
||||
|
||||
JLI_TraceLauncher("Does `%s' exist ... ", jvmpath);
|
||||
@ -663,14 +658,14 @@ GetJVMPath(const char *jrepath, const char *jvmtype,
|
||||
* Find path to JRE based on .exe's location or registry settings.
|
||||
*/
|
||||
static jboolean
|
||||
GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative)
|
||||
GetJREPath(char *path, jint pathsize, jboolean speculative)
|
||||
{
|
||||
char libjava[MAXPATHLEN];
|
||||
struct stat s;
|
||||
|
||||
if (GetApplicationHome(path, pathsize)) {
|
||||
/* Is JRE co-located with the application? */
|
||||
JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/%s/" JAVA_DLL, path, arch);
|
||||
JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path);
|
||||
if (access(libjava, F_OK) == 0) {
|
||||
JLI_TraceLauncher("JRE path is %s\n", path);
|
||||
return JNI_TRUE;
|
||||
@ -681,7 +676,7 @@ GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative)
|
||||
return JNI_FALSE;
|
||||
}
|
||||
/* Does the app ship a private JRE in <apphome>/jre directory? */
|
||||
JLI_Snprintf(libjava, sizeof(libjava), "%s/jre/lib/%s/" JAVA_DLL, path, arch);
|
||||
JLI_Snprintf(libjava, sizeof(libjava), "%s/jre/lib/" JAVA_DLL, path);
|
||||
if (access(libjava, F_OK) == 0) {
|
||||
JLI_StrCat(path, "/jre");
|
||||
JLI_TraceLauncher("JRE path is %s\n", path);
|
||||
@ -690,7 +685,7 @@ GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative)
|
||||
}
|
||||
|
||||
if (GetApplicationHomeFromDll(path, pathsize)) {
|
||||
JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/%s/" JAVA_DLL, path, arch);
|
||||
JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path);
|
||||
if (stat(libjava, &s) == 0) {
|
||||
JLI_TraceLauncher("JRE path is %s\n", path);
|
||||
return JNI_TRUE;
|
||||
@ -856,12 +851,12 @@ void* SplashProcAddress(const char* name) {
|
||||
char jrePath[MAXPATHLEN];
|
||||
char splashPath[MAXPATHLEN];
|
||||
|
||||
if (!GetJREPath(jrePath, sizeof(jrePath), LIBARCHNAME, JNI_FALSE)) {
|
||||
if (!GetJREPath(jrePath, sizeof(jrePath), JNI_FALSE)) {
|
||||
JLI_ReportErrorMessage(JRE_ERROR1);
|
||||
return NULL;
|
||||
}
|
||||
ret = JLI_Snprintf(splashPath, sizeof(splashPath), "%s/lib/%s/%s",
|
||||
jrePath, LIBARCHNAME, SPLASHSCREEN_SO);
|
||||
ret = JLI_Snprintf(splashPath, sizeof(splashPath), "%s/lib/%s",
|
||||
jrePath, SPLASHSCREEN_SO);
|
||||
|
||||
if (ret >= (int) sizeof(splashPath)) {
|
||||
JLI_ReportErrorMessage(JRE_ERROR11);
|
||||
|
@ -37,273 +37,10 @@
|
||||
|
||||
#include "java_net_Inet4AddressImpl.h"
|
||||
|
||||
#if defined(__GLIBC__) || (defined(__FreeBSD__) && (__FreeBSD_version >= 601104))
|
||||
#define HAS_GLIBC_GETHOSTBY_R 1
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_ALLBSD_SOURCE) && !defined(HAS_GLIBC_GETHOSTBY_R)
|
||||
#if defined(MACOSX)
|
||||
extern jobjectArray lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6);
|
||||
|
||||
/* Use getaddrinfo(3), which is thread safe */
|
||||
/************************************************************************
|
||||
* Inet4AddressImpl
|
||||
*/
|
||||
|
||||
/*
|
||||
* Class: java_net_Inet4AddressImpl
|
||||
* Method: getLocalHostName
|
||||
* Signature: ()Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_java_net_Inet4AddressImpl_getLocalHostName(JNIEnv *env, jobject this) {
|
||||
char hostname[NI_MAXHOST+1];
|
||||
|
||||
hostname[0] = '\0';
|
||||
if (gethostname(hostname, NI_MAXHOST)) {
|
||||
/* Something went wrong, maybe networking is not setup? */
|
||||
strcpy(hostname, "localhost");
|
||||
} else {
|
||||
struct addrinfo hints, *res;
|
||||
int error;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
|
||||
error = getaddrinfo(hostname, NULL, &hints, &res);
|
||||
|
||||
if (error == 0) {
|
||||
/* host is known to name service */
|
||||
error = getnameinfo(res->ai_addr,
|
||||
res->ai_addrlen,
|
||||
hostname,
|
||||
NI_MAXHOST,
|
||||
NULL,
|
||||
0,
|
||||
NI_NAMEREQD);
|
||||
|
||||
/* if getnameinfo fails hostname is still the value
|
||||
from gethostname */
|
||||
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
}
|
||||
return (*env)->NewStringUTF(env, hostname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an internet address for a given hostname. Note that this
|
||||
* code only works for addresses of type INET. The translation
|
||||
* of %d.%d.%d.%d to an address (int) occurs in java now, so the
|
||||
* String "host" shouldn't *ever* be a %d.%d.%d.%d string
|
||||
*
|
||||
* Class: java_net_Inet4AddressImpl
|
||||
* Method: lookupAllHostAddr
|
||||
* Signature: (Ljava/lang/String;)[[B
|
||||
*/
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
jstring host) {
|
||||
const char *hostname;
|
||||
jobject name;
|
||||
jobjectArray ret = 0;
|
||||
int retLen = 0;
|
||||
|
||||
int getaddrinfo_error=0;
|
||||
struct addrinfo hints, *res, *resNew = NULL;
|
||||
|
||||
initInetAddressIDs(env);
|
||||
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
|
||||
|
||||
if (IS_NULL(host)) {
|
||||
JNU_ThrowNullPointerException(env, "host is null");
|
||||
return 0;
|
||||
}
|
||||
hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE);
|
||||
CHECK_NULL_RETURN(hostname, NULL);
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_family = AF_INET;
|
||||
|
||||
/*
|
||||
* Workaround for Solaris bug 4160367 - if a hostname contains a
|
||||
* white space then 0.0.0.0 is returned
|
||||
*/
|
||||
if (isspace((unsigned char)hostname[0])) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException",
|
||||
(char *)hostname);
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
getaddrinfo_error = getaddrinfo(hostname, NULL, &hints, &res);
|
||||
|
||||
#ifdef MACOSX
|
||||
if (getaddrinfo_error) {
|
||||
// If getaddrinfo fails try getifaddrs.
|
||||
ret = lookupIfLocalhost(env, hostname, JNI_FALSE);
|
||||
if (ret != NULL || (*env)->ExceptionCheck(env)) {
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (getaddrinfo_error) {
|
||||
/* report error */
|
||||
NET_ThrowUnknownHostExceptionWithGaiError(
|
||||
env, hostname, getaddrinfo_error);
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return NULL;
|
||||
} else {
|
||||
int i = 0;
|
||||
struct addrinfo *itr, *last = NULL, *iterator = res;
|
||||
while (iterator != NULL) {
|
||||
int skip = 0;
|
||||
itr = resNew;
|
||||
|
||||
while (itr != NULL) {
|
||||
struct sockaddr_in *addr1, *addr2;
|
||||
|
||||
addr1 = (struct sockaddr_in *)iterator->ai_addr;
|
||||
addr2 = (struct sockaddr_in *)itr->ai_addr;
|
||||
if (addr1->sin_addr.s_addr ==
|
||||
addr2->sin_addr.s_addr) {
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
itr = itr->ai_next;
|
||||
}
|
||||
|
||||
if (!skip) {
|
||||
struct addrinfo *next
|
||||
= (struct addrinfo*) malloc(sizeof(struct addrinfo));
|
||||
if (!next) {
|
||||
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
|
||||
ret = NULL;
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
memcpy(next, iterator, sizeof(struct addrinfo));
|
||||
next->ai_next = NULL;
|
||||
if (resNew == NULL) {
|
||||
resNew = next;
|
||||
} else {
|
||||
last->ai_next = next;
|
||||
}
|
||||
last = next;
|
||||
i++;
|
||||
}
|
||||
iterator = iterator->ai_next;
|
||||
}
|
||||
|
||||
retLen = i;
|
||||
iterator = resNew;
|
||||
i = 0;
|
||||
|
||||
name = (*env)->NewStringUTF(env, hostname);
|
||||
if (IS_NULL(name)) {
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
|
||||
ret = (*env)->NewObjectArray(env, retLen, ia_class, NULL);
|
||||
if (IS_NULL(ret)) {
|
||||
/* we may have memory to free at the end of this */
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
|
||||
while (iterator != NULL) {
|
||||
/* We need 4 bytes to store ipv4 address; */
|
||||
int len = 4;
|
||||
|
||||
jobject iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
|
||||
if (IS_NULL(iaObj)) {
|
||||
/* we may have memory to free at the end of this */
|
||||
ret = NULL;
|
||||
goto cleanupAndReturn;
|
||||
}
|
||||
setInetAddress_addr(env, iaObj, ntohl(((struct sockaddr_in*)(iterator->ai_addr))->sin_addr.s_addr));
|
||||
setInetAddress_hostName(env, iaObj, name);
|
||||
(*env)->SetObjectArrayElement(env, ret, retLen - i -1, iaObj);
|
||||
i++;
|
||||
iterator = iterator->ai_next;
|
||||
}
|
||||
}
|
||||
|
||||
cleanupAndReturn:
|
||||
{
|
||||
struct addrinfo *iterator, *tmp;
|
||||
iterator = resNew;
|
||||
while (iterator != NULL) {
|
||||
tmp = iterator;
|
||||
iterator = iterator->ai_next;
|
||||
free(tmp);
|
||||
}
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: java_net_Inet4AddressImpl
|
||||
* Method: getHostByAddr
|
||||
* Signature: (I)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
|
||||
jbyteArray addrArray) {
|
||||
jstring ret = NULL;
|
||||
|
||||
char host[NI_MAXHOST+1];
|
||||
jfieldID fid;
|
||||
int error = 0;
|
||||
jint family;
|
||||
struct sockaddr *him ;
|
||||
int len = 0;
|
||||
jbyte caddr[4];
|
||||
jint addr;
|
||||
|
||||
struct sockaddr_in him4;
|
||||
struct sockaddr *sa;
|
||||
|
||||
/*
|
||||
* For IPv4 addresses construct a sockaddr_in structure.
|
||||
*/
|
||||
(*env)->GetByteArrayRegion(env, addrArray, 0, 4, caddr);
|
||||
addr = ((caddr[0]<<24) & 0xff000000);
|
||||
addr |= ((caddr[1] <<16) & 0xff0000);
|
||||
addr |= ((caddr[2] <<8) & 0xff00);
|
||||
addr |= (caddr[3] & 0xff);
|
||||
memset((char *) &him4, 0, sizeof(him4));
|
||||
him4.sin_addr.s_addr = htonl(addr);
|
||||
him4.sin_family = AF_INET;
|
||||
sa = (struct sockaddr *) &him4;
|
||||
len = sizeof(him4);
|
||||
|
||||
error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
|
||||
|
||||
if (!error) {
|
||||
ret = (*env)->NewStringUTF(env, host);
|
||||
}
|
||||
|
||||
if (ret == NULL) {
|
||||
JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
#else /* defined(_ALLBSD_SOURCE) && !defined(HAS_GLIBC_GETHOSTBY_R) */
|
||||
|
||||
/* the initial size of our hostent buffers */
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
@ -405,6 +142,17 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
|
||||
error = getaddrinfo(hostname, NULL, &hints, &res);
|
||||
|
||||
#ifdef MACOSX
|
||||
if (error) {
|
||||
// If getaddrinfo fails try getifaddrs, see bug 8170910.
|
||||
ret = lookupIfLocalhost(env, hostname, JNI_FALSE);
|
||||
if (ret != NULL || (*env)->ExceptionCheck(env)) {
|
||||
JNU_ReleaseStringPlatformChars(env, host, hostname);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (error) {
|
||||
/* report error */
|
||||
NET_ThrowUnknownHostExceptionWithGaiError(env, hostname, error);
|
||||
@ -475,7 +223,7 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
|
||||
}
|
||||
}
|
||||
|
||||
cleanupAndReturn:
|
||||
cleanupAndReturn:
|
||||
{
|
||||
struct addrinfo *iterator, *tmp;
|
||||
iterator = resNew;
|
||||
@ -535,8 +283,6 @@ Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* _ALLBSD_SOURCE */
|
||||
|
||||
#define SET_NONBLOCKING(fd) { \
|
||||
int flags = fcntl(fd, F_GETFL); \
|
||||
flags |= O_NONBLOCK; \
|
||||
|
@ -150,22 +150,6 @@ IsJavaw()
|
||||
return _isjavaw;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the arch path, to get the current arch use the
|
||||
* macro GetArch, nbits here is ignored for now.
|
||||
*/
|
||||
const char *
|
||||
GetArchPath(int nbits)
|
||||
{
|
||||
#ifdef _M_AMD64
|
||||
return "amd64";
|
||||
#elif defined(_M_IA64)
|
||||
return "ia64";
|
||||
#else
|
||||
return "i386";
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
@ -207,8 +191,8 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
||||
exit(2);
|
||||
}
|
||||
|
||||
JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg",
|
||||
jrepath, FILESEP, FILESEP, (char*)GetArch(), FILESEP);
|
||||
JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%sjvm.cfg",
|
||||
jrepath, FILESEP, FILESEP);
|
||||
|
||||
/* Find the specified JVM type */
|
||||
if (ReadKnownVMs(jvmcfg, JNI_FALSE) < 1) {
|
||||
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Supplements {@code java.compact2} with JDBC RowSet, JMX, JNDI, Compiler,
|
||||
* Instrumentation, Preferences, Security, and XML cryptography APIs.
|
||||
*/
|
||||
module java.compact3 {
|
||||
requires transitive java.compact2;
|
||||
requires transitive java.compiler;
|
||||
requires transitive java.instrument;
|
||||
requires transitive java.management;
|
||||
requires transitive java.naming;
|
||||
requires transitive java.prefs;
|
||||
requires transitive java.security.jgss;
|
||||
requires transitive java.security.sasl;
|
||||
requires transitive java.sql.rowset;
|
||||
requires transitive java.xml.crypto;
|
||||
}
|
||||
|
@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.cosnaming;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.spi.NamingManager;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.omg.CosNaming.*;
|
||||
|
||||
/**
|
||||
* Implements the JNDI NamingEnumeration interface for COS
|
||||
* Naming. Gets hold of a list of bindings from the COS Naming Server
|
||||
* and allows the client to iterate through them.
|
||||
*
|
||||
* @author Raj Krishnamurthy
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
final class CNBindingEnumeration
|
||||
implements NamingEnumeration<javax.naming.Binding> {
|
||||
|
||||
private static final int DEFAULT_BATCHSIZE = 100;
|
||||
private BindingListHolder _bindingList; // list of bindings
|
||||
private BindingIterator _bindingIter; // iterator for getting list of bindings
|
||||
private int counter; // pointer in _bindingList
|
||||
private int batchsize = DEFAULT_BATCHSIZE; // how many to ask for each time
|
||||
private CNCtx _ctx; // ctx to list
|
||||
private Hashtable<?,?> _env; // environment for getObjectInstance
|
||||
private boolean more = false; // iterator done?
|
||||
private boolean isLookedUpCtx = false; // iterating on a context beneath this context ?
|
||||
|
||||
/**
|
||||
* Creates a CNBindingEnumeration object.
|
||||
* @param ctx Context to enumerate
|
||||
*/
|
||||
CNBindingEnumeration(CNCtx ctx, boolean isLookedUpCtx, Hashtable<?,?> env) {
|
||||
// Get batch size to use
|
||||
String batch = (env != null ?
|
||||
(String)env.get(javax.naming.Context.BATCHSIZE) : null);
|
||||
if (batch != null) {
|
||||
try {
|
||||
batchsize = Integer.parseInt(batch);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Batch size not numeric: " + batch);
|
||||
}
|
||||
}
|
||||
_ctx = ctx;
|
||||
_ctx.incEnumCount();
|
||||
this.isLookedUpCtx = isLookedUpCtx;
|
||||
_env = env;
|
||||
_bindingList = new BindingListHolder();
|
||||
BindingIteratorHolder _bindingIterH = new BindingIteratorHolder();
|
||||
|
||||
// Perform listing and request that bindings be returned in _bindingIter
|
||||
// Upon return,_bindingList returns a zero length list
|
||||
_ctx._nc.list(0, _bindingList, _bindingIterH);
|
||||
|
||||
_bindingIter = _bindingIterH.value;
|
||||
|
||||
// Get first batch using _bindingIter
|
||||
if (_bindingIter != null) {
|
||||
more = _bindingIter.next_n(batchsize, _bindingList);
|
||||
} else {
|
||||
more = false;
|
||||
}
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next binding in the list.
|
||||
* @exception NamingException any naming exception.
|
||||
*/
|
||||
|
||||
public javax.naming.Binding next() throws NamingException {
|
||||
if (more && counter >= _bindingList.value.length) {
|
||||
getMore();
|
||||
}
|
||||
if (more && counter < _bindingList.value.length) {
|
||||
org.omg.CosNaming.Binding bndg = _bindingList.value[counter];
|
||||
counter++;
|
||||
return mapBinding(bndg);
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true or false depending on whether there are more bindings.
|
||||
* @return boolean value
|
||||
*/
|
||||
|
||||
public boolean hasMore() throws NamingException {
|
||||
// If there's more, check whether current bindingList has been exhausted,
|
||||
// and if so, try to get more.
|
||||
// If no more, just say so.
|
||||
return more ? (counter < _bindingList.value.length || getMore()) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true or false depending on whether there are more bindings.
|
||||
* Need to define this to satisfy the Enumeration api requirement.
|
||||
* @return boolean value
|
||||
*/
|
||||
|
||||
public boolean hasMoreElements() {
|
||||
try {
|
||||
return hasMore();
|
||||
} catch (NamingException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next binding in the list.
|
||||
* @exception NoSuchElementException Thrown when the end of the
|
||||
* list is reached.
|
||||
*/
|
||||
|
||||
public javax.naming.Binding nextElement() {
|
||||
try {
|
||||
return next();
|
||||
} catch (NamingException ne) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws NamingException {
|
||||
more = false;
|
||||
if (_bindingIter != null) {
|
||||
_bindingIter.destroy();
|
||||
_bindingIter = null;
|
||||
}
|
||||
if (_ctx != null) {
|
||||
_ctx.decEnumCount();
|
||||
|
||||
/**
|
||||
* context was obtained by CNCtx, the user doesn't have a handle to
|
||||
* it, close it as we are done enumerating through the context
|
||||
*/
|
||||
if (isLookedUpCtx) {
|
||||
_ctx.close();
|
||||
}
|
||||
_ctx = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalize() {
|
||||
try {
|
||||
close();
|
||||
} catch (NamingException e) {
|
||||
// ignore failures
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next batch using _bindingIter. Update the 'more' field.
|
||||
*/
|
||||
private boolean getMore() throws NamingException {
|
||||
try {
|
||||
more = _bindingIter.next_n(batchsize, _bindingList);
|
||||
counter = 0; // reset
|
||||
} catch (Exception e) {
|
||||
more = false;
|
||||
NamingException ne = new NamingException(
|
||||
"Problem getting binding list");
|
||||
ne.setRootCause(e);
|
||||
throw ne;
|
||||
}
|
||||
return more;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a JNDI Binding object from the COS Naming binding
|
||||
* object.
|
||||
* @exception NameNotFound No objects under the name.
|
||||
* @exception CannotProceed Unable to obtain a continuation context
|
||||
* @exception InvalidName Name not understood.
|
||||
* @exception NamingException One of the above.
|
||||
*/
|
||||
|
||||
private javax.naming.Binding mapBinding(org.omg.CosNaming.Binding bndg)
|
||||
throws NamingException {
|
||||
java.lang.Object obj = _ctx.callResolve(bndg.binding_name);
|
||||
|
||||
Name cname = CNNameParser.cosNameToName(bndg.binding_name);
|
||||
|
||||
try {
|
||||
obj = NamingManager.getObjectInstance(obj, cname, _ctx, _env);
|
||||
} catch (NamingException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
NamingException ne = new NamingException(
|
||||
"problem generating object using object factory");
|
||||
ne.setRootCause(e);
|
||||
throw ne;
|
||||
}
|
||||
|
||||
// Use cname.toString() instead of bindingName because the name
|
||||
// in the binding should be a composite name
|
||||
String cnameStr = cname.toString();
|
||||
javax.naming.Binding jbndg = new javax.naming.Binding(cnameStr, obj);
|
||||
|
||||
NameComponent[] comps = _ctx.makeFullName(bndg.binding_name);
|
||||
String fullName = CNNameParser.cosNameToInsString(comps);
|
||||
jbndg.setNameInNamespace(fullName);
|
||||
return jbndg;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.cosnaming;
|
||||
|
||||
import javax.naming.spi.InitialContextFactory;
|
||||
import javax.naming.*;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* Implements the JNDI SPI InitialContextFactory interface used to
|
||||
* create the InitialContext objects.
|
||||
*
|
||||
* @author Raj Krishnamurthy
|
||||
*/
|
||||
|
||||
public class CNCtxFactory implements InitialContextFactory {
|
||||
|
||||
/**
|
||||
* Creates the InitialContext object. Properties parameter should
|
||||
* should contain the ORB object for the value jndi.corba.orb.
|
||||
* @param env Properties object
|
||||
*/
|
||||
|
||||
public Context getInitialContext(Hashtable<?,?> env) throws NamingException {
|
||||
return new CNCtx(env);
|
||||
}
|
||||
}
|
@ -1,500 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.cosnaming;
|
||||
|
||||
import javax.naming.*;
|
||||
import java.util.Properties;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import org.omg.CosNaming.NameComponent;
|
||||
|
||||
/**
|
||||
* Parsing routines for NameParser as well as COS Naming stringified names.
|
||||
* This is used by CNCtx to create a NameComponent[] object and vice versa.
|
||||
* It follows Section 4.5 of Interoperable Naming Service (INS) 98-10-11.
|
||||
* In summary, the stringified form is a left-to-right, forward-slash
|
||||
* separated name. id and kinds are separated by '.'. backslash is the
|
||||
* escape character.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
final public class CNNameParser implements NameParser {
|
||||
|
||||
private static final Properties mySyntax = new Properties();
|
||||
private static final char kindSeparator = '.';
|
||||
private static final char compSeparator = '/';
|
||||
private static final char escapeChar = '\\';
|
||||
static {
|
||||
mySyntax.put("jndi.syntax.direction", "left_to_right");
|
||||
mySyntax.put("jndi.syntax.separator", ""+compSeparator);
|
||||
mySyntax.put("jndi.syntax.escape", ""+escapeChar);
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a new name parser for parsing names in INS syntax.
|
||||
*/
|
||||
public CNNameParser() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a CompoundName given a string in INS syntax.
|
||||
* @param name The non-null string representation of the name.
|
||||
* @return a non-null CompoundName
|
||||
*/
|
||||
public Name parse(String name) throws NamingException {
|
||||
Vector<String> comps = insStringToStringifiedComps(name);
|
||||
return new CNCompoundName(comps.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a NameComponent[] from a Name structure.
|
||||
* Used by CNCtx to convert the input Name arg into a NameComponent[].
|
||||
* @param a CompoundName or a CompositeName;
|
||||
* each component must be the stringified form of a NameComponent.
|
||||
*/
|
||||
static NameComponent[] nameToCosName(Name name)
|
||||
throws InvalidNameException {
|
||||
int len = name.size();
|
||||
if (len == 0) {
|
||||
return new NameComponent[0];
|
||||
}
|
||||
|
||||
NameComponent[] answer = new NameComponent[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
answer[i] = parseComponent(name.get(i));
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the INS stringified form of a NameComponent[].
|
||||
* Used by CNCtx.getNameInNamespace(), CNCompoundName.toString().
|
||||
*/
|
||||
static String cosNameToInsString(NameComponent[] cname) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
for ( int i = 0; i < cname.length; i++) {
|
||||
if ( i > 0) {
|
||||
str.append(compSeparator);
|
||||
}
|
||||
str.append(stringifyComponent(cname[i]));
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CompositeName from a NameComponent[].
|
||||
* Used by ExceptionMapper and CNBindingEnumeration to convert
|
||||
* a NameComponent[] into a composite name.
|
||||
*/
|
||||
static Name cosNameToName(NameComponent[] cname) {
|
||||
Name nm = new CompositeName();
|
||||
for ( int i = 0; cname != null && i < cname.length; i++) {
|
||||
try {
|
||||
nm.add(stringifyComponent(cname[i]));
|
||||
} catch (InvalidNameException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return nm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an INS-syntax string name into a Vector in which
|
||||
* each element of the vector contains a stringified form of
|
||||
* a NameComponent.
|
||||
*/
|
||||
private static Vector<String> insStringToStringifiedComps(String str)
|
||||
throws InvalidNameException {
|
||||
|
||||
int len = str.length();
|
||||
Vector<String> components = new Vector<>(10);
|
||||
char[] id = new char[len];
|
||||
char[] kind = new char[len];
|
||||
int idCount, kindCount;
|
||||
boolean idMode;
|
||||
for (int i = 0; i < len; ) {
|
||||
idCount = kindCount = 0; // reset for new component
|
||||
idMode = true; // always start off parsing id
|
||||
while (i < len) {
|
||||
if (str.charAt(i) == compSeparator) {
|
||||
break;
|
||||
|
||||
} else if (str.charAt(i) == escapeChar) {
|
||||
if (i + 1 >= len) {
|
||||
throw new InvalidNameException(str +
|
||||
": unescaped \\ at end of component");
|
||||
} else if (isMeta(str.charAt(i+1))) {
|
||||
++i; // skip escape and let meta through
|
||||
if (idMode) {
|
||||
id[idCount++] = str.charAt(i++);
|
||||
} else {
|
||||
kind[kindCount++] = str.charAt(i++);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidNameException(str +
|
||||
": invalid character being escaped");
|
||||
}
|
||||
|
||||
} else if (idMode && str.charAt(i) == kindSeparator) {
|
||||
// just look for the first kindSeparator
|
||||
++i; // skip kind separator
|
||||
idMode = false;
|
||||
|
||||
} else {
|
||||
if (idMode) {
|
||||
id[idCount++] = str.charAt(i++);
|
||||
} else {
|
||||
kind[kindCount++] = str.charAt(i++);
|
||||
}
|
||||
}
|
||||
}
|
||||
components.addElement(stringifyComponent(
|
||||
new NameComponent(new String(id, 0, idCount),
|
||||
new String(kind, 0, kindCount))));
|
||||
|
||||
if (i < len) {
|
||||
++i; // skip separator
|
||||
}
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a NameComponent given its stringified form.
|
||||
*/
|
||||
private static NameComponent parseComponent(String compStr)
|
||||
throws InvalidNameException {
|
||||
NameComponent comp = new NameComponent();
|
||||
int kindSep = -1;
|
||||
int len = compStr.length();
|
||||
|
||||
int j = 0;
|
||||
char[] newStr = new char[len];
|
||||
boolean escaped = false;
|
||||
|
||||
// Find the kind separator
|
||||
for (int i = 0; i < len && kindSep < 0; i++) {
|
||||
if (escaped) {
|
||||
newStr[j++] = compStr.charAt(i);
|
||||
escaped = false;
|
||||
} else if (compStr.charAt(i) == escapeChar) {
|
||||
if (i + 1 >= len) {
|
||||
throw new InvalidNameException(compStr +
|
||||
": unescaped \\ at end of component");
|
||||
} else if (isMeta(compStr.charAt(i+1))) {
|
||||
escaped = true;
|
||||
} else {
|
||||
throw new InvalidNameException(compStr +
|
||||
": invalid character being escaped");
|
||||
}
|
||||
} else if (compStr.charAt(i) == kindSeparator) {
|
||||
kindSep = i;
|
||||
} else {
|
||||
newStr[j++] = compStr.charAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Set id
|
||||
comp.id = new String(newStr, 0, j);
|
||||
|
||||
// Set kind
|
||||
if (kindSep < 0) {
|
||||
comp.kind = ""; // no kind separator
|
||||
} else {
|
||||
// unescape kind
|
||||
j = 0;
|
||||
escaped = false;
|
||||
for (int i = kindSep+1; i < len; i++) {
|
||||
if (escaped) {
|
||||
newStr[j++] = compStr.charAt(i);
|
||||
escaped = false;
|
||||
} else if (compStr.charAt(i) == escapeChar) {
|
||||
if (i + 1 >= len) {
|
||||
throw new InvalidNameException(compStr +
|
||||
": unescaped \\ at end of component");
|
||||
} else if (isMeta(compStr.charAt(i+1))) {
|
||||
escaped = true;
|
||||
} else {
|
||||
throw new InvalidNameException(compStr +
|
||||
": invalid character being escaped");
|
||||
}
|
||||
} else {
|
||||
newStr[j++] = compStr.charAt(i);
|
||||
}
|
||||
}
|
||||
comp.kind = new String(newStr, 0, j);
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
|
||||
private static String stringifyComponent(NameComponent comp) {
|
||||
StringBuilder one = new StringBuilder(escape(comp.id));
|
||||
if (comp.kind != null && !comp.kind.equals("")) {
|
||||
one.append(kindSeparator).append(escape(comp.kind));
|
||||
}
|
||||
if (one.length() == 0) {
|
||||
return ""+kindSeparator; // if neither id nor kind specified
|
||||
} else {
|
||||
return one.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with '.', '\', '/' escaped. Used when
|
||||
* stringifying the name into its INS stringified form.
|
||||
*/
|
||||
private static String escape(String str) {
|
||||
if (str.indexOf(kindSeparator) < 0 &&
|
||||
str.indexOf(compSeparator) < 0 &&
|
||||
str.indexOf(escapeChar) < 0) {
|
||||
return str; // no meta characters to escape
|
||||
} else {
|
||||
int len = str.length();
|
||||
int j = 0;
|
||||
char[] newStr = new char[len+len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (isMeta(str.charAt(i))) {
|
||||
newStr[j++] = escapeChar; // escape meta character
|
||||
}
|
||||
newStr[j++] = str.charAt(i);
|
||||
}
|
||||
return new String(newStr, 0, j);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In INS, there are three meta characters: '.', '/' and '\'.
|
||||
*/
|
||||
private static boolean isMeta(char ch) {
|
||||
switch (ch) {
|
||||
case kindSeparator:
|
||||
case compSeparator:
|
||||
case escapeChar:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* An implementation of CompoundName that bypasses the parsing
|
||||
* and stringifying code of the default CompoundName.
|
||||
*/
|
||||
static final class CNCompoundName extends CompoundName {
|
||||
CNCompoundName(Enumeration<String> enum_) {
|
||||
super(enum_, CNNameParser.mySyntax);
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return new CNCompoundName(getAll());
|
||||
}
|
||||
|
||||
public Name getPrefix(int posn) {
|
||||
Enumeration<String> comps = super.getPrefix(posn).getAll();
|
||||
return new CNCompoundName(comps);
|
||||
}
|
||||
|
||||
public Name getSuffix(int posn) {
|
||||
Enumeration<String> comps = super.getSuffix(posn).getAll();
|
||||
return new CNCompoundName(comps);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
try {
|
||||
// Convert Name to NameComponent[] then stringify
|
||||
return cosNameToInsString(nameToCosName(this));
|
||||
} catch (InvalidNameException e) {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -6599252802678482317L;
|
||||
}
|
||||
|
||||
// for testing only
|
||||
/*
|
||||
private static void print(String input) {
|
||||
try {
|
||||
System.out.println("\n >>>>>> input: " + input);
|
||||
|
||||
System.out.println("--Compound Name: ");
|
||||
NameParser parser = new CNNameParser();
|
||||
Name name = parser.parse(input);
|
||||
for (int i = 0; i < name.size(); i++) {
|
||||
System.out.println("\t" + i + ": " + name.get(i));
|
||||
NameComponent cp = parseComponent(name.get(i));
|
||||
System.out.println("\t\t" + "id: " + cp.id + ";kind: " + cp.kind);
|
||||
}
|
||||
System.out.println("\t" + name.toString());
|
||||
|
||||
System.out.println("--Composite Name: ");
|
||||
Name composite = new CompositeName(input);
|
||||
for (int i = 0; i < composite.size(); i++) {
|
||||
System.out.println("\t" + i+": " + composite.get(i));
|
||||
}
|
||||
System.out.println("\t" + composite.toString());
|
||||
|
||||
System.out.println("--Composite To NameComponent");
|
||||
NameComponent[] names = nameToCosName(composite);
|
||||
for (int i = 0; i < composite.size(); i++) {
|
||||
System.out.println("\t" + i+": id: " + names[i].id + "; kind: " + names[i].kind);
|
||||
}
|
||||
System.out.println("\t" + cosNameToInsString(names));
|
||||
} catch (NamingException e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkName(Name name, String[] comps) throws Exception {
|
||||
if (name.size() != comps.length) {
|
||||
throw new Exception(
|
||||
"test failed; incorrect component count in " + name + "; " +
|
||||
"expecting " + comps.length + " got " + name.size());
|
||||
}
|
||||
for (int i = 0; i < name.size(); i++) {
|
||||
if (!comps[i].equals(name.get(i))) {
|
||||
throw new Exception (
|
||||
"test failed; invalid component in " + name + "; " +
|
||||
"expecting '" + comps[i] + "' got '" + name.get(i) + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkCompound(NameParser parser,
|
||||
String input, String[] comps) throws Exception {
|
||||
checkName(parser.parse(input), comps);
|
||||
}
|
||||
|
||||
private static void checkComposite(String input, String[] comps)
|
||||
throws Exception {
|
||||
checkName(new CompositeName(input), comps);
|
||||
}
|
||||
|
||||
private static String[] compounds = {
|
||||
"a/b/c",
|
||||
"a.b/c.d",
|
||||
"a",
|
||||
".",
|
||||
"a.",
|
||||
"c.d",
|
||||
".e",
|
||||
"a/x\\/y\\/z/b",
|
||||
"a\\.b.c\\.d/e.f",
|
||||
"a/b\\\\/c",
|
||||
"x\\\\.y",
|
||||
"x\\.y",
|
||||
"x.\\\\y",
|
||||
"x.y\\\\",
|
||||
"\\\\x.y",
|
||||
"a.b\\.c/d"
|
||||
};
|
||||
private static String[][] compoundComps = {
|
||||
{"a", "b", "c"},
|
||||
{"a.b", "c.d"},
|
||||
{"a"},
|
||||
{"."},
|
||||
{"a"},
|
||||
{"c.d"},
|
||||
{".e"},
|
||||
{"a", "x\\/y\\/z", "b"},
|
||||
{"a\\.b.c\\.d", "e.f"},
|
||||
{"a", "b\\\\", "c"},
|
||||
{"x\\\\.y"},
|
||||
{"x\\.y"},
|
||||
{"x.\\\\y"},
|
||||
{"x.y\\\\"},
|
||||
{"\\\\x.y"},
|
||||
{"a.b\\.c", "d"},
|
||||
};
|
||||
|
||||
private static String[] composites = {
|
||||
"a/b/c",
|
||||
"a.b/c.d",
|
||||
"a",
|
||||
".",
|
||||
"a.",
|
||||
"c.d",
|
||||
".e",
|
||||
"a/x\\\\\\/y\\\\\\/z/b",
|
||||
"a\\\\.b.c\\\\.d/e.f",
|
||||
"a/b\\\\\\\\/c",
|
||||
"x\\\\\\.y",
|
||||
"x\\\\.y",
|
||||
"x.\\\\\\\\y",
|
||||
"x.y\\\\\\\\",
|
||||
"\\\\\\\\x.y"
|
||||
};
|
||||
|
||||
private static String[][] compositeComps = {
|
||||
{"a", "b", "c"},
|
||||
{"a.b", "c.d"},
|
||||
{"a"},
|
||||
{"."},
|
||||
{"a."}, // unlike compound, kind sep is not consumed
|
||||
{"c.d"},
|
||||
{".e"},
|
||||
{"a", "x\\/y\\/z", "b"},
|
||||
{"a\\.b.c\\.d", "e.f"},
|
||||
{"a", "b\\\\", "c"},
|
||||
{"x\\\\.y"},
|
||||
{"x\\.y"},
|
||||
{"x.\\\\y"},
|
||||
{"x.y\\\\"},
|
||||
{"\\\\x.y"}
|
||||
};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length > 0) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
print(args[0]);
|
||||
}
|
||||
} else {
|
||||
print("x\\\\.y");
|
||||
print("x\\.y");
|
||||
print("x.\\\\y");
|
||||
print("x.y\\\\");
|
||||
print("\\\\x.y");
|
||||
}
|
||||
|
||||
NameParser parser = new com.sun.jndi.cosnaming.CNNameParser();
|
||||
for (int i = 0; i < compounds.length; i++) {
|
||||
checkCompound(parser, compounds[i], compoundComps[i]);
|
||||
}
|
||||
for (int i = 0; i < composites.length; i++) {
|
||||
checkComposite(composites[i], compositeComps[i]);
|
||||
}
|
||||
|
||||
System.out.println("hardwire");
|
||||
NameComponent[] foo = new NameComponent[1];
|
||||
foo[0] = new NameComponent("foo\\", "bar");
|
||||
|
||||
System.out.println(cosNameToInsString(foo));
|
||||
System.out.println(cosNameToName(foo));
|
||||
}
|
||||
*/
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.cosnaming;
|
||||
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import com.sun.jndi.toolkit.url.UrlUtil;
|
||||
|
||||
/**
|
||||
* Extract components of a "corbaname" URL.
|
||||
*
|
||||
* The format of an corbaname URL is defined in INS 99-12-03 as follows.
|
||||
* <pre>{@code
|
||||
* corbaname url = "corbaname:" <corbaloc_obj> ["#" <string_name>]
|
||||
* corbaloc_obj = <obj_addr_list> ["/" <key_string>]
|
||||
* obj_addr_list = as defined in a corbaloc URL
|
||||
* key_string = as defined in a corbaloc URL
|
||||
* string_name = stringified COS name | empty_string
|
||||
* }</pre>
|
||||
* Characters in {@code <string_name>} are escaped as follows.
|
||||
* US-ASCII alphanumeric characters are not escaped. Any characters outside
|
||||
* of this range are escaped except for the following:
|
||||
* <pre>{@code
|
||||
* ; / : ? @ & = + $ , - _ . ! ~ * ; ( )
|
||||
* }</pre>
|
||||
* Escaped characters is escaped by using a % followed by its 2 hexadecimal
|
||||
* numbers representing the octet.
|
||||
* <p>
|
||||
* The corbaname URL is parsed into two parts: a corbaloc URL and a COS name.
|
||||
* The corbaloc URL is constructed by concatenation {@code "corbaloc:"} with
|
||||
* {@code <corbaloc_obj>}.
|
||||
* The COS name is {@code <string_name>} with the escaped characters resolved.
|
||||
* <p>
|
||||
* A corbaname URL is resolved by:
|
||||
* <ol>
|
||||
* <li>Construct a corbaloc URL by concatenating {@code "corbaloc:"} and {@code <corbaloc_obj>}.
|
||||
* <li>Resolve the corbaloc URL to a NamingContext by using
|
||||
* <pre>{@code
|
||||
* nctx = ORB.string_to_object(corbalocUrl);
|
||||
* }</pre>
|
||||
* <li>Resolve {@code <string_name>} in the NamingContext.
|
||||
* </ol>
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
public final class CorbanameUrl {
|
||||
private String stringName;
|
||||
private String location;
|
||||
|
||||
/**
|
||||
* Returns a possibly empty but non-null string that is the "string_name"
|
||||
* portion of the URL.
|
||||
*/
|
||||
public String getStringName() {
|
||||
return stringName;
|
||||
}
|
||||
|
||||
public Name getCosName() throws NamingException {
|
||||
return CNCtx.parser.parse(stringName);
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return "corbaloc:" + location;
|
||||
}
|
||||
|
||||
public CorbanameUrl(String url) throws MalformedURLException {
|
||||
|
||||
if (!url.startsWith("corbaname:")) {
|
||||
throw new MalformedURLException("Invalid corbaname URL: " + url);
|
||||
}
|
||||
|
||||
int addrStart = 10; // "corbaname:"
|
||||
|
||||
int addrEnd = url.indexOf('#', addrStart);
|
||||
if (addrEnd < 0) {
|
||||
addrEnd = url.length();
|
||||
stringName = "";
|
||||
} else {
|
||||
stringName = UrlUtil.decode(url.substring(addrEnd+1));
|
||||
}
|
||||
location = url.substring(addrStart, addrEnd);
|
||||
|
||||
int keyStart = location.indexOf('/');
|
||||
if (keyStart >= 0) {
|
||||
// Has key string
|
||||
if (keyStart == (location.length() -1)) {
|
||||
location += "NameService";
|
||||
}
|
||||
} else {
|
||||
location += "/NameService";
|
||||
}
|
||||
}
|
||||
/*
|
||||
// for testing only
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
CorbanameUrl url = new CorbanameUrl(args[0]);
|
||||
|
||||
System.out.println("location: " + url.getLocation());
|
||||
System.out.println("string name: " + url.getStringName());
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
@ -1,242 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.cosnaming;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.directory.*;
|
||||
import javax.naming.spi.*;
|
||||
|
||||
import org.omg.CosNaming.*;
|
||||
import org.omg.CosNaming.NamingContextPackage.*;
|
||||
import org.omg.CORBA.*;
|
||||
|
||||
/**
|
||||
* A convenience class to map the COS Naming exceptions to the JNDI exceptions.
|
||||
* @author Raj Krishnamurthy
|
||||
*/
|
||||
|
||||
public final class ExceptionMapper {
|
||||
private ExceptionMapper() {} // ensure no instance
|
||||
private static final boolean debug = false;
|
||||
|
||||
public static final NamingException mapException(Exception e,
|
||||
CNCtx ctx, NameComponent[] inputName) throws NamingException {
|
||||
if (e instanceof NamingException) {
|
||||
return (NamingException)e;
|
||||
}
|
||||
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException)e;
|
||||
}
|
||||
|
||||
NamingException ne;
|
||||
if (e instanceof NotFound) {
|
||||
if (ctx.federation) {
|
||||
return tryFed((NotFound)e, ctx, inputName);
|
||||
|
||||
} else {
|
||||
ne = new NameNotFoundException();
|
||||
}
|
||||
|
||||
} else if (e instanceof CannotProceed) {
|
||||
|
||||
ne = new CannotProceedException();
|
||||
NamingContext nc = ((CannotProceed) e).cxt;
|
||||
NameComponent[] rest = ((CannotProceed) e).rest_of_name;
|
||||
|
||||
// %%% We assume that rest returns *all* unprocessed components.
|
||||
// Don't' know if that is a good assumption, given
|
||||
// NotFound doesn't set rest as expected. -RL
|
||||
if (inputName != null && (inputName.length > rest.length)) {
|
||||
NameComponent[] resolvedName =
|
||||
new NameComponent[inputName.length - rest.length];
|
||||
System.arraycopy(inputName, 0, resolvedName, 0, resolvedName.length);
|
||||
// Wrap resolved NamingContext inside a CNCtx
|
||||
// Guess that its name (which is relative to ctx)
|
||||
// is the part of inputName minus rest_of_name
|
||||
ne.setResolvedObj(new CNCtx(ctx._orb, ctx.orbTracker, nc,
|
||||
ctx._env,
|
||||
ctx.makeFullName(resolvedName)));
|
||||
} else {
|
||||
ne.setResolvedObj(ctx);
|
||||
}
|
||||
|
||||
ne.setRemainingName(CNNameParser.cosNameToName(rest));
|
||||
|
||||
} else if (e instanceof InvalidName) {
|
||||
ne = new InvalidNameException();
|
||||
} else if (e instanceof AlreadyBound) {
|
||||
ne = new NameAlreadyBoundException();
|
||||
} else if (e instanceof NotEmpty) {
|
||||
ne = new ContextNotEmptyException();
|
||||
} else {
|
||||
ne = new NamingException("Unknown reasons");
|
||||
}
|
||||
|
||||
ne.setRootCause(e);
|
||||
return ne;
|
||||
}
|
||||
|
||||
private static final NamingException tryFed(NotFound e, CNCtx ctx,
|
||||
NameComponent[] inputName) throws NamingException {
|
||||
NameComponent[] rest = e.rest_of_name;
|
||||
|
||||
if (debug) {
|
||||
System.out.println(e.why.value());
|
||||
System.out.println(rest.length);
|
||||
}
|
||||
|
||||
// %%% Using 1.2 & 1.3 Sun's tnameserv, 'rest' contains only the first
|
||||
// component that failed, not *rest* as advertized. This is useless
|
||||
// because what if you have something like aa/aa/aa/aa/aa.
|
||||
// If one of those is not found, you get "aa" as 'rest'.
|
||||
if (rest.length == 1 && inputName != null) {
|
||||
// Check that we're not talking to 1.2/1.3 Sun tnameserv
|
||||
NameComponent lastIn = inputName[inputName.length-1];
|
||||
if (rest[0].id.equals(lastIn.id) &&
|
||||
rest[0].kind != null &&
|
||||
rest[0].kind.equals(lastIn.kind)) {
|
||||
// Might be legit
|
||||
;
|
||||
} else {
|
||||
// Due to 1.2/1.3 bug that always returns single-item 'rest'
|
||||
NamingException ne = new NameNotFoundException();
|
||||
ne.setRemainingName(CNNameParser.cosNameToName(rest));
|
||||
ne.setRootCause(e);
|
||||
throw ne;
|
||||
}
|
||||
}
|
||||
// Fixed in 1.4; perform calculations based on correct (1.4) behavior
|
||||
|
||||
// Calculate the components of the name that has been resolved
|
||||
NameComponent[] resolvedName = null;
|
||||
int len = 0;
|
||||
if (inputName != null && (inputName.length >= rest.length)) {
|
||||
|
||||
if (e.why == NotFoundReason.not_context) {
|
||||
// First component of rest is found but not a context; keep it
|
||||
// as part of resolved name
|
||||
len = inputName.length - (rest.length - 1);
|
||||
|
||||
// Remove resolved component from rest
|
||||
if (rest.length == 1) {
|
||||
// No more remaining
|
||||
rest = null;
|
||||
} else {
|
||||
NameComponent[] tmp = new NameComponent[rest.length-1];
|
||||
System.arraycopy(rest, 1, tmp, 0, tmp.length);
|
||||
rest = tmp;
|
||||
}
|
||||
} else {
|
||||
len = inputName.length - rest.length;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
resolvedName = new NameComponent[len];
|
||||
System.arraycopy(inputName, 0, resolvedName, 0, len);
|
||||
}
|
||||
}
|
||||
|
||||
// Create CPE and set common fields
|
||||
CannotProceedException cpe = new CannotProceedException();
|
||||
cpe.setRootCause(e);
|
||||
if (rest != null && rest.length > 0) {
|
||||
cpe.setRemainingName(CNNameParser.cosNameToName(rest));
|
||||
}
|
||||
cpe.setEnvironment(ctx._env);
|
||||
|
||||
if (debug) {
|
||||
System.out.println("rest of name: " + cpe.getRemainingName());
|
||||
}
|
||||
|
||||
// Lookup resolved name to get resolved object
|
||||
final java.lang.Object resolvedObj =
|
||||
(resolvedName != null) ? ctx.callResolve(resolvedName) : ctx;
|
||||
|
||||
if (resolvedObj instanceof javax.naming.Context) {
|
||||
// obj is a context and child is not found
|
||||
// try getting its nns dynamically by constructing
|
||||
// a Reference containing obj.
|
||||
RefAddr addr = new RefAddr("nns") {
|
||||
public java.lang.Object getContent() {
|
||||
return resolvedObj;
|
||||
}
|
||||
private static final long serialVersionUID =
|
||||
669984699392133792L;
|
||||
};
|
||||
Reference ref = new Reference("java.lang.Object", addr);
|
||||
|
||||
// Resolved name has trailing slash to indicate nns
|
||||
CompositeName cname = new CompositeName();
|
||||
cname.add(""); // add trailing slash
|
||||
|
||||
cpe.setResolvedObj(ref);
|
||||
cpe.setAltName(cname);
|
||||
cpe.setAltNameCtx((javax.naming.Context)resolvedObj);
|
||||
|
||||
return cpe;
|
||||
} else {
|
||||
// Not a context, use object factory to transform object.
|
||||
|
||||
Name cname = CNNameParser.cosNameToName(resolvedName);
|
||||
java.lang.Object resolvedObj2;
|
||||
try {
|
||||
resolvedObj2 = NamingManager.getObjectInstance(resolvedObj,
|
||||
cname, ctx, ctx._env);
|
||||
} catch (NamingException ge) {
|
||||
throw ge;
|
||||
} catch (Exception ge) {
|
||||
NamingException ne = new NamingException(
|
||||
"problem generating object using object factory");
|
||||
ne.setRootCause(ge);
|
||||
throw ne;
|
||||
}
|
||||
|
||||
// If a context, continue operation with context
|
||||
if (resolvedObj2 instanceof javax.naming.Context) {
|
||||
cpe.setResolvedObj(resolvedObj2);
|
||||
} else {
|
||||
// Add trailing slash
|
||||
cname.add("");
|
||||
cpe.setAltName(cname);
|
||||
|
||||
// Create nns reference
|
||||
final java.lang.Object rf2 = resolvedObj2;
|
||||
RefAddr addr = new RefAddr("nns") {
|
||||
public java.lang.Object getContent() {
|
||||
return rf2;
|
||||
}
|
||||
private static final long serialVersionUID =
|
||||
-785132553978269772L;
|
||||
};
|
||||
Reference ref = new Reference("java.lang.Object", addr);
|
||||
cpe.setResolvedObj(ref);
|
||||
cpe.setAltNameCtx(ctx);
|
||||
}
|
||||
return cpe;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.cosnaming;
|
||||
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Vector;
|
||||
import java.util.StringTokenizer;
|
||||
import com.sun.jndi.toolkit.url.UrlUtil;
|
||||
|
||||
/**
|
||||
* Extract components of an "iiop" or "iiopname" URL.
|
||||
*
|
||||
* The format of an iiopname URL is defined in INS 98-10-11 as follows:
|
||||
*
|
||||
* <pre>
|
||||
* iiopname url = "iiopname://" [addr_list]["/" string_name]
|
||||
* addr_list = [address ","]* address
|
||||
* address = [version host [":" port]]
|
||||
* host = DNS style host name | IP address
|
||||
* version = major "." minor "@" | empty_string
|
||||
* port = number
|
||||
* major = number
|
||||
* minor = number
|
||||
* string_name = stringified name | empty_string
|
||||
* </pre>
|
||||
*
|
||||
* The default port is 9999. The default version is "1.0"
|
||||
* US-ASCII alphanumeric characters are not escaped. Any characters outside
|
||||
* of this range are escaped except for the following:
|
||||
* <pre>{@code
|
||||
* ; / : ? : @ & = + $ , - _ . ! ~ * ' ( )
|
||||
* }</pre>
|
||||
* Escaped characters is escaped by using a % followed by its 2 hexadecimal
|
||||
* numbers representing the octet.
|
||||
*
|
||||
* For backward compatibility, the "iiop" URL as defined in INS 97-6-6
|
||||
* is also supported:
|
||||
* <pre>{@code
|
||||
* iiop url = "iiop://" [host [":" port]] ["/" string_name]
|
||||
* }</pre>
|
||||
* The default port is 900.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
public final class IiopUrl {
|
||||
static final private int DEFAULT_IIOPNAME_PORT = 9999;
|
||||
static final private int DEFAULT_IIOP_PORT = 900;
|
||||
static final private String DEFAULT_HOST = "localhost";
|
||||
private Vector<Address> addresses;
|
||||
private String stringName;
|
||||
|
||||
public static class Address {
|
||||
public int port = -1;
|
||||
public int major, minor;
|
||||
public String host;
|
||||
|
||||
public Address(String hostPortVers, boolean oldFormat)
|
||||
throws MalformedURLException {
|
||||
// [version host [":" port]]
|
||||
int start;
|
||||
|
||||
// Parse version
|
||||
int at;
|
||||
if (oldFormat || (at = hostPortVers.indexOf('@')) < 0) {
|
||||
major = 1;
|
||||
minor = 0;
|
||||
start = 0; // start at the beginning
|
||||
} else {
|
||||
int dot = hostPortVers.indexOf('.');
|
||||
if (dot < 0) {
|
||||
throw new MalformedURLException(
|
||||
"invalid version: " + hostPortVers);
|
||||
}
|
||||
try {
|
||||
major = Integer.parseInt(hostPortVers.substring(0, dot));
|
||||
minor = Integer.parseInt(hostPortVers.substring(dot+1, at));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new MalformedURLException(
|
||||
"Nonnumeric version: " + hostPortVers);
|
||||
}
|
||||
start = at + 1; // skip '@' sign
|
||||
}
|
||||
|
||||
// Parse host and port
|
||||
int slash = hostPortVers.indexOf('/', start);
|
||||
if (slash < 0) {
|
||||
slash = hostPortVers.length();
|
||||
}
|
||||
if (hostPortVers.startsWith("[", start)) { // at IPv6 literal
|
||||
int brac = hostPortVers.indexOf(']', start + 1);
|
||||
if (brac < 0 || brac > slash) {
|
||||
throw new IllegalArgumentException(
|
||||
"IiopURL: name is an Invalid URL: " + hostPortVers);
|
||||
}
|
||||
|
||||
// include brackets
|
||||
host = hostPortVers.substring(start, brac + 1);
|
||||
start = brac + 1;
|
||||
} else { // at hostname or IPv4
|
||||
int colon = hostPortVers.indexOf(':', start);
|
||||
int hostEnd = (colon < 0 || colon > slash)
|
||||
? slash
|
||||
: colon;
|
||||
if (start < hostEnd) {
|
||||
host = hostPortVers.substring(start, hostEnd);
|
||||
}
|
||||
start = hostEnd; // skip past host
|
||||
}
|
||||
if ((start + 1 < slash)) {
|
||||
if ( hostPortVers.startsWith(":", start)) { // parse port
|
||||
start++; // skip past ":"
|
||||
port = Integer.parseInt(hostPortVers.
|
||||
substring(start, slash));
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"IiopURL: name is an Invalid URL: " + hostPortVers);
|
||||
}
|
||||
}
|
||||
start = slash;
|
||||
if ("".equals(host) || host == null) {
|
||||
host = DEFAULT_HOST ;
|
||||
}
|
||||
if (port == -1) {
|
||||
port = (oldFormat ? DEFAULT_IIOP_PORT :
|
||||
DEFAULT_IIOPNAME_PORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector<Address> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a possibly empty but non-null string that is the "string_name"
|
||||
* portion of the URL.
|
||||
*/
|
||||
public String getStringName() {
|
||||
return stringName;
|
||||
}
|
||||
|
||||
public Name getCosName() throws NamingException {
|
||||
return CNCtx.parser.parse(stringName);
|
||||
}
|
||||
|
||||
public IiopUrl(String url) throws MalformedURLException {
|
||||
int addrStart;
|
||||
boolean oldFormat;
|
||||
|
||||
if (url.startsWith("iiopname://")) {
|
||||
oldFormat = false;
|
||||
addrStart = 11;
|
||||
} else if (url.startsWith("iiop://")) {
|
||||
oldFormat = true;
|
||||
addrStart = 7;
|
||||
} else {
|
||||
throw new MalformedURLException("Invalid iiop/iiopname URL: " + url);
|
||||
}
|
||||
int addrEnd = url.indexOf('/', addrStart);
|
||||
if (addrEnd < 0) {
|
||||
addrEnd = url.length();
|
||||
stringName = "";
|
||||
} else {
|
||||
stringName = UrlUtil.decode(url.substring(addrEnd+1));
|
||||
}
|
||||
addresses = new Vector<>(3);
|
||||
if (oldFormat) {
|
||||
// Only one host:port part, not multiple
|
||||
addresses.addElement(
|
||||
new Address(url.substring(addrStart, addrEnd), oldFormat));
|
||||
} else {
|
||||
StringTokenizer tokens =
|
||||
new StringTokenizer(url.substring(addrStart, addrEnd), ",");
|
||||
while (tokens.hasMoreTokens()) {
|
||||
addresses.addElement(new Address(tokens.nextToken(), oldFormat));
|
||||
}
|
||||
if (addresses.size() == 0) {
|
||||
addresses.addElement(new Address("", oldFormat));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for testing only
|
||||
/*public static void main(String[] args) {
|
||||
try {
|
||||
IiopUrl url = new IiopUrl(args[0]);
|
||||
Vector addrs = url.getAddresses();
|
||||
String name = url.getStringName();
|
||||
|
||||
for (int i = 0; i < addrs.size(); i++) {
|
||||
Address addr = (Address)addrs.elementAt(i);
|
||||
System.out.println("host: " + addr.host);
|
||||
System.out.println("port: " + addr.port);
|
||||
System.out.println("version: " + addr.major + " " + addr.minor);
|
||||
}
|
||||
System.out.println("name: " + name);
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} */
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.cosnaming;
|
||||
|
||||
import org.omg.CORBA.ORB;
|
||||
|
||||
/**
|
||||
* This class keeps track of references to the shared ORB object
|
||||
* and destroys it when no more references are made to the ORB
|
||||
* object. This object is created for each ORB object that CNCtx
|
||||
* creates.
|
||||
*/
|
||||
class OrbReuseTracker {
|
||||
|
||||
int referenceCnt;
|
||||
ORB orb;
|
||||
|
||||
private static final boolean debug = false;
|
||||
|
||||
OrbReuseTracker(ORB orb) {
|
||||
this.orb = orb;
|
||||
referenceCnt++;
|
||||
if (debug) {
|
||||
System.out.println("New OrbReuseTracker created");
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void incRefCount() {
|
||||
referenceCnt++;
|
||||
if (debug) {
|
||||
System.out.println("Increment orb ref count to:" + referenceCnt);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void decRefCount() {
|
||||
referenceCnt--;
|
||||
if (debug) {
|
||||
System.out.println("Decrement orb ref count to:" + referenceCnt);
|
||||
}
|
||||
if ((referenceCnt == 0)) {
|
||||
if (debug) {
|
||||
System.out.println("Destroying the ORB");
|
||||
}
|
||||
orb.destroy();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.cosnaming;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.spi.StateFactory;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.omg.CORBA.ORB;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.server.ExportException;
|
||||
|
||||
import com.sun.jndi.toolkit.corba.CorbaUtils; // for RMI-IIOP
|
||||
|
||||
/**
|
||||
* StateFactory that turns java.rmi.Remote objects to org.omg.CORBA.Object.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
public class RemoteToCorba implements StateFactory {
|
||||
public RemoteToCorba() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CORBA object for a Remote object.
|
||||
* If input is not a Remote object, or if Remote object uses JRMP, return null.
|
||||
* If the RMI-IIOP library is not available, throw ConfigurationException.
|
||||
*
|
||||
* @param orig The object to turn into a CORBA object. If not Remote,
|
||||
* or if is a JRMP stub or impl, return null.
|
||||
* @param name Ignored
|
||||
* @param ctx The non-null CNCtx whose ORB to use.
|
||||
* @param env Ignored
|
||||
* @return The CORBA object for {@code orig} or null.
|
||||
* @exception ConfigurationException If the CORBA object cannot be obtained
|
||||
* due to configuration problems, for instance, if RMI-IIOP not available.
|
||||
* @exception NamingException If some other problem prevented a CORBA
|
||||
* object from being obtained from the Remote object.
|
||||
*/
|
||||
public Object getStateToBind(Object orig, Name name, Context ctx,
|
||||
Hashtable<?,?> env) throws NamingException {
|
||||
if (orig instanceof org.omg.CORBA.Object) {
|
||||
// Already a CORBA object, just use it
|
||||
return null;
|
||||
}
|
||||
|
||||
if (orig instanceof Remote) {
|
||||
// Turn remote object into org.omg.CORBA.Object
|
||||
// Returns null if JRMP; let next factory try
|
||||
// CNCtx will eventually throw IllegalArgumentException if
|
||||
// no CORBA object gotten
|
||||
return CorbaUtils.remoteToCorba((Remote)orig, ((CNCtx)ctx)._orb);
|
||||
}
|
||||
return null; // pass and let next state factory try
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
# Provider resource file for the COS Naming service provider.
|
||||
|
||||
# State factory to turn java.rmi.Remote into org.omg.CORBA.Object.
|
||||
java.naming.factory.state=com.sun.jndi.cosnaming.RemoteToCorba
|
@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.toolkit.corba;
|
||||
|
||||
// Needed for RMI/IIOP
|
||||
import java.rmi.Remote;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Properties;
|
||||
import java.util.Enumeration;
|
||||
import java.applet.Applet;
|
||||
|
||||
import org.omg.CORBA.ORB;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.rmi.CORBA.Stub;
|
||||
import javax.rmi.PortableRemoteObject;
|
||||
|
||||
/**
|
||||
* Contains utilities for performing CORBA-related tasks:
|
||||
* 1. Get the org.omg.CORBA.Object for a java.rmi.Remote object.
|
||||
* 2. Create an ORB to use for a given host/port, and environment properties.
|
||||
*
|
||||
* @author Simon Nash
|
||||
* @author Bryan Atsatt
|
||||
*/
|
||||
|
||||
public class CorbaUtils {
|
||||
/**
|
||||
* Returns the CORBA object reference associated with a Remote
|
||||
* object by using the javax.rmi.CORBA package.
|
||||
*<p>
|
||||
* This method effective does the following:
|
||||
* <blockquote><pre>
|
||||
* java.lang.Object stub;
|
||||
* try {
|
||||
* stub = PortableRemoteObject.toStub(remoteObj);
|
||||
* } catch (Exception e) {
|
||||
* throw new ConfigurationException("Object not exported or not found");
|
||||
* }
|
||||
* if (!(stub instanceof javax.rmi.CORBA.Stub)) {
|
||||
* return null; // JRMP impl or JRMP stub
|
||||
* }
|
||||
* try {
|
||||
* ((javax.rmi.CORBA.Stub)stub).connect(orb); // try to connect IIOP stub
|
||||
* } catch (RemoteException e) {
|
||||
* // ignore 'already connected' error
|
||||
* }
|
||||
* return (javax.rmi.CORBA.Stub)stub;
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* @param remoteObj The non-null remote object for
|
||||
* @param orb The non-null ORB to connect the remote object to
|
||||
* @return The CORBA Object for remoteObj; null if {@code remoteObj}
|
||||
* is a JRMP implementation or JRMP stub.
|
||||
* @exception ConfigurationException The CORBA Object cannot be obtained
|
||||
* because of configuration problems.
|
||||
*/
|
||||
public static org.omg.CORBA.Object remoteToCorba(Remote remoteObj, ORB orb)
|
||||
throws ConfigurationException {
|
||||
|
||||
// First, get remoteObj's stub
|
||||
|
||||
// javax.rmi.CORBA.Stub stub = PortableRemoteObject.toStub(remoteObj);
|
||||
|
||||
Remote stub;
|
||||
|
||||
try {
|
||||
stub = PortableRemoteObject.toStub(remoteObj);
|
||||
} catch (Throwable t) {
|
||||
ConfigurationException ce = new ConfigurationException(
|
||||
"Problem with PortableRemoteObject.toStub(); object not exported or stub not found");
|
||||
ce.setRootCause(t);
|
||||
throw ce;
|
||||
}
|
||||
|
||||
// Next, make sure that the stub is javax.rmi.CORBA.Stub
|
||||
|
||||
if (!(stub instanceof Stub)) {
|
||||
return null; // JRMP implementation or JRMP stub
|
||||
}
|
||||
|
||||
// Next, make sure that the stub is connected
|
||||
try {
|
||||
((Stub) stub).connect(orb);
|
||||
} catch (RemoteException e) {
|
||||
// ignore RemoteException because stub might have already
|
||||
// been connected
|
||||
} catch (Throwable t) {
|
||||
ConfigurationException ce = new ConfigurationException(
|
||||
"Problem invoking javax.rmi.CORBA.Stub.connect()");
|
||||
ce.setRootCause(t);
|
||||
throw ce;
|
||||
}
|
||||
// Finally, return stub
|
||||
return (org.omg.CORBA.Object)stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ORB using given server and port number, and properties from environment.
|
||||
*
|
||||
* @param server Possibly null server; if null means use default;
|
||||
* For applet, it is the applet host; for app, it is localhost.
|
||||
* @param port Port number, -1 means default port
|
||||
* @param env Possibly null environment. Contains environment properties.
|
||||
* Could contain ORB itself; or applet used for initializing ORB.
|
||||
* Use all String properties from env for initializing ORB
|
||||
* @return A non-null ORB.
|
||||
*/
|
||||
public static ORB getOrb(String server, int port, Hashtable<?,?> env) {
|
||||
// See if we can get info from environment
|
||||
Properties orbProp;
|
||||
|
||||
// Extract any org.omg.CORBA properties from environment
|
||||
if (env != null) {
|
||||
if (env instanceof Properties) {
|
||||
// Already a Properties, just clone
|
||||
orbProp = (Properties) env.clone();
|
||||
} else {
|
||||
// Get all String properties
|
||||
Enumeration<?> envProp;
|
||||
orbProp = new Properties();
|
||||
for (envProp = env.keys(); envProp.hasMoreElements();) {
|
||||
String key = (String)envProp.nextElement();
|
||||
Object val = env.get(key);
|
||||
if (val instanceof String) {
|
||||
orbProp.put(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
orbProp = new Properties();
|
||||
}
|
||||
|
||||
if (server != null) {
|
||||
orbProp.put("org.omg.CORBA.ORBInitialHost", server);
|
||||
}
|
||||
if (port >= 0) {
|
||||
orbProp.put("org.omg.CORBA.ORBInitialPort", ""+port);
|
||||
}
|
||||
|
||||
// Get Applet from environment
|
||||
if (env != null) {
|
||||
@SuppressWarnings("deprecation")
|
||||
Applet applet = (Applet) env.get(Context.APPLET);
|
||||
if (applet != null) {
|
||||
// Create ORBs using applet and orbProp
|
||||
return ORB.init(applet, orbProp);
|
||||
}
|
||||
}
|
||||
|
||||
return ORB.init(new String[0], orbProp);
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.url.corbaname;
|
||||
|
||||
import com.sun.jndi.url.iiop.iiopURLContextFactory;
|
||||
|
||||
/**
|
||||
* A corbaname URL context factory.
|
||||
* It just uses the iiop URL context factory but is needed here
|
||||
* so that NamingManager.getURLContext() will find it.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
final public class corbanameURLContextFactory extends iiopURLContextFactory {
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.url.iiop;
|
||||
|
||||
import javax.naming.spi.ResolveResult;
|
||||
import javax.naming.*;
|
||||
import java.util.Hashtable;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import com.sun.jndi.cosnaming.IiopUrl;
|
||||
import com.sun.jndi.cosnaming.CorbanameUrl;
|
||||
|
||||
/**
|
||||
* An IIOP URL context.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
public class iiopURLContext
|
||||
extends com.sun.jndi.toolkit.url.GenericURLContext {
|
||||
|
||||
iiopURLContext(Hashtable<?,?> env) {
|
||||
super(env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves 'name' into a target context with remaining name.
|
||||
* It only resolves the hostname/port number. The remaining name
|
||||
* contains the rest of the name found in the URL.
|
||||
*
|
||||
* For example, with a iiop URL "iiop://localhost:900/rest/of/name",
|
||||
* this method resolves "iiop://localhost:900/" to the "NameService"
|
||||
* context on for the ORB at 'localhost' on port 900,
|
||||
* and returns as the remaining name "rest/of/name".
|
||||
*/
|
||||
protected ResolveResult getRootURLContext(String name, Hashtable<?,?> env)
|
||||
throws NamingException {
|
||||
return iiopURLContextFactory.getUsingURLIgnoreRest(name, env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the suffix of an "iiop", "iiopname", or "corbaname" url.
|
||||
* prefix parameter is ignored.
|
||||
*/
|
||||
protected Name getURLSuffix(String prefix, String url)
|
||||
throws NamingException {
|
||||
try {
|
||||
if (url.startsWith("iiop://") || url.startsWith("iiopname://")) {
|
||||
IiopUrl parsedUrl = new IiopUrl(url);
|
||||
return parsedUrl.getCosName();
|
||||
} else if (url.startsWith("corbaname:")) {
|
||||
CorbanameUrl parsedUrl = new CorbanameUrl(url);
|
||||
return parsedUrl.getCosName();
|
||||
} else {
|
||||
throw new MalformedURLException("Not a valid URL: " + url);
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
throw new InvalidNameException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.jndi.url.iiop;
|
||||
|
||||
import javax.naming.*;
|
||||
import javax.naming.spi.*;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import com.sun.jndi.cosnaming.CNCtx;
|
||||
|
||||
/**
|
||||
* An IIOP URL context factory.
|
||||
*
|
||||
* @author Rosanna Lee
|
||||
*/
|
||||
|
||||
public class iiopURLContextFactory implements ObjectFactory {
|
||||
|
||||
public Object getObjectInstance(Object urlInfo, Name name, Context nameCtx,
|
||||
Hashtable<?,?> env) throws Exception {
|
||||
|
||||
//System.out.println("iiopURLContextFactory " + urlInfo);
|
||||
if (urlInfo == null) {
|
||||
return new iiopURLContext(env);
|
||||
}
|
||||
if (urlInfo instanceof String) {
|
||||
return getUsingURL((String)urlInfo, env);
|
||||
} else if (urlInfo instanceof String[]) {
|
||||
return getUsingURLs((String[])urlInfo, env);
|
||||
} else {
|
||||
throw (new IllegalArgumentException(
|
||||
"iiopURLContextFactory.getObjectInstance: " +
|
||||
"argument must be a URL String or array of URLs"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves 'name' into a target context with remaining name.
|
||||
* It only resolves the hostname/port number. The remaining name
|
||||
* contains the rest of the name found in the URL.
|
||||
*
|
||||
* For example, with a iiop URL "iiop://localhost:900/rest/of/name",
|
||||
* this method resolves "iiop://localhost:900/" to the "NameService"
|
||||
* context on for the ORB at 'localhost' on port 900,
|
||||
* and returns as the remaining name "rest/of/name".
|
||||
*/
|
||||
static ResolveResult getUsingURLIgnoreRest(String url, Hashtable<?,?> env)
|
||||
throws NamingException {
|
||||
return CNCtx.createUsingURL(url, env);
|
||||
}
|
||||
|
||||
private static Object getUsingURL(String url, Hashtable<?,?> env)
|
||||
throws NamingException {
|
||||
ResolveResult res = getUsingURLIgnoreRest(url, env);
|
||||
|
||||
Context ctx = (Context)res.getResolvedObj();
|
||||
try {
|
||||
return ctx.lookup(res.getRemainingName());
|
||||
} finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static Object getUsingURLs(String[] urls, Hashtable<?,?> env) {
|
||||
for (int i = 0; i < urls.length; i++) {
|
||||
String url = urls[i];
|
||||
try {
|
||||
Object obj = getUsingURL(url, env);
|
||||
if (obj != null) {
|
||||
return obj;
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
}
|
||||
}
|
||||
return null; // %%% exception??
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 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
|
||||
@ -51,7 +51,9 @@ import javax.management.remote.TargetedNotification;
|
||||
|
||||
import com.sun.jmx.remote.util.ClassLogger;
|
||||
import com.sun.jmx.remote.util.EnvHelp;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.rmi.UnmarshalException;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
|
||||
|
||||
public abstract class ClientNotifForwarder {
|
||||
@ -559,10 +561,38 @@ public abstract class ClientNotifForwarder {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
executor.execute(this);
|
||||
try {
|
||||
executor.execute(this);
|
||||
} catch (Exception e) {
|
||||
if (isRejectedExecutionException(e)) {
|
||||
// We reached here because the executor was shutdown.
|
||||
// If executor was supplied by client, then it was shutdown
|
||||
// abruptly or JMXConnector was shutdown along with executor
|
||||
// while this thread was suspended at L564.
|
||||
if (!(executor instanceof LinearExecutor)) {
|
||||
// Spawn new executor that will do cleanup if JMXConnector is closed
|
||||
// or keep notif system running otherwise
|
||||
executor = new LinearExecutor();
|
||||
executor.execute(this);
|
||||
}
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRejectedExecutionException(Exception e) {
|
||||
Throwable cause = e;
|
||||
while (cause != null) {
|
||||
if (cause instanceof RejectedExecutionException) {
|
||||
return true;
|
||||
}
|
||||
cause = cause.getCause();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void dispatchNotification(TargetedNotification tn,
|
||||
Integer myListenerID,
|
||||
Map<Integer, ClientListenerInfo> listeners) {
|
||||
@ -866,7 +896,7 @@ public abstract class ClientNotifForwarder {
|
||||
// -------------------------------------------------
|
||||
|
||||
private final ClassLoader defaultClassLoader;
|
||||
private final Executor executor;
|
||||
private Executor executor;
|
||||
|
||||
private final Map<Integer, ClientListenerInfo> infoList =
|
||||
new HashMap<Integer, ClientListenerInfo>();
|
||||
|
@ -27,7 +27,6 @@ package com.sun.jndi.ldap.pool;
|
||||
|
||||
import java.util.ArrayList; // JDK 1.2
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.SoftReference;
|
||||
@ -290,23 +289,28 @@ final class Connections implements PoolCallback {
|
||||
* @param threshold an entry idle since this time has expired.
|
||||
* @return true if no more connections in list
|
||||
*/
|
||||
synchronized boolean expire(long threshold) {
|
||||
Iterator<ConnectionDesc> iter = conns.iterator();
|
||||
ConnectionDesc entry;
|
||||
while (iter.hasNext()) {
|
||||
entry = iter.next();
|
||||
boolean expire(long threshold) {
|
||||
List<ConnectionDesc> clonedConns;
|
||||
synchronized(this) {
|
||||
clonedConns = new ArrayList<>(conns);
|
||||
}
|
||||
List<ConnectionDesc> expired = new ArrayList<>();
|
||||
|
||||
for (ConnectionDesc entry : clonedConns) {
|
||||
d("expire(): ", entry);
|
||||
if (entry.expire(threshold)) {
|
||||
d("expire(): removing ", entry);
|
||||
td("Expired ", entry);
|
||||
|
||||
iter.remove(); // remove from pool
|
||||
|
||||
// Don't need to call notify() because we're
|
||||
// removing only idle connections. If there were
|
||||
// idle connections, then there should be no waiters.
|
||||
expired.add(entry);
|
||||
td("expire(): Expired ", entry);
|
||||
}
|
||||
}
|
||||
return conns.isEmpty(); // whether whole list has 'expired'
|
||||
|
||||
synchronized (this) {
|
||||
conns.removeAll(expired);
|
||||
// Don't need to call notify() because we're
|
||||
// removing only idle connections. If there were
|
||||
// idle connections, then there should be no waiters.
|
||||
return conns.isEmpty(); // whether whole list has 'expired'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,11 +25,11 @@
|
||||
|
||||
package com.sun.jndi.ldap.pool;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import java.io.PrintStream;
|
||||
@ -166,17 +166,25 @@ final public class Pool {
|
||||
* and removed.
|
||||
*/
|
||||
public void expire(long threshold) {
|
||||
Collection<ConnectionsRef> copy;
|
||||
synchronized (map) {
|
||||
Iterator<ConnectionsRef> iter = map.values().iterator();
|
||||
Connections conns;
|
||||
while (iter.hasNext()) {
|
||||
conns = iter.next().getConnections();
|
||||
if (conns.expire(threshold)) {
|
||||
d("expire(): removing ", conns);
|
||||
iter.remove();
|
||||
}
|
||||
copy = new ArrayList<>(map.values());
|
||||
}
|
||||
|
||||
ArrayList<ConnectionsRef> removed = new ArrayList<>();
|
||||
Connections conns;
|
||||
for (ConnectionsRef ref : copy) {
|
||||
conns = ref.getConnections();
|
||||
if (conns.expire(threshold)) {
|
||||
d("expire(): removing ", conns);
|
||||
removed.add(ref);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (map) {
|
||||
map.values().removeAll(removed);
|
||||
}
|
||||
|
||||
expungeStaleConnections();
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,6 @@ module java.naming {
|
||||
exports com.sun.jndi.toolkit.ctx to
|
||||
jdk.naming.dns;
|
||||
exports com.sun.jndi.toolkit.url to
|
||||
java.corba,
|
||||
jdk.naming.dns,
|
||||
jdk.naming.rmi;
|
||||
uses javax.naming.ldap.StartTlsResponse;
|
||||
|
@ -26,12 +26,25 @@
|
||||
/**
|
||||
* Defines the core Java SE API.
|
||||
* <P>
|
||||
* The modules defining
|
||||
* CORBA and Java EE APIs are not required by this module, but they are
|
||||
* required by {@code java.se.ee}.
|
||||
* The modules defining CORBA and Java EE APIs are not required by
|
||||
* this module, but they are required by {@code java.se.ee}.
|
||||
*/
|
||||
module java.se {
|
||||
requires transitive java.compact3;
|
||||
requires transitive java.compiler;
|
||||
requires transitive java.datatransfer;
|
||||
requires transitive java.desktop;
|
||||
requires transitive java.instrument;
|
||||
requires transitive java.logging;
|
||||
requires transitive java.management;
|
||||
requires transitive java.naming;
|
||||
requires transitive java.prefs;
|
||||
requires transitive java.rmi;
|
||||
requires transitive java.scripting;
|
||||
requires transitive java.security.jgss;
|
||||
requires transitive java.security.sasl;
|
||||
requires transitive java.sql;
|
||||
requires transitive java.sql.rowset;
|
||||
requires transitive java.xml;
|
||||
requires transitive java.xml.crypto;
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,12 @@ module java.security.jgss {
|
||||
jdk.security.jgss;
|
||||
exports sun.security.krb5.internal.ktab to
|
||||
jdk.security.auth;
|
||||
|
||||
// Opens for reflective instantiation of sun.net.www.protocol.http.spnego.NegotiatorImpl
|
||||
// to sun.net.www.protocol.http.HttpURLConnection
|
||||
opens sun.net.www.protocol.http.spnego to
|
||||
java.base;
|
||||
|
||||
provides java.security.Provider with sun.security.jgss.SunProvider;
|
||||
provides sun.security.ssl.ClientKeyExchangeService
|
||||
with sun.security.krb5.internal.ssl.Krb5KeyExchangeService;
|
||||
|
@ -41,46 +41,41 @@ import jdk.internal.reflect.Reflection;
|
||||
|
||||
|
||||
/**
|
||||
* <P>The basic service for managing a set of JDBC drivers.<br>
|
||||
* <B>NOTE:</B> The {@link javax.sql.DataSource} interface, new in the
|
||||
* JDBC 2.0 API, provides another way to connect to a data source.
|
||||
* The use of a <code>DataSource</code> object is the preferred means of
|
||||
* The basic service for managing a set of JDBC drivers.
|
||||
* <p>
|
||||
* <strong>NOTE:</strong> The {@link javax.sql.DataSource} interface, provides
|
||||
* another way to connect to a data source.
|
||||
* The use of a {@code DataSource} object is the preferred means of
|
||||
* connecting to a data source.
|
||||
*
|
||||
* <P>As part of its initialization, the <code>DriverManager</code> class will
|
||||
* attempt to load the driver classes referenced in the "jdbc.drivers"
|
||||
* system property. This allows a user to customize the JDBC Drivers
|
||||
* used by their applications. For example in your
|
||||
* ~/.hotjava/properties file you might specify:
|
||||
* <pre>
|
||||
* <CODE>jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.taste.ourDriver</CODE>
|
||||
* </pre>
|
||||
*<P> The <code>DriverManager</code> methods <code>getConnection</code> and
|
||||
* <code>getDrivers</code> have been enhanced to support the Java Standard Edition
|
||||
* <a href="../../../technotes/guides/jar/jar.html#Service%20Provider">Service Provider</a> mechanism. JDBC 4.0 Drivers must
|
||||
* include the file <code>META-INF/services/java.sql.Driver</code>. This file contains the name of the JDBC drivers
|
||||
* implementation of <code>java.sql.Driver</code>. For example, to load the <code>my.sql.Driver</code> class,
|
||||
* the <code>META-INF/services/java.sql.Driver</code> file would contain the entry:
|
||||
* <pre>
|
||||
* <code>my.sql.Driver</code>
|
||||
* </pre>
|
||||
*
|
||||
* <P>Applications no longer need to explicitly load JDBC drivers using <code>Class.forName()</code>. Existing programs
|
||||
* which currently load JDBC drivers using <code>Class.forName()</code> will continue to work without
|
||||
* modification.
|
||||
*
|
||||
* <P>When the method <code>getConnection</code> is called,
|
||||
* the <code>DriverManager</code> will attempt to
|
||||
* locate a suitable driver from amongst those loaded at
|
||||
* initialization and those loaded explicitly using the same classloader
|
||||
* as the current applet or application.
|
||||
*
|
||||
* <P>
|
||||
* Starting with the Java 2 SDK, Standard Edition, version 1.3, a
|
||||
* logging stream can be set only if the proper
|
||||
* permission has been granted. Normally this will be done with
|
||||
* the tool PolicyTool, which can be used to grant <code>permission
|
||||
* java.sql.SQLPermission "setLog"</code>.
|
||||
* As part of its initialization, the {@code DriverManager} class will
|
||||
* attempt to load available JDBC drivers by using:
|
||||
* <ul>
|
||||
* <li>The {@code jdbc.drivers} system property which contains a
|
||||
* colon separated list of fully qualified class names of JDBC drivers. Each
|
||||
* driver is loaded using the {@linkplain ClassLoader#getSystemClassLoader
|
||||
* system class loader}:
|
||||
* <ul>
|
||||
* <li>{@code jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.taste.ourDriver}
|
||||
* </ul>
|
||||
*
|
||||
* <li>Service providers of the {@code java.sql.Driver} class, that are loaded
|
||||
* via the {@linkplain ServiceLoader#load service-provider loading} mechanism.
|
||||
*</ul>
|
||||
*
|
||||
*<P>
|
||||
* @ImplNote
|
||||
* {@code DriverManager} initialization is done lazily and looks up service
|
||||
* providers using the thread context class loader. The drivers loaded and
|
||||
* available to an application will depend on the thread context class loader of
|
||||
* the thread that triggers driver initialization by {@code DriverManager}.
|
||||
*
|
||||
* <P>When the method {@code getConnection} is called,
|
||||
* the {@code DriverManager} will attempt to
|
||||
* locate a suitable driver from amongst those loaded at
|
||||
* initialization and those loaded explicitly using the same class loader
|
||||
* as the current application.
|
||||
*
|
||||
* @see Driver
|
||||
* @see Connection
|
||||
*/
|
||||
@ -137,29 +132,15 @@ public class DriverManager {
|
||||
/**
|
||||
* Sets the logging/tracing <code>PrintWriter</code> object
|
||||
* that is used by the <code>DriverManager</code> and all drivers.
|
||||
* <P>
|
||||
* There is a minor versioning problem created by the introduction
|
||||
* of the method <code>setLogWriter</code>. The
|
||||
* method <code>setLogWriter</code> cannot create a <code>PrintStream</code> object
|
||||
* that will be returned by <code>getLogStream</code>---the Java platform does
|
||||
* not provide a backward conversion. As a result, a new application
|
||||
* that uses <code>setLogWriter</code> and also uses a JDBC 1.0 driver that uses
|
||||
* <code>getLogStream</code> will likely not see debugging information written
|
||||
* by that driver.
|
||||
*<P>
|
||||
* Starting with the Java 2 SDK, Standard Edition, version 1.3 release, this method checks
|
||||
* to see that there is an <code>SQLPermission</code> object before setting
|
||||
* the logging stream. If a <code>SecurityManager</code> exists and its
|
||||
* <code>checkPermission</code> method denies setting the log writer, this
|
||||
* method throws a <code>java.lang.SecurityException</code>.
|
||||
* If a security manager exists, its {@code checkPermission}
|
||||
* method is first called with a {@code SQLPermission("setLog")}
|
||||
* permission to check that the caller is allowed to call {@code setLogWriter}.
|
||||
*
|
||||
* @param out the new logging/tracing <code>PrintStream</code> object;
|
||||
* <code>null</code> to disable logging and tracing
|
||||
* @throws SecurityException
|
||||
* if a security manager exists and its
|
||||
* <code>checkPermission</code> method denies
|
||||
* setting the log writer
|
||||
*
|
||||
* @throws SecurityException if a security manager exists and its
|
||||
* {@code checkPermission} method denies permission to set the log writer.
|
||||
* @see SecurityManager#checkPermission
|
||||
* @see #getLogWriter
|
||||
* @since 1.2
|
||||
@ -374,8 +355,9 @@ public class DriverManager {
|
||||
* If a {@code null} value is specified for the driver to be removed, then no
|
||||
* action is taken.
|
||||
* <p>
|
||||
* If a security manager exists and its {@code checkPermission} denies
|
||||
* permission, then a {@code SecurityException} will be thrown.
|
||||
* If a security manager exists, its {@code checkPermission}
|
||||
* method is first called with a {@code SQLPermission("deregisterDriver")}
|
||||
* permission to check that the caller is allowed to deregister a JDBC Driver.
|
||||
* <p>
|
||||
* If the specified driver is not found in the list of registered drivers,
|
||||
* then no action is taken. If the driver was found, it will be removed
|
||||
@ -501,17 +483,14 @@ public class DriverManager {
|
||||
* by the <code>DriverManager</code>
|
||||
* and all drivers.
|
||||
*<P>
|
||||
* In the Java 2 SDK, Standard Edition, version 1.3 release, this method checks
|
||||
* to see that there is an <code>SQLPermission</code> object before setting
|
||||
* the logging stream. If a <code>SecurityManager</code> exists and its
|
||||
* <code>checkPermission</code> method denies setting the log writer, this
|
||||
* method throws a <code>java.lang.SecurityException</code>.
|
||||
* If a security manager exists, its {@code checkPermission}
|
||||
* method is first called with a {@code SQLPermission("setLog")}
|
||||
* permission to check that the caller is allowed to call {@code setLogStream}.
|
||||
*
|
||||
* @param out the new logging/tracing PrintStream; to disable, set to <code>null</code>
|
||||
* @deprecated Use {@code setLogWriter}
|
||||
* @throws SecurityException if a security manager exists and its
|
||||
* <code>checkPermission</code> method denies setting the log stream
|
||||
*
|
||||
* {@code checkPermission} method denies permission to set the log stream.
|
||||
* @see SecurityManager#checkPermission
|
||||
* @see #getLogStream
|
||||
*/
|
||||
|
@ -23,7 +23,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module jdk.crypto.pkcs11 {
|
||||
module jdk.crypto.token {
|
||||
// Depends on SunEC provider for EC related functionality
|
||||
requires jdk.crypto.ec;
|
||||
provides java.security.Provider with sun.security.pkcs11.SunPKCS11;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user