This commit is contained in:
Phil Race 2016-12-19 09:16:40 -08:00
commit 58b8478bb6
385 changed files with 6561 additions and 6311 deletions

View File

@ -391,3 +391,4 @@ efa71dc820eb8bd5a6c9f2f66f39c383ac3ee99d jdk-9+144
6e4ff59afb5d0adf21a72c4ff534326594a99e5d jdk-9+146
c41140100bf1e5c10c7b8f3bde91c16eff7485f5 jdk-9+147
9098b2b9d997d65af0026fc2f39cf75234e26bc5 jdk-9+148
5a846396a24c7aff01d6a8feaa7afc0a6369f04d jdk-9+149

View File

@ -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?

View File

@ -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

View File

@ -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)

View File

@ -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 :=

View 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 \
, \
))

View File

@ -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), \
))

View File

@ -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), \

View File

@ -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 += \

View File

@ -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), \

View File

@ -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, \

View File

@ -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;

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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.

View File

@ -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;;) {

View File

@ -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 =

View File

@ -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

View File

@ -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;
}
}
}
}

View File

@ -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;
}

View File

@ -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}

View File

@ -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(); }

View File

@ -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);
}
});
}

View File

@ -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)) {

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}
}
/**

View File

@ -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>

View File

@ -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&trade;
* 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);
}
});
}
}

View File

@ -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());
}
}

View File

@ -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() {

View File

@ -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

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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() {

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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
*/

View File

@ -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;
}
}
}
}

View File

@ -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();
}
}
/**

View File

@ -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());

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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);
}
/**

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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 + "]";
}
}

View File

@ -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

View File

@ -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");
}
}

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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.
*/

View File

@ -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.
*/

View File

@ -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

View File

@ -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")) {

View File

@ -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";

View File

@ -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";

View File

@ -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)
{

View File

@ -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

View File

@ -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";

View File

@ -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;

View File

@ -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"

View File

@ -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);

View File

@ -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; \

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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));
}
*/
}

View File

@ -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();
}
}
*/
}

View File

@ -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;
}
}
}

View File

@ -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();
}
} */
}

View File

@ -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();
}
}
}

View File

@ -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
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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 {
}

View File

@ -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());
}
}
}

View File

@ -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??
}
}

View File

@ -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>();

View File

@ -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'
}
}
/**

View File

@ -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();
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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
*/

View File

@ -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