This commit is contained in:
Lana Steuck 2016-08-11 17:02:46 +00:00
commit 43568d8cc0
258 changed files with 4132 additions and 1695 deletions
jdk
make
src
test

@ -42,6 +42,6 @@ $(GENGRAPHS_DIR)/technology-summary.html: $(TOOLS_MODULE_SRCDIR)/technology-summ
$(GENGRAPHS_DIR)/module-summary.html: $(BUILD_JIGSAW_TOOLS) $(GENGRAPHS_DIR)/technology-summary.html
$(MKDIR) -p $(@D)
$(TOOL_MODULESUMMARY) -o $@ -mp $(IMAGES_OUTPUTDIR)/jmods
$(TOOL_MODULESUMMARY) -o $@ --module-path $(IMAGES_OUTPUTDIR)/jmods
all: $(GENGRAPHS_DIR)/jdk.dot $(GENGRAPHS_DIR)/module-summary.html

@ -36,12 +36,12 @@ $(eval $(call SetupJavaCompilation,BUILD_JIGSAW_TOOLS, \
INCLUDES := build/tools/deps \
build/tools/jigsaw, \
BIN := $(TOOLS_CLASSES_DIR), \
ADD_JAVAC_FLAGS := -XaddExports:jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED ))
ADD_JAVAC_FLAGS := --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED ))
TOOL_GENGRAPHS := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
build.tools.jigsaw.GenGraphs
TOOL_MODULESUMMARY := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
-XaddExports:jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
--add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
build.tools.jigsaw.ModuleSummary

@ -38,7 +38,7 @@ BUILD_TOOLS_JDK := $(call SetupJavaCompilationCompileTarget, \
################################################################################
ifeq ($(BOOT_JDK_MODULAR), true)
COMPILEFONTCONFIG_ADD_EXPORTS := -XaddExports:java.desktop/sun.awt=ALL-UNNAMED
COMPILEFONTCONFIG_ADD_EXPORTS := --add-exports java.desktop/sun.awt=ALL-UNNAMED
endif
TOOL_COMPILEFONTCONFIG = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
@ -94,7 +94,7 @@ TOOL_SPP = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes build.too
# Nimbus is used somewhere in the swing build.
ifeq ($(BOOT_JDK_MODULAR), true)
COMPILENIMBUS_ADD_MODS := -addmods java.xml.bind
COMPILENIMBUS_ADD_MODS := --add-modules java.xml.bind
endif
TOOL_GENERATENIMBUS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \

@ -203,7 +203,7 @@ TARGETS += $(DEF_POLICY_DST)
################################################################################
ifeq ($(CACERTS_FILE), )
CACERTS_FILE := $(JDK_TOPDIR)/src/java.base/share/conf/security/cacerts
CACERTS_FILE := $(JDK_TOPDIR)/src/java.base/share/lib/security/cacerts
endif
CACERTS_DST := $(LIB_DST_DIR)/security/cacerts

@ -63,11 +63,11 @@ $(eval $(call SetupJavaCompilation,BUILD_BREAKITERATOR_LD, \
ifeq ($(BOOT_JDK_MODULAR), true)
BREAK_ITERATOR_BOOTCLASSPATH := \
-Xpatch:java.base=$(BREAK_ITERATOR_CLASSES)/java.base \
-Xpatch:jdk.localedata=$(BREAK_ITERATOR_CLASSES)/jdk.localedata \
-XaddExports:java.base/sun.text=ALL-UNNAMED \
-XaddExports:java.base/sun.text.resources=ALL-UNNAMED \
-XaddExports:jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \
--patch-module java.base=$(BREAK_ITERATOR_CLASSES)/java.base \
--patch-module jdk.localedata=$(BREAK_ITERATOR_CLASSES)/jdk.localedata \
--add-exports java.base/sun.text=ALL-UNNAMED \
--add-exports java.base/sun.text.resources=ALL-UNNAMED \
--add-exports jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \
#
else
BREAK_ITERATOR_BOOTCLASSPATH := -Xbootclasspath/p:$(call PathList, \

@ -31,7 +31,7 @@ $(eval $(call IncludeCustomExtension, jdk, launcher/Launcher-java.desktop.gmk))
ifndef BUILD_HEADLESS_ONLY
$(eval $(call SetupBuildLauncher, appletviewer, \
MAIN_CLASS := sun.applet.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \
JAVA_ARGS := --add-modules ALL-DEFAULT, \
LIBS_unix := $(X_LIBS), \
))
endif

@ -27,5 +27,5 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jrunscript, \
MAIN_CLASS := com.sun.tools.script.shell.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \
JAVA_ARGS := --add-modules ALL-DEFAULT, \
))

@ -27,7 +27,7 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, javac, \
MAIN_CLASS := com.sun.tools.javac.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \
JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
))

@ -27,7 +27,7 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, javadoc, \
MAIN_CLASS := jdk.javadoc.internal.tool.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \
JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
))

@ -32,7 +32,7 @@ $(eval $(call SetupBuildLauncher, jimage,\
$(eval $(call SetupBuildLauncher, jlink,\
MAIN_CLASS := jdk.tools.jlink.internal.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \
JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DENABLE_ARG_FILES \
-DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \

@ -27,6 +27,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jjs, \
MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \
JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DENABLE_ARG_FILES, \
))

@ -51,7 +51,7 @@ import static build.tools.jigsaw.ModuleSummary.HtmlDocument.Selector.*;
import static build.tools.jigsaw.ModuleSummary.HtmlDocument.Division.*;
public class ModuleSummary {
private static final String USAGE = "Usage: ModuleSummary -mp <dir> -o <outfile> [-root mn]*";
private static final String USAGE = "Usage: ModuleSummary --module-path <dir> -o <outfile> [--root mn]*";
public static void main(String[] args) throws Exception {
int i=0;
@ -61,13 +61,13 @@ public class ModuleSummary {
while (i < args.length && args[i].startsWith("-")) {
String arg = args[i++];
switch (arg) {
case "-mp":
case "--module-path":
modpath = Paths.get(args[i++]);
break;
case "-o":
outfile = Paths.get(args[i++]);
break;
case "-root":
case "--root":
roots.add(args[i++]);
default:
System.err.println(USAGE);

@ -131,8 +131,10 @@ public class CharArrayReader extends Reader {
if (pos >= count) {
return -1;
}
if (pos + len > count) {
len = count - pos;
int avail = count - pos;
if (len > avail) {
len = avail;
}
if (len <= 0) {
return 0;
@ -158,8 +160,10 @@ public class CharArrayReader extends Reader {
public long skip(long n) throws IOException {
synchronized (lock) {
ensureOpen();
if (pos + n > count) {
n = count - pos;
long avail = count - pos;
if (n > avail) {
n = avail;
}
if (n < 0) {
return 0;

@ -118,8 +118,10 @@ class StringBufferInputStream extends InputStream {
if (pos >= count) {
return -1;
}
if (pos + len > count) {
len = count - pos;
int avail = count - pos;
if (len > avail) {
len = avail;
}
if (len <= 0) {
return 0;

@ -644,23 +644,20 @@ public final class System {
* <code>getProperties</code> operation, it may choose to permit the
* {@link #getProperty(String)} operation.
*
* @implNote In addition to the standard system properties, the {@code
* java} launcher may create the Java Virtual Machine with system
* properties that have the following keys:
* @implNote In addition to the standard system properties, the system
* properties may include the following keys:
* <table summary="Shows property keys and associated values">
* <tr><th>Key</th>
* <th>Description of Associated Value</th></tr>
* <tr><td>{@code jdk.module.path}</td>
* <td>Application module path</td></tr>
* <tr><td>{@code jdk.upgrade.module.path}</td>
* <td>The application module path</td></tr>
* <tr><td>{@code jdk.module.upgrade.path}</td>
* <td>The upgrade module path</td></tr>
* <tr><td>{@code jdk.module.main}</td>
* <td>The module name of the initial/main module</td></tr>
* <tr><td>{@code jdk.module.main.class}</td>
* <td>The main class name of the initial module</td></tr>
* </table>
* These properties may also be set by custom launchers that use the JNI
* invocation API to create the Java Virtual Machine.
*
* @return the system properties
* @exception SecurityException if a security manager exists and its

@ -587,26 +587,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
return bmhClass;
}
/**
* @implNote this method is used by GenerateBMHClassesPlugin to enable
* ahead-of-time generation of BMH classes at link time. It does
* added validation since this string may be user provided.
*/
static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
final String types) {
for (char c : types.toCharArray()) {
if ("LIJFD".indexOf(c) < 0) {
throw new IllegalArgumentException("All characters must "
+ "correspond to a basic field type: LIJFD");
}
}
String shortTypes = LambdaForm.shortenSignature(types);
final String className = speciesInternalClassName(shortTypes);
return Map.entry(className,
generateConcreteBMHClassBytes(shortTypes, types, className));
}
private static String speciesInternalClassName(String shortTypes) {
static String speciesInternalClassName(String shortTypes) {
return SPECIES_PREFIX_PATH + shortTypes;
}

@ -186,7 +186,7 @@ class DirectMethodHandle extends MethodHandle {
return mtype.form().setCachedLambdaForm(which, lform);
}
private static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
boolean needsInit = (which == LF_INVSTATIC_INIT);
boolean doesAlloc = (which == LF_NEWINVSPECIAL);
String linkerName, lambdaName;
@ -248,20 +248,6 @@ class DirectMethodHandle extends MethodHandle {
return lform;
}
/*
* NOTE: This method acts as an API hook for use by the
* GenerateJLIClassesPlugin to generate a class wrapping DirectMethodHandle
* methods for an array of method types.
*/
static byte[] generateDMHClassBytes(String className, MethodType[] methodTypes, int[] types) {
LambdaForm[] forms = new LambdaForm[methodTypes.length];
for (int i = 0; i < forms.length; i++) {
forms[i] = makePreparedLambdaForm(methodTypes[i], types[i]);
methodTypes[i] = forms[i].methodType();
}
return InvokerBytecodeGenerator.generateCodeBytesForMultiple(className, forms, methodTypes);
}
static Object findDirectMethodHandle(Name name) {
if (name.function == NF_internalMemberName ||
name.function == NF_internalMemberNameEnsureInit ||
@ -515,7 +501,7 @@ class DirectMethodHandle extends MethodHandle {
// Enumerate the different field kinds using Wrapper,
// with an extra case added for checked references.
private static final int
FT_LAST_WRAPPER = Wrapper.values().length-1,
FT_LAST_WRAPPER = Wrapper.COUNT-1,
FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
FT_CHECKED_REF = FT_LAST_WRAPPER+1,
FT_LIMIT = FT_LAST_WRAPPER+2;

@ -0,0 +1,85 @@
/*
* 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 java.lang.invoke;
import java.util.Map;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* Helper class to assist the GenerateJLIClassesPlugin to get access to
* generate classes ahead of time.
*/
class GenerateJLIClassesHelper {
static byte[] generateDMHClassBytes(String className,
MethodType[] methodTypes, int[] types) {
LambdaForm[] forms = new LambdaForm[methodTypes.length];
for (int i = 0; i < forms.length; i++) {
forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i],
types[i]);
methodTypes[i] = forms[i].methodType();
}
return generateCodeBytesForLFs(className, forms, methodTypes);
}
/*
* Generate customized code for a set of LambdaForms of specified types into
* a class with a specified name.
*/
private static byte[] generateCodeBytesForLFs(String className,
LambdaForm[] forms, MethodType[] types) {
assert(forms.length == types.length);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
className, null, InvokerBytecodeGenerator.INVOKER_SUPER_NAME, null);
cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null);
for (int i = 0; i < forms.length; i++) {
InvokerBytecodeGenerator g
= new InvokerBytecodeGenerator(className, forms[i], types[i]);
g.setClassWriter(cw);
g.addMethod();
}
return cw.toByteArray();
}
static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
final String types) {
for (char c : types.toCharArray()) {
if ("LIJFD".indexOf(c) < 0) {
throw new IllegalArgumentException("All characters must "
+ "correspond to a basic field type: LIJFD");
}
}
String shortTypes = LambdaForm.shortenSignature(types);
final String className =
BoundMethodHandle.Factory.speciesInternalClassName(shortTypes);
return Map.entry(className,
BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
shortTypes, types, className));
}
}

@ -70,7 +70,7 @@ class InvokerBytecodeGenerator {
private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V";
/** Name of its super class*/
private static final String INVOKER_SUPER_NAME = OBJ;
static final String INVOKER_SUPER_NAME = OBJ;
/** Name of new class */
private final String className;
@ -124,7 +124,7 @@ class InvokerBytecodeGenerator {
}
/** For generating customized code for a single LambdaForm. */
private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
this(form, form.names.length,
className, form.debugName, invokerType);
// Create an array to map name indexes to locals indexes.
@ -655,35 +655,11 @@ class InvokerBytecodeGenerator {
return classFile;
}
/*
* NOTE: This is used from GenerateJLIClassesPlugin via
* DirectMethodHandle::generateDMHClassBytes.
*
* Generate customized code for a set of LambdaForms of specified types into
* a class with a specified name.
*/
static byte[] generateCodeBytesForMultiple(String className,
LambdaForm[] forms, MethodType[] types) {
assert(forms.length == types.length);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
className, null, INVOKER_SUPER_NAME, null);
cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null);
for (int i = 0; i < forms.length; i++) {
InvokerBytecodeGenerator g
= new InvokerBytecodeGenerator(className, forms[i], types[i]);
g.setClassWriter(cw);
g.addMethod();
}
return cw.toByteArray();
}
private void setClassWriter(ClassWriter cw) {
void setClassWriter(ClassWriter cw) {
this.cw = cw;
}
private void addMethod() {
void addMethod() {
methodPrologue();
// Suppress this method in backtraces displayed to the user.

@ -60,7 +60,7 @@ class LambdaFormEditor {
}
/** A description of a cached transform, possibly associated with the result of the transform.
* The logical content is a sequence of byte values, starting with a Kind.ordinal value.
* The logical content is a sequence of byte values, starting with a kind value.
* The sequence is unterminated, ending with an indefinite number of zero bytes.
* Sequences that are simple (short enough and with small enough values) pack into a 64-bit long.
*/
@ -68,17 +68,22 @@ class LambdaFormEditor {
final long packedBytes;
final byte[] fullBytes;
private enum Kind {
NO_KIND, // necessary because ordinal must be greater than zero
BIND_ARG, ADD_ARG, DUP_ARG,
SPREAD_ARGS,
FILTER_ARG, FILTER_RETURN, FILTER_RETURN_TO_ZERO,
COLLECT_ARGS, COLLECT_ARGS_TO_VOID, COLLECT_ARGS_TO_ARRAY,
FOLD_ARGS, FOLD_ARGS_TO_VOID,
PERMUTE_ARGS,
LOCAL_TYPES
//maybe add more for guard with test, catch exception, pointwise type conversions
}
// maybe add more for guard with test, catch exception, pointwise type conversions
private static final byte
BIND_ARG = 1,
ADD_ARG = 2,
DUP_ARG = 3,
SPREAD_ARGS = 4,
FILTER_ARG = 5,
FILTER_RETURN = 6,
FILTER_RETURN_TO_ZERO = 7,
COLLECT_ARGS = 8,
COLLECT_ARGS_TO_VOID = 9,
COLLECT_ARGS_TO_ARRAY = 10,
FOLD_ARGS = 11,
FOLD_ARGS_TO_VOID = 12,
PERMUTE_ARGS = 13,
LOCAL_TYPES = 14;
private static final boolean STRESS_TEST = false; // turn on to disable most packing
private static final int
@ -131,20 +136,6 @@ class LambdaFormEditor {
return bytes;
}
private byte byteAt(int i) {
long pb = packedBytes;
if (pb == 0) {
if (i >= fullBytes.length) return 0;
return fullBytes[i];
}
assert(fullBytes == null);
if (i > PACKED_BYTE_MAX_LENGTH) return 0;
int pos = (i * PACKED_BYTE_SIZE);
return (byte)((pb >>> pos) & PACKED_BYTE_MASK);
}
Kind kind() { return Kind.values()[byteAt(0)]; }
private Transform(long packedBytes, byte[] fullBytes, LambdaForm result) {
super(result);
this.packedBytes = packedBytes;
@ -162,44 +153,39 @@ class LambdaFormEditor {
assert((b & 0xFF) == b); // incoming value must fit in *unsigned* byte
return (byte)b;
}
private static byte bval(Kind k) {
return bval(k.ordinal());
}
static Transform of(Kind k, int b1) {
static Transform of(byte k, int b1) {
byte b0 = bval(k);
if (inRange(b0 | b1))
return new Transform(packedBytes(b0, b1));
else
return new Transform(fullBytes(b0, b1));
}
static Transform of(Kind k, int b1, int b2) {
byte b0 = (byte) k.ordinal();
static Transform of(byte b0, int b1, int b2) {
if (inRange(b0 | b1 | b2))
return new Transform(packedBytes(b0, b1, b2));
else
return new Transform(fullBytes(b0, b1, b2));
}
static Transform of(Kind k, int b1, int b2, int b3) {
byte b0 = (byte) k.ordinal();
static Transform of(byte b0, int b1, int b2, int b3) {
if (inRange(b0 | b1 | b2 | b3))
return new Transform(packedBytes(b0, b1, b2, b3));
else
return new Transform(fullBytes(b0, b1, b2, b3));
}
private static final byte[] NO_BYTES = {};
static Transform of(Kind k, int... b123) {
return ofBothArrays(k, b123, NO_BYTES);
static Transform of(byte kind, int... b123) {
return ofBothArrays(kind, b123, NO_BYTES);
}
static Transform of(Kind k, int b1, byte[] b234) {
return ofBothArrays(k, new int[]{ b1 }, b234);
static Transform of(byte kind, int b1, byte[] b234) {
return ofBothArrays(kind, new int[]{ b1 }, b234);
}
static Transform of(Kind k, int b1, int b2, byte[] b345) {
return ofBothArrays(k, new int[]{ b1, b2 }, b345);
static Transform of(byte kind, int b1, int b2, byte[] b345) {
return ofBothArrays(kind, new int[]{ b1, b2 }, b345);
}
private static Transform ofBothArrays(Kind k, int[] b123, byte[] b456) {
private static Transform ofBothArrays(byte kind, int[] b123, byte[] b456) {
byte[] fullBytes = new byte[1 + b123.length + b456.length];
int i = 0;
fullBytes[i++] = bval(k);
fullBytes[i++] = bval(kind);
for (int bv : b123) {
fullBytes[i++] = bval(bv);
}
@ -449,7 +435,7 @@ class LambdaFormEditor {
// Each editing method can (potentially) cache the edited LF so that it can be reused later.
LambdaForm bindArgumentForm(int pos) {
Transform key = Transform.of(Transform.Kind.BIND_ARG, pos);
Transform key = Transform.of(Transform.BIND_ARG, pos);
LambdaForm form = getInCache(key);
if (form != null) {
assert(form.parameterConstraint(0) == newSpeciesData(lambdaForm.parameterType(pos)));
@ -484,7 +470,7 @@ class LambdaFormEditor {
}
LambdaForm addArgumentForm(int pos, BasicType type) {
Transform key = Transform.of(Transform.Kind.ADD_ARG, pos, type.ordinal());
Transform key = Transform.of(Transform.ADD_ARG, pos, type.ordinal());
LambdaForm form = getInCache(key);
if (form != null) {
assert(form.arity == lambdaForm.arity+1);
@ -501,7 +487,7 @@ class LambdaFormEditor {
}
LambdaForm dupArgumentForm(int srcPos, int dstPos) {
Transform key = Transform.of(Transform.Kind.DUP_ARG, srcPos, dstPos);
Transform key = Transform.of(Transform.DUP_ARG, srcPos, dstPos);
LambdaForm form = getInCache(key);
if (form != null) {
assert(form.arity == lambdaForm.arity-1);
@ -530,7 +516,7 @@ class LambdaFormEditor {
elementTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
}
}
Transform key = Transform.of(Transform.Kind.SPREAD_ARGS, pos, elementTypeKey, arrayLength);
Transform key = Transform.of(Transform.SPREAD_ARGS, pos, elementTypeKey, arrayLength);
LambdaForm form = getInCache(key);
if (form != null) {
assert(form.arity == lambdaForm.arity - arrayLength + 1);
@ -569,9 +555,9 @@ class LambdaFormEditor {
return filterArgumentForm(pos, basicType(collectorType.parameterType(0)));
}
byte[] newTypes = BasicType.basicTypesOrd(collectorType.parameterArray());
Transform.Kind kind = (dropResult
? Transform.Kind.COLLECT_ARGS_TO_VOID
: Transform.Kind.COLLECT_ARGS);
byte kind = (dropResult
? Transform.COLLECT_ARGS_TO_VOID
: Transform.COLLECT_ARGS);
if (dropResult && collectorArity == 0) pos = 1; // pure side effect
Transform key = Transform.of(kind, pos, collectorArity, newTypes);
LambdaForm form = getInCache(key);
@ -598,7 +584,7 @@ class LambdaFormEditor {
argTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
}
assert(collectorType.parameterList().equals(Collections.nCopies(collectorArity, elementType)));
Transform.Kind kind = Transform.Kind.COLLECT_ARGS_TO_ARRAY;
byte kind = Transform.COLLECT_ARGS_TO_ARRAY;
Transform key = Transform.of(kind, pos, collectorArity, argTypeKey);
LambdaForm form = getInCache(key);
if (form != null) {
@ -634,7 +620,7 @@ class LambdaFormEditor {
}
LambdaForm filterArgumentForm(int pos, BasicType newType) {
Transform key = Transform.of(Transform.Kind.FILTER_ARG, pos, newType.ordinal());
Transform key = Transform.of(Transform.FILTER_ARG, pos, newType.ordinal());
LambdaForm form = getInCache(key);
if (form != null) {
assert(form.arity == lambdaForm.arity);
@ -710,7 +696,7 @@ class LambdaFormEditor {
}
LambdaForm filterReturnForm(BasicType newType, boolean constantZero) {
Transform.Kind kind = (constantZero ? Transform.Kind.FILTER_RETURN_TO_ZERO : Transform.Kind.FILTER_RETURN);
byte kind = (constantZero ? Transform.FILTER_RETURN_TO_ZERO : Transform.FILTER_RETURN);
Transform key = Transform.of(kind, newType.ordinal());
LambdaForm form = getInCache(key);
if (form != null) {
@ -762,11 +748,11 @@ class LambdaFormEditor {
LambdaForm foldArgumentsForm(int foldPos, boolean dropResult, MethodType combinerType) {
int combinerArity = combinerType.parameterCount();
Transform.Kind kind = (dropResult ? Transform.Kind.FOLD_ARGS_TO_VOID : Transform.Kind.FOLD_ARGS);
byte kind = (dropResult ? Transform.FOLD_ARGS_TO_VOID : Transform.FOLD_ARGS);
Transform key = Transform.of(kind, foldPos, combinerArity);
LambdaForm form = getInCache(key);
if (form != null) {
assert(form.arity == lambdaForm.arity - (kind == Transform.Kind.FOLD_ARGS ? 1 : 0));
assert(form.arity == lambdaForm.arity - (kind == Transform.FOLD_ARGS ? 1 : 0));
return form;
}
form = makeArgumentCombinationForm(foldPos, combinerType, true, dropResult);
@ -786,7 +772,7 @@ class LambdaFormEditor {
}
assert(skip + reorder.length == lambdaForm.arity);
if (nullPerm) return lambdaForm; // do not bother to cache
Transform key = Transform.of(Transform.Kind.PERMUTE_ARGS, reorder);
Transform key = Transform.of(Transform.PERMUTE_ARGS, reorder);
LambdaForm form = getInCache(key);
if (form != null) {
assert(form.arity == skip+inTypes) : form;
@ -855,7 +841,7 @@ class LambdaFormEditor {
int[] desc = BasicType.basicTypeOrds(localTypes);
desc = Arrays.copyOf(desc, desc.length + 1);
desc[desc.length - 1] = pos;
Transform key = Transform.of(Transform.Kind.LOCAL_TYPES, desc);
Transform key = Transform.of(Transform.LOCAL_TYPES, desc);
LambdaForm form = getInCache(key);
if (form != null) {
return form;

@ -25,8 +25,6 @@
package java.lang.invoke;
import jdk.internal.misc.JavaLangInvokeAccess;
import jdk.internal.misc.SharedSecrets;
import sun.invoke.util.BytecodeDescriptor;
import sun.invoke.util.VerifyAccess;
@ -37,7 +35,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Module;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@ -1002,7 +999,9 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
Collections.addAll(result, buf0);
}
}
result.addAll(Arrays.asList(buf).subList(0, bufCount));
for (int i = 0; i < bufCount; i++) {
result.add(buf[i]);
}
// Signature matching is not the same as type matching, since
// one signature might correspond to several types.
// So if matchType is a Class or MethodType, refilter the results.
@ -1150,27 +1149,4 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
return buf;
}
}
static {
// StackFrameInfo stores Member and this provides the shared secrets
// for stack walker to access MemberName information.
SharedSecrets.setJavaLangInvokeAccess(new JavaLangInvokeAccess() {
@Override
public Object newMemberName() {
return new MemberName();
}
@Override
public String getName(Object mname) {
MemberName memberName = (MemberName)mname;
return memberName.getName();
}
@Override
public boolean isNative(Object mname) {
MemberName memberName = (MemberName)mname;
return memberName.isNative();
}
});
}
}

@ -25,6 +25,8 @@
package java.lang.invoke;
import jdk.internal.misc.JavaLangInvokeAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
@ -44,6 +46,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
@ -1710,6 +1713,39 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
SharedSecrets.setJavaLangInvokeAccess(new JavaLangInvokeAccess() {
@Override
public Object newMemberName() {
return new MemberName();
}
@Override
public String getName(Object mname) {
MemberName memberName = (MemberName)mname;
return memberName.getName();
}
@Override
public boolean isNative(Object mname) {
MemberName memberName = (MemberName)mname;
return memberName.isNative();
}
@Override
public byte[] generateDMHClassBytes(String className,
MethodType[] methodTypes, int[] types) {
return GenerateJLIClassesHelper
.generateDMHClassBytes(className, methodTypes, types);
}
@Override
public Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
final String types) {
return GenerateJLIClassesHelper
.generateConcreteBMHClassBytes(types);
}
});
}
/** Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore(). */

@ -3115,7 +3115,7 @@ assert((int)twice.invokeExact(21) == 42);
return dropArguments(zero(type.returnType()), 0, type.parameterList());
}
private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.values().length];
private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.COUNT];
private static MethodHandle makeIdentity(Class<?> ptype) {
MethodType mtype = methodType(ptype, ptype);
LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
@ -3133,7 +3133,7 @@ assert((int)twice.invokeExact(21) == 42);
assert(btw == Wrapper.OBJECT);
return makeZero(rtype);
}
private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.values().length];
private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.COUNT];
private static MethodHandle makeZero(Class<?> rtype) {
MethodType mtype = methodType(rtype);
LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));

@ -281,8 +281,7 @@ public final class StringConcatFactory {
if (c == TAG_CONST) {
Object cnst = constants[constC++];
el.add(new RecipeElement(cnst));
}
if (c == TAG_ARG) {
} else if (c == TAG_ARG) {
el.add(new RecipeElement(argC++));
}
} else {
@ -322,32 +321,30 @@ public final class StringConcatFactory {
private static final class RecipeElement {
private final Object value;
private final int argPos;
private final Tag tag;
public RecipeElement(Object cnst) {
this.value = Objects.requireNonNull(cnst);
this.argPos = -1;
this.tag = Tag.CONST;
}
public RecipeElement(int arg) {
this.value = null;
assert (arg >= 0);
this.argPos = arg;
this.tag = Tag.ARG;
}
public Object getValue() {
assert (tag == Tag.CONST);
assert (isConst());
return value;
}
public int getArgPos() {
assert (tag == Tag.ARG);
assert (!isConst());
return argPos;
}
public Tag getTag() {
return tag;
public boolean isConst() {
return argPos == -1;
}
@Override
@ -357,22 +354,19 @@ public final class StringConcatFactory {
RecipeElement that = (RecipeElement) o;
if (tag != that.tag) return false;
if (tag == Tag.CONST && (!value.equals(that.value))) return false;
if (tag == Tag.ARG && (argPos != that.argPos)) return false;
boolean isConst = isConst();
if (isConst != that.isConst()) return false;
if (isConst && (!value.equals(that.value))) return false;
if (!isConst && (argPos != that.argPos)) return false;
return true;
}
@Override
public int hashCode() {
return tag.hashCode();
return argPos;
}
}
private enum Tag {
CONST, ARG
}
/**
* Facilitates the creation of optimized String concatenation methods, that
* can be used to efficiently concatenate a known number of arguments of
@ -880,31 +874,24 @@ public final class StringConcatFactory {
int off = 0;
for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) {
case CONST: {
// Guaranteed non-null, no null check required.
break;
if (el.isConst()) {
// Guaranteed non-null, no null check required.
} else {
// Null-checks are needed only for String arguments, and when a previous stage
// did not do implicit null-checks. If a String is null, we eagerly replace it
// with "null" constant. Note, we omit Objects here, because we don't call
// .length() on them down below.
int ac = el.getArgPos();
Class<?> cl = arr[ac];
if (cl == String.class && !guaranteedNonNull[ac]) {
Label l0 = new Label();
mv.visitIntInsn(ALOAD, off);
mv.visitJumpInsn(IFNONNULL, l0);
mv.visitLdcInsn("null");
mv.visitIntInsn(ASTORE, off);
mv.visitLabel(l0);
}
case ARG: {
// Null-checks are needed only for String arguments, and when a previous stage
// did not do implicit null-checks. If a String is null, we eagerly replace it
// with "null" constant. Note, we omit Objects here, because we don't call
// .length() on them down below.
int ac = el.getArgPos();
Class<?> cl = arr[ac];
if (cl == String.class && !guaranteedNonNull[ac]) {
Label l0 = new Label();
mv.visitIntInsn(ALOAD, off);
mv.visitJumpInsn(IFNONNULL, l0);
mv.visitLdcInsn("null");
mv.visitIntInsn(ASTORE, off);
mv.visitLabel(l0);
}
off += getParameterSize(cl);
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
off += getParameterSize(cl);
}
}
}
@ -925,37 +912,30 @@ public final class StringConcatFactory {
mv.visitInsn(ICONST_0);
for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) {
case CONST: {
Object cnst = el.getValue();
len += cnst.toString().length();
break;
if (el.isConst()) {
Object cnst = el.getValue();
len += cnst.toString().length();
} else {
/*
If an argument is String, then we can call .length() on it. Sized/Exact modes have
converted arguments for us. If an argument is primitive, we can provide a guess
for its String representation size.
*/
Class<?> cl = arr[el.getArgPos()];
if (cl == String.class) {
mv.visitIntInsn(ALOAD, off);
mv.visitMethodInsn(
INVOKEVIRTUAL,
"java/lang/String",
"length",
"()I",
false
);
mv.visitInsn(IADD);
} else if (cl.isPrimitive()) {
len += estimateSize(cl);
}
case ARG: {
/*
If an argument is String, then we can call .length() on it. Sized/Exact modes have
converted arguments for us. If an argument is primitive, we can provide a guess
for its String representation size.
*/
Class<?> cl = arr[el.getArgPos()];
if (cl == String.class) {
mv.visitIntInsn(ALOAD, off);
mv.visitMethodInsn(
INVOKEVIRTUAL,
"java/lang/String",
"length",
"()I",
false
);
mv.visitInsn(IADD);
} else if (cl.isPrimitive()) {
len += estimateSize(cl);
}
off += getParameterSize(cl);
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
off += getParameterSize(cl);
}
}
@ -987,23 +967,17 @@ public final class StringConcatFactory {
int off = 0;
for (RecipeElement el : recipe.getElements()) {
String desc;
switch (el.getTag()) {
case CONST: {
Object cnst = el.getValue();
mv.visitLdcInsn(cnst);
desc = getSBAppendDesc(cnst.getClass());
break;
}
case ARG: {
Class<?> cl = arr[el.getArgPos()];
mv.visitVarInsn(getLoadOpcode(cl), off);
off += getParameterSize(cl);
desc = getSBAppendDesc(cl);
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
if (el.isConst()) {
Object cnst = el.getValue();
mv.visitLdcInsn(cnst);
desc = getSBAppendDesc(cnst.getClass());
} else {
Class<?> cl = arr[el.getArgPos()];
mv.visitVarInsn(getLoadOpcode(cl), off);
off += getParameterSize(cl);
desc = getSBAppendDesc(cl);
}
mv.visitMethodInsn(
INVOKEVIRTUAL,
"java/lang/StringBuilder",
@ -1279,26 +1253,19 @@ public final class StringConcatFactory {
// call the usual String.length(). Primitive values string sizes can be estimated.
int initial = 0;
for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) {
case CONST: {
Object cnst = el.getValue();
initial += cnst.toString().length();
break;
if (el.isConst()) {
Object cnst = el.getValue();
initial += cnst.toString().length();
} else {
final int i = el.getArgPos();
Class<?> type = ptypesList.get(i);
if (type.isPrimitive()) {
MethodHandle est = MethodHandles.constant(int.class, estimateSize(type));
est = MethodHandles.dropArguments(est, 0, type);
lengthers[i] = est;
} else {
lengthers[i] = STRING_LENGTH;
}
case ARG: {
final int i = el.getArgPos();
Class<?> type = ptypesList.get(i);
if (type.isPrimitive()) {
MethodHandle est = MethodHandles.constant(int.class, estimateSize(type));
est = MethodHandles.dropArguments(est, 0, type);
lengthers[i] = est;
} else {
lengthers[i] = STRING_LENGTH;
}
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
}
}
@ -1311,26 +1278,19 @@ public final class StringConcatFactory {
for (int i = elements.size() - 1; i >= 0; i--) {
RecipeElement el = elements.get(i);
MethodHandle appender;
switch (el.getTag()) {
case CONST: {
Object constant = el.getValue();
MethodHandle mh = appender(adaptToStringBuilder(constant.getClass()));
appender = MethodHandles.insertArguments(mh, 1, constant);
break;
}
case ARG: {
int ac = el.getArgPos();
appender = appender(ptypesList.get(ac));
if (el.isConst()) {
Object constant = el.getValue();
MethodHandle mh = appender(adaptToStringBuilder(constant.getClass()));
appender = MethodHandles.insertArguments(mh, 1, constant);
} else {
int ac = el.getArgPos();
appender = appender(ptypesList.get(ac));
// Insert dummy arguments to match the prefix in the signature.
// The actual appender argument will be the ac-ith argument.
if (ac != 0) {
appender = MethodHandles.dropArguments(appender, 1, ptypesList.subList(0, ac));
}
break;
// Insert dummy arguments to match the prefix in the signature.
// The actual appender argument will be the ac-ith argument.
if (ac != 0) {
appender = MethodHandles.dropArguments(appender, 1, ptypesList.subList(0, ac));
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
}
builder = MethodHandles.foldArguments(builder, appender);
}
@ -1521,19 +1481,12 @@ public final class StringConcatFactory {
// *ending* index.
for (RecipeElement el : recipe.getElements()) {
MethodHandle prepender;
switch (el.getTag()) {
case CONST: {
Object cnst = el.getValue();
prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
break;
}
case ARG: {
int pos = el.getArgPos();
prepender = selectArgument(prepender(ptypesList.get(pos)), 3, ptypesList, pos);
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
if (el.isConst()) {
Object cnst = el.getValue();
prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
} else {
int pos = el.getArgPos();
prepender = selectArgument(prepender(ptypesList.get(pos)), 3, ptypesList, pos);
}
// Remove "old" index from arguments
@ -1573,43 +1526,36 @@ public final class StringConcatFactory {
byte initialCoder = INITIAL_CODER;
int initialLen = 0; // initial length, in characters
for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) {
case CONST: {
Object constant = el.getValue();
String s = constant.toString();
initialCoder = (byte) coderMixer(String.class).invoke(initialCoder, s);
initialLen += s.length();
break;
}
case ARG: {
int ac = el.getArgPos();
if (el.isConst()) {
Object constant = el.getValue();
String s = constant.toString();
initialCoder = (byte) coderMixer(String.class).invoke(initialCoder, s);
initialLen += s.length();
} else {
int ac = el.getArgPos();
Class<?> argClass = ptypesList.get(ac);
MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypesList, ac);
lm = MethodHandles.dropArguments(lm, 0, byte.class); // (*)
lm = MethodHandles.dropArguments(lm, 2, byte.class);
Class<?> argClass = ptypesList.get(ac);
MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypesList, ac);
lm = MethodHandles.dropArguments(lm, 0, byte.class); // (*)
lm = MethodHandles.dropArguments(lm, 2, byte.class);
MethodHandle cm = selectArgument(coderMixer(argClass), 1, ptypesList, ac);
cm = MethodHandles.dropArguments(cm, 0, int.class); // (**)
MethodHandle cm = selectArgument(coderMixer(argClass), 1, ptypesList, ac);
cm = MethodHandles.dropArguments(cm, 0, int.class); // (**)
// Read this bottom up:
// Read this bottom up:
// 4. Drop old index and coder, producing ("new-index", "new-coder", <args>)
mh = MethodHandles.dropArguments(mh, 2, int.class, byte.class);
// 4. Drop old index and coder, producing ("new-index", "new-coder", <args>)
mh = MethodHandles.dropArguments(mh, 2, int.class, byte.class);
// 3. Compute "new-index", producing ("new-index", "new-coder", "old-index", "old-coder", <args>)
// Length mixer ignores both "new-coder" and "old-coder" due to dropArguments above (*)
mh = MethodHandles.foldArguments(mh, lm);
// 3. Compute "new-index", producing ("new-index", "new-coder", "old-index", "old-coder", <args>)
// Length mixer ignores both "new-coder" and "old-coder" due to dropArguments above (*)
mh = MethodHandles.foldArguments(mh, lm);
// 2. Compute "new-coder", producing ("new-coder", "old-index", "old-coder", <args>)
// Coder mixer ignores the "old-index" arg due to dropArguments above (**)
mh = MethodHandles.foldArguments(mh, cm);
// 2. Compute "new-coder", producing ("new-coder", "old-index", "old-coder", <args>)
// Coder mixer ignores the "old-index" arg due to dropArguments above (**)
mh = MethodHandles.foldArguments(mh, cm);
// 1. The mh shape here is ("old-index", "old-coder", <args>)
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
// 1. The mh shape here is ("old-index", "old-coder", <args>)
}
}

@ -38,7 +38,7 @@ class TypeConvertingMethodAdapter extends MethodVisitor {
super(Opcodes.ASM5, mv);
}
private static final int NUM_WRAPPERS = Wrapper.values().length;
private static final int NUM_WRAPPERS = Wrapper.COUNT;
private static final String NAME_OBJECT = "java/lang/Object";
private static final String WRAPPER_PREFIX = "Ljava/lang/";

@ -1057,57 +1057,11 @@ public abstract class VarHandle {
Object addAndGet(Object... args);
enum AccessType {
GET(Object.class) {
@Override
MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate) {
Class<?>[] ps = allocateParameters(0, receiver, intermediate);
fillParameters(ps, receiver, intermediate);
return MethodType.methodType(value, ps);
}
},
SET(void.class) {
@Override
MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate) {
Class<?>[] ps = allocateParameters(1, receiver, intermediate);
int i = fillParameters(ps, receiver, intermediate);
ps[i] = value;
return MethodType.methodType(void.class, ps);
}
},
COMPARE_AND_SWAP(boolean.class) {
@Override
MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate) {
Class<?>[] ps = allocateParameters(2, receiver, intermediate);
int i = fillParameters(ps, receiver, intermediate);
ps[i++] = value;
ps[i] = value;
return MethodType.methodType(boolean.class, ps);
}
},
COMPARE_AND_EXCHANGE(Object.class) {
@Override
MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate) {
Class<?>[] ps = allocateParameters(2, receiver, intermediate);
int i = fillParameters(ps, receiver, intermediate);
ps[i++] = value;
ps[i] = value;
return MethodType.methodType(value, ps);
}
},
GET_AND_UPDATE(Object.class) {
@Override
MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate) {
Class<?>[] ps = allocateParameters(1, receiver, intermediate);
int i = fillParameters(ps, receiver, intermediate);
ps[i] = value;
return MethodType.methodType(value, ps);
}
};
GET(Object.class),
SET(void.class),
COMPARE_AND_SWAP(boolean.class),
COMPARE_AND_EXCHANGE(Object.class),
GET_AND_UPDATE(Object.class);
final Class<?> returnType;
final boolean isMonomorphicInReturnType;
@ -1117,8 +1071,41 @@ public abstract class VarHandle {
isMonomorphicInReturnType = returnType != Object.class;
}
abstract MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate);
MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate) {
Class<?>[] ps;
int i;
switch (this) {
case GET:
ps = allocateParameters(0, receiver, intermediate);
fillParameters(ps, receiver, intermediate);
return MethodType.methodType(value, ps);
case SET:
ps = allocateParameters(1, receiver, intermediate);
i = fillParameters(ps, receiver, intermediate);
ps[i] = value;
return MethodType.methodType(void.class, ps);
case COMPARE_AND_SWAP:
ps = allocateParameters(2, receiver, intermediate);
i = fillParameters(ps, receiver, intermediate);
ps[i++] = value;
ps[i] = value;
return MethodType.methodType(boolean.class, ps);
case COMPARE_AND_EXCHANGE:
ps = allocateParameters(2, receiver, intermediate);
i = fillParameters(ps, receiver, intermediate);
ps[i++] = value;
ps[i] = value;
return MethodType.methodType(value, ps);
case GET_AND_UPDATE:
ps = allocateParameters(1, receiver, intermediate);
i = fillParameters(ps, receiver, intermediate);
ps[i] = value;
return MethodType.methodType(value, ps);
default:
throw new InternalError("Unknown AccessType");
}
}
private static Class<?>[] allocateParameters(int values,
Class<?> receiver, Class<?>... intermediate) {

@ -169,7 +169,7 @@ public final class ModuleReference {
/**
* Returns {@code true} if this module has been patched via -Xpatch.
* Returns {@code true} if this module has been patched via --patch-module.
*/
boolean isPatched() {
return patched;

@ -68,7 +68,7 @@ class ModuleReferences {
/**
* Creates a ModuleReference to a module or to patched module when
* creating modules for the boot Layer and -Xpatch is specified.
* creating modules for the boot Layer and --patch-module is specified.
*/
private static ModuleReference newModule(ModuleDescriptor md,
URI uri,

@ -178,7 +178,7 @@ class SystemModuleFinder implements ModuleFinder {
ModuleReference mref =
new ModuleReference(md, uri, readerSupplier, hash);
// may need a reference to a patched module if -Xpatch specified
// may need a reference to a patched module if --patch-module specified
mref = ModulePatcher.interposeIfNeeded(mref);
return mref;

@ -25,19 +25,42 @@
package jdk.internal.misc;
import java.lang.invoke.MethodType;
import java.util.Map;
public interface JavaLangInvokeAccess {
/**
* Create a new MemberName instance
* Create a new MemberName instance. Used by {@see StackFrameInfo}.
*/
Object newMemberName();
/**
* Returns the name for the given MemberName
* Returns the name for the given MemberName. Used by {@see StackFrameInfo}.
*/
String getName(Object mname);
/**
* Returns {@code true} if the given MemberName is a native method
* Returns {@code true} if the given MemberName is a native method. Used by
* {@see StackFrameInfo}.
*/
boolean isNative(Object mname);
/**
* Returns a {@code byte[]} containing the bytecode for a class implementing
* DirectMethodHandle of each pairwise combination of {@code MethodType} and
* an {@code int} representing method type. Used by
* GenerateJLIClassesPlugin to generate such a class during the jlink phase.
*/
byte[] generateDMHClassBytes(String className, MethodType[] methodTypes,
int[] types);
/**
* Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle
* species class implementing the signature defined by {@code types}. Used
* by GenerateBMHClassesPlugin to enable generation of such classes during
* the jlink phase. Should do some added validation since this string may be
* user provided.
*/
Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
final String types);
}

@ -95,7 +95,7 @@ public class SharedSecrets {
public static JavaLangInvokeAccess getJavaLangInvokeAccess() {
if (javaLangInvokeAccess == null) {
try {
Class<?> c = Class.forName("java.lang.invoke.MemberName");
Class<?> c = Class.forName("java.lang.invoke.MethodHandleImpl");
unsafe.ensureClassInitialized(c);
} catch (ClassNotFoundException e) {};
}

@ -56,8 +56,8 @@ import jdk.internal.perf.PerfCounter;
* The {@link #boot() boot} method is called early in the startup to initialize
* the module system. In summary, the boot method creates a Configuration by
* resolving a set of module names specified via the launcher (or equivalent)
* -m and -addmods options. The modules are located on a module path that is
* constructed from the upgrade module path, system modules, and application
* -m and --add-modules options. The modules are located on a module path that
* is constructed from the upgrade module path, system modules, and application
* module path. The Configuration is instantiated as the boot Layer with each
* module in the the configuration defined to one of the built-in class loaders.
*/
@ -127,16 +127,16 @@ public final class ModuleBootstrap {
long t2 = System.nanoTime();
// -upgrademodulepath option specified to launcher
// --upgrade-module-path option specified to launcher
ModuleFinder upgradeModulePath
= createModulePathFinder("jdk.upgrade.module.path");
= createModulePathFinder("jdk.module.upgrade.path");
if (upgradeModulePath != null)
systemModules = ModuleFinder.compose(upgradeModulePath, systemModules);
// -modulepath option specified to the launcher
// --module-path option specified to the launcher
ModuleFinder appModulePath = createModulePathFinder("jdk.module.path");
// The module finder: [-upgrademodulepath] system [-modulepath]
// The module finder: [--upgrade-module-path] system [--module-path]
ModuleFinder finder = systemModules;
if (appModulePath != null)
finder = ModuleFinder.compose(finder, appModulePath);
@ -149,11 +149,11 @@ public final class ModuleBootstrap {
if (mainModule != null)
roots.add(mainModule);
// additional module(s) specified by -addmods
// additional module(s) specified by --add-modules
boolean addAllDefaultModules = false;
boolean addAllSystemModules = false;
boolean addAllApplicationModules = false;
String propValue = System.getProperty("jdk.launcher.addmods");
String propValue = getAndRemoveProperty("jdk.module.addmods");
if (propValue != null) {
for (String mod: propValue.split(",")) {
switch (mod) {
@ -172,8 +172,8 @@ public final class ModuleBootstrap {
}
}
// -limitmods
propValue = System.getProperty("jdk.launcher.limitmods");
// --limit-modules
propValue = getAndRemoveProperty("jdk.module.limitmods");
if (propValue != null) {
Set<String> mods = new HashSet<>();
for (String mod: propValue.split(",")) {
@ -216,7 +216,7 @@ public final class ModuleBootstrap {
}
}
// If `-addmods ALL-SYSTEM` is specified then all observable system
// If `--add-modules ALL-SYSTEM` is specified then all observable system
// modules will be resolved.
if (addAllSystemModules) {
ModuleFinder f = finder; // observable modules
@ -228,9 +228,9 @@ public final class ModuleBootstrap {
.forEach(mn -> roots.add(mn));
}
// If `-addmods ALL-MODULE-PATH` is specified then all observable
// If `--add-modules ALL-MODULE-PATH` is specified then all observable
// modules on the application module path will be resolved.
if (appModulePath != null && addAllApplicationModules) {
if (appModulePath != null && addAllApplicationModules) {
ModuleFinder f = finder; // observable modules
appModulePath.findAll()
.stream()
@ -250,7 +250,7 @@ public final class ModuleBootstrap {
if (baseUri.getScheme().equals("jrt") // toLowerCase not needed here
&& (upgradeModulePath == null)
&& (appModulePath == null)
&& (System.getProperty("jdk.launcher.patch.0") == null)) {
&& (!ModulePatcher.isBootLayerPatched())) {
needPostResolutionChecks = false;
}
@ -317,7 +317,7 @@ public final class ModuleBootstrap {
PerfCounters.loadModulesTime.addElapsedTimeFrom(t5);
// -XaddReads and -XaddExports
// --add-reads and --add-exports
addExtraReads(bootLayer);
addExtraExports(bootLayer);
@ -394,13 +394,13 @@ public final class ModuleBootstrap {
/**
* Process the -XaddReads options to add any additional read edges that
* Process the --add-reads options to add any additional read edges that
* are specified on the command-line.
*/
private static void addExtraReads(Layer bootLayer) {
// decode the command line options
Map<String, Set<String>> map = decode("jdk.launcher.addreads.");
Map<String, Set<String>> map = decode("jdk.module.addreads.");
for (Map.Entry<String, Set<String>> e : map.entrySet()) {
@ -431,13 +431,13 @@ public final class ModuleBootstrap {
/**
* Process the -XaddExports options to add any additional read edges that
* Process the --add-exports options to add any additional read edges that
* are specified on the command-line.
*/
private static void addExtraExports(Layer bootLayer) {
// decode the command line options
Map<String, Set<String>> map = decode("jdk.launcher.addexports.");
Map<String, Set<String>> map = decode("jdk.module.addexports.");
for (Map.Entry<String, Set<String>> e : map.entrySet()) {
@ -483,13 +483,14 @@ public final class ModuleBootstrap {
/**
* Decodes the values of -XaddReads or -XaddExports options
* Decodes the values of --add-reads or --add-exports options
*
* The format of the options is: $KEY=$MODULE(,$MODULE)*
*/
private static Map<String, Set<String>> decode(String prefix) {
int index = 0;
String value = System.getProperty(prefix + index);
// the system property is removed after decoding
String value = getAndRemoveProperty(prefix + index);
if (value == null)
return Collections.emptyMap();
@ -522,12 +523,18 @@ public final class ModuleBootstrap {
}
index++;
value = System.getProperty(prefix + index);
value = getAndRemoveProperty(prefix + index);
}
return map;
}
/**
* Gets and remove the named system property
*/
private static String getAndRemoveProperty(String key) {
return (String)System.getProperties().remove(key);
}
/**
* Throws a RuntimeException with the given message

@ -58,7 +58,7 @@ import sun.net.www.ParseUtil;
/**
* Provides support for patching modules in the boot layer with -Xpatch.
* Provides support for patching modules in the boot layer with --patch-module.
*/
public final class ModulePatcher {
@ -66,28 +66,27 @@ public final class ModulePatcher {
private static final JavaLangModuleAccess JLMA
= SharedSecrets.getJavaLangModuleAccess();
// the prefix of the system properties that encode the value of -Xpatch
private static final String PATCH_PROPERTY_PREFIX = "jdk.launcher.patch.";
// the prefix of the system properties that encode the value of --patch-module
private static final String PATCH_PROPERTY_PREFIX = "jdk.module.patch.";
// module name -> sequence of patches (directories or JAR files)
private static final Map<String, List<Path>> PATCH_MAP = decodeProperties();
private ModulePatcher() { }
/**
* Decodes the values of -Xpatch options, returning a Map of module name to
* list of file paths.
* Decodes the values of --patch-module options, returning a Map of module
* name to list of file paths.
*
* @throws IllegalArgumentException if the the module name is missing or
* -Xpatch is used more than once to patch the same module
* --patch-module is used more than once to patch the same module
*/
private static Map<String, List<Path>> decodeProperties() {
int index = 0;
String value = System.getProperty(PATCH_PROPERTY_PREFIX + index);
String value = getAndRemoveProperty(PATCH_PROPERTY_PREFIX + index);
if (value == null)
return Collections.emptyMap(); // -Xpatch not specified
return Collections.emptyMap(); // --patch-module not specified
Map<String, List<Path>> map = new HashMap<>();
while (value != null) {
@ -115,13 +114,21 @@ public final class ModulePatcher {
}
index++;
value = System.getProperty(PATCH_PROPERTY_PREFIX + index);
value = getAndRemoveProperty(PATCH_PROPERTY_PREFIX + index);
}
return map;
}
/**
* Returns {@code true} is --patch-module is specified to patch modules
* in the boot layer.
*/
static boolean isBootLayerPatched() {
return !PATCH_MAP.isEmpty();
}
/**
* Returns a module reference that interposes on the given module if
* needed. If there are no patches for the given module then the module
@ -536,6 +543,13 @@ public final class ModulePatcher {
}
}
/**
* Gets and remove the named system property
*/
private static String getAndRemoveProperty(String key) {
return (String)System.getProperties().remove(key);
}
/**
* Derives a package name from the name of an entry in a JAR file.
*/

@ -128,6 +128,7 @@ module java.base {
exports jdk.internal.logger to
java.logging;
exports jdk.internal.org.objectweb.asm to
jdk.jartool,
jdk.jlink,
jdk.scripting.nashorn,
jdk.vm.ci;

@ -29,27 +29,32 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.util.EnumMap;
import jdk.internal.vm.annotation.Stable;
public class ValueConversions {
private static final Class<?> THIS_CLASS = ValueConversions.class;
private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
/** Thread-safe canonicalized mapping from Wrapper to MethodHandle
/**
* Thread-safe canonicalized mapping from Wrapper to MethodHandle
* with unsynchronized reads and synchronized writes.
* It's safe to publish MethodHandles by data race because they are immutable. */
* It's safe to publish MethodHandles by data race because they are immutable.
*/
private static class WrapperCache {
/** EnumMap uses preconstructed array internally, which is constant during it's lifetime. */
private final EnumMap<Wrapper, MethodHandle> map = new EnumMap<>(Wrapper.class);
@Stable
private final MethodHandle[] map = new MethodHandle[Wrapper.COUNT];
public MethodHandle get(Wrapper w) {
return map.get(w);
return map[w.ordinal()];
}
public synchronized MethodHandle put(final Wrapper w, final MethodHandle mh) {
// Simulate CAS to avoid racy duplication
MethodHandle prev = map.putIfAbsent(w, mh);
if (prev != null) return prev;
return mh;
MethodHandle prev = map[w.ordinal()];
if (prev != null) {
return prev;
} else {
map[w.ordinal()] = mh;
return mh;
}
}
}
@ -623,7 +628,7 @@ public class ValueConversions {
return (x ? (byte)1 : (byte)0);
}
private static final WrapperCache[] CONVERT_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.values().length);
private static final WrapperCache[] CONVERT_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.COUNT);
public static MethodHandle convertPrimitive(Wrapper wsrc, Wrapper wdst) {
WrapperCache cache = CONVERT_PRIMITIVE_FUNCTIONS[wsrc.ordinal()];

@ -42,6 +42,8 @@ public enum Wrapper {
VOID ( Void.class, void.class, 'V', null, Format.other( 0)),
;
public static final int COUNT = 10;
private final Class<?> wrapperType;
private final Class<?> primitiveType;
private final char basicTypeChar;
@ -160,7 +162,10 @@ public enum Wrapper {
return true;
}
static { assert(checkConvertibleFrom()); }
static {
assert(checkConvertibleFrom());
assert(COUNT == Wrapper.values().length);
}
private static boolean checkConvertibleFrom() {
// Check the matrix for correct classification of widening conversions.
for (Wrapper w : values()) {

@ -60,8 +60,6 @@ import java.nio.charset.Charset;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.Normalizer;
import java.text.MessageFormat;
import java.util.ResourceBundle;
@ -905,7 +903,7 @@ public final class LauncherHelper {
ModuleFinder finder = jdk.internal.module.ModuleBootstrap.finder();
int colon = optionFlag.indexOf(':');
int colon = optionFlag.indexOf('=');
if (colon == -1) {
finder.findAll().stream()
.sorted(Comparator.comparing(ModuleReference::descriptor))

@ -27,7 +27,7 @@
java.launcher.opt.header = Usage: {0} [options] class [args...]\n\
\ (to execute a class)\n or {0} [options] -jar jarfile [args...]\n\
\ (to execute a jar file)\n\
\ or {0} [options] -mp <modulepath> -m <modulename>[/<mainclass>] [args...]\n\
\ or {0} [options] -p <modulepath> -m <modulename>[/<mainclass>] [args...]\n\
\ (to execute the main class in a module)\n\
where options include:\n
@ -41,24 +41,28 @@ java.launcher.ergo.message2 =\ because you are running on a se
# Translators please note do not translate the options themselves
java.launcher.opt.footer =\ -cp <class search path of directories and zip/jar files>\n\
\ -classpath <class search path of directories and zip/jar files>\n\
\ --class-path <class search path of directories and zip/jar files>\n\
\ A {0} separated list of directories, JAR archives,\n\
\ and ZIP archives to search for class files.\n\
\ -mp <module path>\n\
\ -modulepath <module path>...\n\
\ -p <module path>\n\
\ --module-path <module path>...\n\
\ A {0} separated list of directories, each directory\n\
\ is a directory of modules.\n\
\ -upgrademodulepath <module path>...\n\
\ --upgrade-module-path <module path>...\n\
\ A {0} separated list of directories, each directory\n\
\ is a directory of modules that replace upgradeable\n\
\ modules in the runtime image\n\
\ -m <modulename>[/<mainclass>]\n\
\ -m <module>[/<mainclass>]\n\
\ --module <modulename>[/<mainclass>]\n\
\ the initial module to resolve, and the name of the main class\n\
\ to execute if not specified by the module\n\
\ -addmods <modulename>[,<modulename>...]\n\
\ root modules to resolve in addition to the initial module\n\
\ -limitmods <modulename>[,<modulename>...]\n\
\ --add-modules <modulename>[,<modulename>...]\n\
\ root modules to resolve in addition to the initial module.\n\
\ <modulename> can also be ALL-DEFAULT, ALL-SYSTEM,\n\
\ ALL-MODULE-PATH.\n\
\ --limit-modules <modulename>[,<modulename>...]\n\
\ limit the universe of observable modules\n\
\ -listmods[:<modulename>[,<modulename>...]]\n\
\ --list-modules [<modulename>[,<modulename>...]]\n\
\ list the observable modules and exit\n\
\ --dry-run create VM but do not execute main method.\n\
\ This --dry-run option may be useful for validating the\n\
@ -69,7 +73,8 @@ java.launcher.opt.footer =\ -cp <class search path of directories and zip
\ enable verbose output\n\
\ -version print product version and exit\n\
\ -showversion print product version and continue\n\
\ -? -help print this help message\n\
\ -? -help --help\n\
\ print this help message\n\
\ -X print help on non-standard options\n\
\ -ea[:<packagename>...|:<classname>]\n\
\ -enableassertions[:<packagename>...|:<classname>]\n\
@ -91,6 +96,8 @@ java.launcher.opt.footer =\ -cp <class search path of directories and zip
\ -splash:<imagepath>\n\
\ show splash screen with specified image\n\
\ @<filepath> read options from the specified file\n\
\To specify an argument for a long option, you can use --<name>=<value> or\n\
\--<name> <value>.\n\
See http://www.oracle.com/technetwork/java/javase/documentation/index.html for more details.
@ -123,17 +130,21 @@ java.launcher.X.usage=\
\ show all property settings and continue\n\
\ -XshowSettings:locale\n\
\ show all locale related settings and continue\n\
\ -XaddReads:<module>=<other-module>(,<other-module>)*\n\
\ <module> reads other modules,\n\
\ regardless of module declaration\n\
\ -XaddExports:<module>/<package>=<other-module>(,<other-module>)*\n\
\ <module> exports <package> to other modules,\n\
\ regardless of module declaration\n\
\ -Xpatch:<module>=<file>({0}<file>)*\n\
\ -Xdisable-@files disable further argument file expansion\n\
\ --add-reads <module>=<target-module>(,<target-module>)*\n\
\ updates <module> to read <target-module>, regardless\n\
\ of module declaration. \n\
\ <target-module> can be ALL-UNNAMED to read all unnamed\n\
\ modules.\n\
\ --add-exports <module>/<package>=<target-module>(,<target-module>)*\n\
\ updates <module> to export <package> to <target-module>,\n\
\ regardless of module declaration.\n\
\ <target-module> can be ALL-UNNAMED to export to all\n\
\ unnamed modules.\n\
\ --patch-module <module>=<file>({0}<file>)*\n\
\ Override or augment a module with classes and resources\n\
\ in JAR files or directories\n\
\ -Xdisable-@files disable further argument file expansion\n\n\
The -X options are non-standard and subject to change without notice.\n
\ in JAR files or directories.\n\n\
These options are non-standard and subject to change without notice.\n
# Translators please note do not translate the options themselves
java.launcher.X.macosx.usage=\

@ -1994,7 +1994,7 @@ final class ServerHandshaker extends Handshaker {
private StaplingParameters processStapling(ClientHello mesg) {
StaplingParameters params = null;
ExtensionType ext;
ExtensionType ext = null;
StatusRequestType type = null;
StatusRequest req = null;
Map<X509Certificate, byte[]> responses;
@ -2012,33 +2012,40 @@ final class ServerHandshaker extends Handshaker {
CertStatusReqListV2Extension statReqExtV2 =
(CertStatusReqListV2Extension)mesg.extensions.get(
ExtensionType.EXT_STATUS_REQUEST_V2);
// Keep processing only if either status_request or status_request_v2
// has been sent in the ClientHello.
if (statReqExt == null && statReqExtV2 == null) {
return null;
}
// Determine which type of stapling we are doing and assert the
// proper extension in the server hello.
// Favor status_request_v2 over status_request and ocsp_multi
// over ocsp.
// If multiple ocsp or ocsp_multi types exist, select the first
// instance of a given type
ext = ExtensionType.EXT_STATUS_REQUEST;
// instance of a given type. Also since we don't support ResponderId
// selection yet, only accept a request if the ResponderId field
// is empty.
if (statReqExtV2 != null) { // RFC 6961 stapling
ext = ExtensionType.EXT_STATUS_REQUEST_V2;
List<CertStatusReqItemV2> reqItems =
statReqExtV2.getRequestItems();
int ocspIdx = -1;
int ocspMultiIdx = -1;
for (int pos = 0; pos < reqItems.size(); pos++) {
for (int pos = 0; (pos < reqItems.size() &&
(ocspIdx == -1 || ocspMultiIdx == -1)); pos++) {
CertStatusReqItemV2 item = reqItems.get(pos);
if (ocspIdx < 0 && item.getType() ==
StatusRequestType.OCSP) {
ocspIdx = pos;
} else if (ocspMultiIdx < 0 && item.getType() ==
StatusRequestType.OCSP_MULTI) {
ocspMultiIdx = pos;
StatusRequestType curType = item.getType();
if (ocspIdx < 0 && curType == StatusRequestType.OCSP) {
OCSPStatusRequest ocspReq =
(OCSPStatusRequest)item.getRequest();
if (ocspReq.getResponderIds().isEmpty()) {
ocspIdx = pos;
}
} else if (ocspMultiIdx < 0 &&
curType == StatusRequestType.OCSP_MULTI) {
// If the type is OCSP, then the request
// is guaranteed to be OCSPStatusRequest
OCSPStatusRequest ocspReq =
(OCSPStatusRequest)item.getRequest();
if (ocspReq.getResponderIds().isEmpty()) {
ocspMultiIdx = pos;
}
}
}
if (ocspMultiIdx >= 0) {
@ -2047,16 +2054,47 @@ final class ServerHandshaker extends Handshaker {
} else if (ocspIdx >= 0) {
type = reqItems.get(ocspIdx).getType();
req = reqItems.get(ocspIdx).getRequest();
} else {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Warning: No suitable request " +
"found in the status_request_v2 extension.");
}
}
}
// Only attempt to process a status_request extension if:
// * The status_request extension is set AND
// * either the status_request_v2 extension is not present OR
// * none of the underlying OCSPStatusRequest structures is suitable
// for stapling.
// If either of the latter two bullet items is true the ext, type and
// req variables should all be null. If any are null we will try
// processing an asserted status_request.
if ((statReqExt != null) &&
(ext == null || type == null || req == null)) {
ext = ExtensionType.EXT_STATUS_REQUEST;
type = statReqExt.getType();
if (type == StatusRequestType.OCSP) {
// If the type is OCSP, then the request is guaranteed
// to be OCSPStatusRequest
OCSPStatusRequest ocspReq =
(OCSPStatusRequest)statReqExt.getRequest();
if (ocspReq.getResponderIds().isEmpty()) {
req = ocspReq;
} else {
if (debug != null && Debug.isOn("handshake")) {
req = null;
System.out.println("Warning: No suitable request " +
"found in the status_request extension.");
}
}
}
} else { // RFC 6066 stapling
type = StatusRequestType.OCSP;
req = statReqExt.getRequest();
}
// If, after walking through the extensions we were unable to
// find a suitable StatusRequest, then stapling is disabled.
// Both statReqType and statReqData must have been set to continue.
if (type == null || req == null) {
// The ext, type and req variables must have been set to continue.
if (type == null || req == null || ext == null) {
return null;
}

@ -63,8 +63,6 @@ public class KeyStoreUtil {
// this class is not meant to be instantiated
}
private static final String JKS = "jks";
private static final Collator collator = Collator.getInstance();
static {
// this is for case insensitive string comparisons
@ -112,25 +110,25 @@ public class KeyStoreUtil {
}
}
/**
* Returns the file name of the keystore with the configured CA certificates.
*/
public static String getCacerts() {
String sep = File.separator;
return System.getProperty("java.home") + sep
+ "lib" + sep + "security" + sep
+ "cacerts";
}
/**
* Returns the keystore with the configured CA certificates.
*/
public static KeyStore getCacertsKeyStore()
throws Exception
{
String sep = File.separator;
File file = new File(System.getProperty("java.home") + sep
+ "lib" + sep + "security" + sep
+ "cacerts");
public static KeyStore getCacertsKeyStore() throws Exception {
File file = new File(getCacerts());
if (!file.exists()) {
return null;
}
KeyStore caks = null;
try (FileInputStream fis = new FileInputStream(file)) {
caks = KeyStore.getInstance(JKS);
caks.load(fis, null);
}
return caks;
return KeyStore.getInstance(file, (char[])null);
}
public static char[] getPassWithModifier(String modifier, String arg,

@ -153,6 +153,7 @@ public final class Main {
private boolean trustcacerts = false;
private boolean protectedPath = false;
private boolean srcprotectedPath = false;
private boolean cacerts = false;
private CertificateFactory cf = null;
private KeyStore caks = null; // "cacerts" keystore
private char[] srcstorePass = null;
@ -169,15 +170,15 @@ public final class Main {
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
CHANGEALIAS("Changes.an.entry.s.alias",
ALIAS, DESTALIAS, KEYPASS, KEYSTORE, STOREPASS,
ALIAS, DESTALIAS, KEYPASS, KEYSTORE, CACERTS, STOREPASS,
STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V, PROTECTED),
DELETE("Deletes.an.entry",
ALIAS, KEYSTORE, STOREPASS, STORETYPE,
ALIAS, KEYSTORE, CACERTS, STOREPASS, STORETYPE,
PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V, PROTECTED),
EXPORTCERT("Exports.certificate",
RFC, ALIAS, FILEOUT, KEYSTORE, STOREPASS,
RFC, ALIAS, FILEOUT, KEYSTORE, CACERTS, STOREPASS,
STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V, PROTECTED),
GENKEYPAIR("Generates.a.key.pair",
@ -196,7 +197,7 @@ public final class Main {
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
IMPORTCERT("Imports.a.certificate.or.a.certificate.chain",
NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
KEYPASS, KEYSTORE, CACERTS, STOREPASS, STORETYPE,
PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V),
IMPORTPASS("Imports.a.password",
@ -215,7 +216,7 @@ public final class Main {
STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V),
LIST("Lists.entries.in.a.keystore",
RFC, ALIAS, KEYSTORE, STOREPASS, STORETYPE,
RFC, ALIAS, KEYSTORE, CACERTS, STOREPASS, STORETYPE,
PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V, PROTECTED),
PRINTCERT("Prints.the.content.of.a.certificate",
@ -225,7 +226,7 @@ public final class Main {
PRINTCRL("Prints.the.content.of.a.CRL.file",
FILEIN, V),
STOREPASSWD("Changes.the.store.password.of.a.keystore",
NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
NEW, KEYSTORE, CACERTS, STOREPASS, STORETYPE, PROVIDERNAME,
ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V),
// Undocumented start here, KEYCLONE is used a marker in -help;
@ -306,6 +307,7 @@ public final class Main {
KEYPASS("keypass", "<arg>", "key.password"),
KEYSIZE("keysize", "<size>", "key.bit.size"),
KEYSTORE("keystore", "<keystore>", "keystore.name"),
CACERTS("cacerts", null, "access.the.cacerts.keystore"),
NEW("new", "<arg>", "new.password"),
NOPROMPT("noprompt", null, "do.not.prompt"),
OUTFILE("outfile", "<file>", "output.file.name"),
@ -472,14 +474,16 @@ public final class Main {
help = true;
} else if (collator.compare(flags, "-conf") == 0) {
i++;
}
/*
* specifiers
*/
else if (collator.compare(flags, "-keystore") == 0 ||
collator.compare(flags, "-destkeystore") == 0) {
} else if (collator.compare(flags, "-keystore") == 0) {
ksfname = args[++i];
if (new File(ksfname).getCanonicalPath().equals(
new File(KeyStoreUtil.getCacerts()).getCanonicalPath())) {
System.err.println(rb.getString("warning.cacerts.option"));
}
} else if (collator.compare(flags, "-destkeystore") == 0) {
ksfname = args[++i];
} else if (collator.compare(flags, "-cacerts") == 0) {
cacerts = true;
} else if (collator.compare(flags, "-storepass") == 0 ||
collator.compare(flags, "-deststorepass") == 0) {
storePass = getPass(modifier, args[++i]);
@ -636,6 +640,15 @@ public final class Main {
* Execute the commands.
*/
void doCommands(PrintStream out) throws Exception {
if (cacerts) {
if (ksfname != null || storetype != null) {
throw new IllegalArgumentException(rb.getString
("the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option"));
}
ksfname = KeyStoreUtil.getCacerts();
}
if (storetype == null) {
storetype = KeyStore.getDefaultType();
}

@ -127,6 +127,10 @@ public class Resources extends java.util.ListResourceBundle {
"key bit size"}, //-keysize
{"keystore.name",
"keystore name"}, //-keystore
{"access.the.cacerts.keystore",
"access the cacerts keystore"}, // -cacerts
{"warning.cacerts.option",
"Warning: use -cacerts option to access cacerts keystore"},
{"new.password",
"new password"}, //-new
{"do.not.prompt",
@ -194,6 +198,8 @@ public class Resources extends java.util.ListResourceBundle {
{"Command.option.flag.needs.an.argument.", "Command option {0} needs an argument."},
{"Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value.",
"Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified {0} value."},
{"the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option",
"The -keystore or -storetype option cannot be used with the -cacerts option"},
{".keystore.must.be.NONE.if.storetype.is.{0}",
"-keystore must be NONE if -storetype is {0}"},
{"Too.many.retries.program.terminated",

@ -102,24 +102,21 @@ static void checkArg(const char *arg) {
// All arguments arrive here must be a launcher argument,
// ie. by now, all argfile expansions must have been performed.
if (*arg++ == '-') {
if (*arg == '-') {
expectingNoDashArg = JNI_FALSE;
if (JLI_StrCmp(arg, "cp") == 0 ||
JLI_StrCmp(arg, "classpath") == 0 ||
JLI_StrCmp(arg, "addmods") == 0 ||
JLI_StrCmp(arg, "limitmods") == 0 ||
JLI_StrCmp(arg, "mp") == 0 ||
JLI_StrCmp(arg, "modulepath") == 0 ||
JLI_StrCmp(arg, "upgrademodulepath") == 0) {
if (IsWhiteSpaceOption(arg)) {
// expect an argument
expectingNoDashArg = JNI_TRUE;
} else if (JLI_StrCmp(arg, "jar") == 0 ||
JLI_StrCmp(arg, "m") == 0) {
// This is tricky, we do expect NoDashArg
// But that is considered main class to stop expansion
expectingNoDashArg = JNI_FALSE;
// We can not just update the idx here because if -jar @file
// still need expansion of @file to get the argument for -jar
} else if (JLI_StrCmp(arg, "Xdisable-@files") == 0) {
if (JLI_StrCmp(arg, "-jar") == 0 ||
JLI_StrCmp(arg, "-m") == 0) {
// This is tricky, we do expect NoDashArg
// But that is considered main class to stop expansion
expectingNoDashArg = JNI_FALSE;
// We can not just update the idx here because if -jar @file
// still need expansion of @file to get the argument for -jar
}
} else if (JLI_StrCmp(arg, "-Xdisable-@files") == 0) {
stopExpansion = JNI_TRUE;
}
} else {

@ -69,7 +69,7 @@ static jboolean showVersion = JNI_FALSE; /* print but continue */
static jboolean printUsage = JNI_FALSE; /* print and exit*/
static jboolean printXUsage = JNI_FALSE; /* print and exit*/
static jboolean dryRun = JNI_FALSE; /* initialize VM and exit */
static char *showSettings = NULL; /* print but continue */
static char *showSettings = NULL; /* print but continue */
static char *listModules = NULL;
static const char *_program_name;
@ -99,17 +99,9 @@ static int numOptions, maxOptions;
* Prototypes for functions internal to launcher.
*/
static void SetClassPath(const char *s);
static void SetModulePath(const char *s);
static void SetUpgradeModulePath(const char *s);
static void SetMainModule(const char *s);
static void SetAddModulesProp(const char *mods);
static void SetLimitModulesProp(const char *mods);
static void SetAddReadsProp(const jint n, const char *s);
static void SetAddExportsProp(const jint n, const char *s);
static void SetPatchProp(const jint n, const char *s);
static void SelectVersion(int argc, char **argv, char **main_class);
static void SetJvmEnvironment(int argc, char **argv);
static jboolean IsWhiteSpaceOptionArgument(const char* name);
static jboolean ParseArguments(int *pargc, char ***pargv,
int *pmode, char **pwhat,
int *pret, const char *jrepath);
@ -133,6 +125,18 @@ static void SetPaths(int argc, char **argv);
static void DumpState();
static jboolean RemovableOption(char *option);
enum OptionKind {
LAUNCHER_OPTION = 0,
LAUNCHER_OPTION_WITH_ARGUMENT,
LAUNCHER_MAIN_OPTION,
VM_LONG_OPTION,
VM_LONG_OPTION_WITH_ARGUMENT,
VM_OPTION
};
static int GetOpt(int *pargc, char ***pargv, char **poption, char **pvalue);
static jboolean IsOptionWithArgument(int argc, char **argv);
/* Maximum supported entries from jvm.cfg. */
#define INIT_MAX_KNOWN_VMS 10
@ -162,6 +166,19 @@ static int KnownVMIndex(const char* name);
static void FreeKnownVMs();
static jboolean IsWildCardEnabled();
/*
* This reports error. VM will not be created and no usage is printed.
*/
#define REPORT_ERROR(AC_ok, AC_failure_message, AC_questionable_arg) \
do { \
if (!AC_ok) { \
JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); \
printUsage = JNI_FALSE; \
*pret = 1; \
return JNI_FALSE; \
} \
} while (JNI_FALSE)
#define ARG_CHECK(AC_arg_count, AC_failure_message, AC_questionable_arg) \
do { \
if (AC_arg_count < 1) { \
@ -511,17 +528,73 @@ JavaMain(void * _args)
}
/*
* Test if the given option name has a whitespace separated argument.
* Test if the given name is one of the class path options.
*/
jboolean
IsWhiteSpaceOptionArgument(const char* name) {
static jboolean
IsClassPathOption(const char* name) {
return JLI_StrCmp(name, "-classpath") == 0 ||
JLI_StrCmp(name, "-cp") == 0 ||
JLI_StrCmp(name, "-modulepath") == 0 ||
JLI_StrCmp(name, "-mp") == 0 ||
JLI_StrCmp(name, "-upgrademodulepath") == 0 ||
JLI_StrCmp(name, "-addmods") == 0 ||
JLI_StrCmp(name, "-limitmods") == 0;
JLI_StrCmp(name, "--class-path") == 0;
}
/*
* Test if the given name is a launcher option taking the main entry point.
*/
static jboolean
IsLauncherMainOption(const char* name) {
return JLI_StrCmp(name, "--module") == 0 ||
JLI_StrCmp(name, "-m") == 0;
}
/*
* Test if the given name is a white-space launcher option.
*/
static jboolean
IsLauncherOption(const char* name) {
return IsClassPathOption(name) ||
IsLauncherMainOption(name) ||
JLI_StrCmp(name, "--list-modules") == 0;
}
#ifndef OLD_MODULE_OPTIONS
/*
* Old module options for transition
*/
static jboolean
IsOldModuleOption(const char* name) {
return JLI_StrCmp(name, "-modulepath") == 0 ||
JLI_StrCmp(name, "-mp") == 0 ||
JLI_StrCmp(name, "-upgrademodulepath") == 0 ||
JLI_StrCmp(name, "-addmods") == 0 ||
JLI_StrCmp(name, "-limitmods") == 0;
}
#endif
/*
* Test if the given name is a module-system white-space option that
* will be passed to the VM with its corresponding long-form option
* name and "=" delimiter.
*/
static jboolean
IsModuleOption(const char* name) {
return JLI_StrCmp(name, "--module-path") == 0 ||
JLI_StrCmp(name, "-p") == 0 ||
JLI_StrCmp(name, "--upgrade-module-path") == 0 ||
JLI_StrCmp(name, "--add-modules") == 0 ||
JLI_StrCmp(name, "--limit-modules") == 0 ||
JLI_StrCmp(name, "--add-exports") == 0 ||
JLI_StrCmp(name, "--add-reads") == 0 ||
JLI_StrCmp(name, "--patch-module") == 0 ||
IsOldModuleOption(name);
}
/*
* Test if the given name has a white space option.
*/
jboolean
IsWhiteSpaceOption(const char* name) {
return IsModuleOption(name) ||
IsLauncherOption(name);
}
/*
@ -559,7 +632,7 @@ CheckJvmType(int *pargc, char ***argv, jboolean speculative) {
continue;
}
} else {
if (IsWhiteSpaceOptionArgument(arg)) {
if (IsWhiteSpaceOption(arg)) {
newArgv[newArgvIdx++] = arg;
argi++;
if (argi < argc) {
@ -701,7 +774,7 @@ SetJvmEnvironment(int argc, char **argv) {
if (i > 0) {
char *prev = argv[i - 1];
// skip non-dash arg preceded by class path specifiers
if (*arg != '-' && IsWhiteSpaceOptionArgument(prev)) {
if (*arg != '-' && IsWhiteSpaceOption(prev)) {
continue;
}
@ -709,6 +782,7 @@ SetJvmEnvironment(int argc, char **argv) {
|| JLI_StrCmp(arg, "-version") == 0
|| JLI_StrCmp(arg, "-fullversion") == 0
|| JLI_StrCmp(arg, "-help") == 0
|| JLI_StrCmp(arg, "--help") == 0
|| JLI_StrCmp(arg, "-?") == 0
|| JLI_StrCmp(arg, "-jar") == 0
|| JLI_StrCmp(arg, "-X") == 0) {
@ -882,39 +956,16 @@ SetClassPath(const char *s)
}
static void
SetModulePath(const char *s)
AddLongFormOption(const char *option, const char *arg)
{
static const char format[] = "%s=%s";
char *def;
const char *orig = s;
static const char format[] = "-Djdk.module.path=%s";
if (s == NULL)
return;
s = JLI_WildcardExpandClasspath(s);
def = JLI_MemAlloc(sizeof(format)
- 2 /* strlen("%s") */
+ JLI_StrLen(s));
sprintf(def, format, s);
AddOption(def, NULL);
if (s != orig)
JLI_MemFree((char *) s);
}
size_t def_len;
static void
SetUpgradeModulePath(const char *s)
{
char *def;
const char *orig = s;
static const char format[] = "-Djdk.upgrade.module.path=%s";
if (s == NULL)
return;
s = JLI_WildcardExpandClasspath(s);
def = JLI_MemAlloc(sizeof(format)
- 2 /* strlen("%s") */
+ JLI_StrLen(s));
sprintf(def, format, s);
def_len = JLI_StrLen(option) + 1 + JLI_StrLen(arg) + 1;
def = JLI_MemAlloc(def_len);
JLI_Snprintf(def, def_len, format, option, arg);
AddOption(def, NULL);
if (s != orig)
JLI_MemFree((char *) s);
}
static void
@ -939,46 +990,6 @@ SetMainModule(const char *s)
AddOption(def, NULL);
}
static void
SetAddModulesProp(const char *mods) {
size_t buflen = JLI_StrLen(mods) + 40;
char *prop = (char *)JLI_MemAlloc(buflen);
JLI_Snprintf(prop, buflen, "-Djdk.launcher.addmods=%s", mods);
AddOption(prop, NULL);
}
static void
SetLimitModulesProp(const char *mods) {
size_t buflen = JLI_StrLen(mods) + 40;
char *prop = (char *)JLI_MemAlloc(buflen);
JLI_Snprintf(prop, buflen, "-Djdk.launcher.limitmods=%s", mods);
AddOption(prop, NULL);
}
static void
SetAddReadsProp(const jint n, const char *s) {
size_t buflen = JLI_StrLen(s) + 40;
char *prop = (char *)JLI_MemAlloc(buflen);
JLI_Snprintf(prop, buflen, "-Djdk.launcher.addreads.%d=%s", n, s);
AddOption(prop, NULL);
}
static void
SetAddExportsProp(const jint n, const char *s) {
size_t buflen = JLI_StrLen(s) + 40;
char *prop = (char *)JLI_MemAlloc(buflen);
JLI_Snprintf(prop, buflen, "-Djdk.launcher.addexports.%d=%s", n, s);
AddOption(prop, NULL);
}
static void
SetPatchProp(const jint n, const char *s) {
size_t buflen = JLI_StrLen(s) + 40;
char *prop = (char *)JLI_MemAlloc(buflen);
JLI_Snprintf(prop, buflen, "-Djdk.launcher.patch.%d=%s", n, s);
AddOption(prop, NULL);
}
/*
* The SelectVersion() routine ensures that an appropriate version of
* the JRE is running. The specification for the appropriate version
@ -1003,6 +1014,7 @@ SelectVersion(int argc, char **argv, char **main_class)
char *splash_jar_name = NULL;
char *env_in;
int res;
jboolean has_arg;
/*
* If the version has already been selected, set *main_class
@ -1033,9 +1045,11 @@ SelectVersion(int argc, char **argv, char **main_class)
* This capability is no longer available with JRE versions 1.9 and later.
* These command line options are reported as errors.
*/
argc--;
argv++;
while ((arg = *argv) != 0 && *arg == '-') {
has_arg = IsOptionWithArgument(argc, argv);
if (JLI_StrCCmp(arg, "-version:") == 0) {
JLI_ReportErrorMessage(SPC_ERROR1);
} else if (JLI_StrCmp(arg, "-jre-restrict-search") == 0) {
@ -1045,10 +1059,12 @@ SelectVersion(int argc, char **argv, char **main_class)
} else {
if (JLI_StrCmp(arg, "-jar") == 0)
jarflag = 1;
if (IsWhiteSpaceOptionArgument(arg) && (argc >= 2)) {
argc--;
argv++;
arg = *argv;
if (IsWhiteSpaceOption(arg)) {
if (has_arg) {
argc--;
argv++;
arg = *argv;
}
}
/*
@ -1139,6 +1155,108 @@ SelectVersion(int argc, char **argv, char **main_class)
}
/*
* Test if the current argv is an option, i.e. with a leading `-`
* and followed with an argument without a leading `-`.
*/
static jboolean
IsOptionWithArgument(int argc, char** argv) {
char* option;
char* arg;
if (argc <= 1)
return JNI_FALSE;
option = *argv;
arg = *(argv+1);
return *option == '-' && *arg != '-';
}
/*
* Gets the option, and its argument if the option has an argument.
* It will update *pargc, **pargv to the next option.
*/
static int
GetOpt(int *pargc, char ***pargv, char **poption, char **pvalue) {
int argc = *pargc;
char** argv = *pargv;
char* arg = *argv;
char* option = arg;
char* value = NULL;
char* equals = NULL;
int kind = LAUNCHER_OPTION;
jboolean has_arg = JNI_FALSE;
// check if this option may be a white-space option with an argument
has_arg = IsOptionWithArgument(argc, argv);
argv++; --argc;
if (IsLauncherOption(arg)) {
if (has_arg) {
value = *argv;
argv++; --argc;
}
kind = IsLauncherMainOption(arg) ? LAUNCHER_MAIN_OPTION
: LAUNCHER_OPTION_WITH_ARGUMENT;
} else if (IsModuleOption(arg)) {
kind = VM_LONG_OPTION_WITH_ARGUMENT;
if (has_arg) {
value = *argv;
argv++; --argc;
}
/*
* Support short form alias
*/
if (JLI_StrCmp(arg, "-p") == 0) {
option = "--module-path";
}
} else if (JLI_StrCCmp(arg, "--") == 0 && (equals = JLI_StrChr(arg, '=')) != NULL) {
value = equals+1;
if (JLI_StrCCmp(arg, "--list-modules=") == 0 ||
JLI_StrCCmp(arg, "--module=") == 0 ||
JLI_StrCCmp(arg, "--class-path=") == 0) {
kind = LAUNCHER_OPTION_WITH_ARGUMENT;
} else {
kind = VM_LONG_OPTION;
}
}
#ifndef OLD_MODULE_OPTIONS
// for transition to support both old and new syntax
if (JLI_StrCmp(arg, "-modulepath") == 0 ||
JLI_StrCmp(arg, "-mp") == 0) {
option = "--module-path";
} else if (JLI_StrCmp(arg, "-upgrademodulepath") == 0) {
option = "--upgrade-module-path";
} else if (JLI_StrCmp(arg, "-addmods") == 0) {
option = "--add-modules";
} else if (JLI_StrCmp(arg, "-limitmods") == 0) {
option = "--limit-modules";
} else if (JLI_StrCCmp(arg, "-XaddExports:") == 0) {
option = "--add-exports";
value = arg + 13;
kind = VM_LONG_OPTION_WITH_ARGUMENT;
} else if (JLI_StrCCmp(arg, "-XaddReads:") == 0) {
option = "--add-reads";
value = arg + 11;
kind = VM_LONG_OPTION_WITH_ARGUMENT;
} else if (JLI_StrCCmp(arg, "-Xpatch:") == 0) {
option = "--patch-module";
value = arg + 8;
kind = VM_LONG_OPTION_WITH_ARGUMENT;
}
#endif
*pargc = argc;
*pargv = argv;
*poption = option;
*pvalue = value;
return kind;
}
/*
* Parses command line arguments. Returns JNI_FALSE if launcher
* should exit without starting vm, returns JNI_TRUE if vm needs
@ -1158,52 +1276,85 @@ ParseArguments(int *pargc, char ***pargv,
*pret = 0;
while ((arg = *argv) != 0 && *arg == '-') {
argv++; --argc;
if (JLI_StrCmp(arg, "-classpath") == 0 || JLI_StrCmp(arg, "-cp") == 0) {
ARG_CHECK (argc, ARG_ERROR1, arg);
SetClassPath(*argv);
mode = LM_CLASS;
argv++; --argc;
} else if (JLI_StrCmp(arg, "-modulepath") == 0 || JLI_StrCmp(arg, "-mp") == 0) {
ARG_CHECK (argc, ARG_ERROR4, arg);
SetModulePath(*argv);
argv++; --argc;
} else if (JLI_StrCmp(arg, "-upgrademodulepath") == 0) {
ARG_CHECK (argc, ARG_ERROR4, arg);
SetUpgradeModulePath(*argv);
argv++; --argc;
} else if (JLI_StrCmp(arg, "-jar") == 0) {
ARG_CHECK (argc, ARG_ERROR2, arg);
char *option = NULL;
char *value = NULL;
int kind = GetOpt(&argc, &argv, &option, &value);
jboolean has_arg = value != NULL;
/*
* Option to set main entry point
*/
if (JLI_StrCmp(arg, "-jar") == 0) {
ARG_CHECK(argc, ARG_ERROR2, arg);
mode = LM_JAR;
} else if (JLI_StrCmp(arg, "-m") == 0) {
ARG_CHECK (argc, ARG_ERROR5, arg);
SetMainModule(*argv);
} else if (JLI_StrCmp(arg, "--module") == 0 ||
JLI_StrCCmp(arg, "--module=") == 0 ||
JLI_StrCmp(arg, "-m") == 0) {
REPORT_ERROR (has_arg, ARG_ERROR5, arg);
SetMainModule(value);
mode = LM_MODULE;
} else if (JLI_StrCmp(arg, "-addmods") == 0) {
ARG_CHECK (argc, ARG_ERROR6, arg);
SetAddModulesProp(*argv);
argv++; --argc;
} else if (JLI_StrCmp(arg, "-limitmods") == 0) {
ARG_CHECK (argc, ARG_ERROR6, arg);
SetLimitModulesProp(*argv);
argv++; --argc;
} else if (JLI_StrCmp(arg, "-listmods") == 0 ||
JLI_StrCCmp(arg, "-listmods:") == 0) {
if (has_arg) {
*pwhat = value;
break;
}
} else if (JLI_StrCmp(arg, "--class-path") == 0 ||
JLI_StrCCmp(arg, "--class-path=") == 0 ||
JLI_StrCmp(arg, "-classpath") == 0 ||
JLI_StrCmp(arg, "-cp") == 0) {
REPORT_ERROR (has_arg, ARG_ERROR1, arg);
SetClassPath(value);
mode = LM_CLASS;
} else if (JLI_StrCmp(arg, "--list-modules") == 0 ||
JLI_StrCCmp(arg, "--list-modules=") == 0) {
listModules = arg;
// set listModules to --list-modules=<module-names> if argument is specified
if (JLI_StrCmp(arg, "--list-modules") == 0 && has_arg) {
static const char format[] = "%s=%s";
size_t buflen = JLI_StrLen(option) + 2 + JLI_StrLen(value);
listModules = JLI_MemAlloc(buflen);
JLI_Snprintf(listModules, buflen, format, option, value);
}
return JNI_TRUE;
} else if (JLI_StrCCmp(arg, "-XaddReads:") == 0) {
static jint n;
char *value = arg + 11;
SetAddReadsProp(n++, value);
} else if (JLI_StrCCmp(arg, "-XaddExports:") == 0) {
static jint n;
char *value = arg + 13;
SetAddExportsProp(n++, value);
} else if (JLI_StrCCmp(arg, "-Xpatch:") == 0) {
static jint n;
char *value = arg + 8;
SetPatchProp(n++, value);
} else if (JLI_StrCmp(arg, "-help") == 0 ||
/*
* Parse white-space options
*/
} else if (has_arg) {
if (kind == VM_LONG_OPTION) {
AddOption(option, NULL);
} else if (kind == VM_LONG_OPTION_WITH_ARGUMENT) {
AddLongFormOption(option, value);
}
/*
* Error missing argument
*/
} else if (!has_arg && IsWhiteSpaceOption(arg)) {
if (JLI_StrCmp(arg, "--module-path") == 0 ||
JLI_StrCmp(arg, "-p") == 0 ||
JLI_StrCmp(arg, "--upgrade-module-path") == 0) {
REPORT_ERROR (has_arg, ARG_ERROR4, arg);
} else if (JLI_StrCmp(arg, "--add-modules") == 0 ||
JLI_StrCmp(arg, "--limit-modules") == 0 ||
JLI_StrCmp(arg, "--add-exports") == 0 ||
JLI_StrCmp(arg, "--add-reads") == 0 ||
JLI_StrCmp(arg, "--patch-module") == 0) {
REPORT_ERROR (has_arg, ARG_ERROR6, arg);
}
#ifndef OLD_MODULE_OPTIONS
else if (JLI_StrCmp(arg, "-modulepath") == 0 ||
JLI_StrCmp(arg, "-mp") == 0 ||
JLI_StrCmp(arg, "-upgrademodulepath") == 0) {
REPORT_ERROR (has_arg, ARG_ERROR4, arg);
} else if (JLI_StrCmp(arg, "-addmods") == 0 ||
JLI_StrCmp(arg, "-limitmods") == 0) {
REPORT_ERROR (has_arg, ARG_ERROR6, arg);
}
#endif
/*
* The following cases will cause the argument parsing to stop
*/
} else if (JLI_StrCmp(arg, "--help") == 0 ||
JLI_StrCmp(arg, "-help") == 0 ||
JLI_StrCmp(arg, "-h") == 0 ||
JLI_StrCmp(arg, "-?") == 0) {
printUsage = JNI_TRUE;
@ -1282,7 +1433,7 @@ ParseArguments(int *pargc, char ***pargv,
}
}
if (--argc >= 0) {
if (*pwhat == NULL && --argc >= 0) {
*pwhat = *argv++;
}
@ -1692,7 +1843,7 @@ static void
ListModules(JNIEnv *env, char *optString)
{
jmethodID listModulesID;
jstring joptString;
jstring joptString = NULL;
jclass cls = GetLauncherHelperClass(env);
NULL_CHECK(cls);
NULL_CHECK(listModulesID = (*env)->GetStaticMethodID(env, cls,

@ -161,6 +161,7 @@ void SetJavaLauncherProp(void);
jint ReadKnownVMs(const char *jvmcfg, jboolean speculative);
char *CheckJvmType(int *argc, char ***argv, jboolean speculative);
void AddOption(char *str, void *info);
jboolean IsWhiteSpaceOption(const char* name);
enum ergo_policy {
DEFAULT_POLICY = 0,

@ -26,7 +26,7 @@
#include <signal.h>
#include <stdlib.h>
double getNativeScaleFactor();
double getNativeScaleFactor(char *output_name);
#endif

@ -806,7 +806,7 @@ SplashGetScaledImageName(const char* jarName, const char* fileName,
#ifndef __linux__
return JNI_FALSE;
#endif
*scaleFactor = getNativeScaleFactor();
*scaleFactor = getNativeScaleFactor(NULL);
if (*scaleFactor == 2.0) {
size_t length = 0;
char *stringToAppend = ".java-scale2x";

@ -31,7 +31,7 @@ import java.nio.ByteBuffer;
/*
* I/O abstraction used to implement WebSocket.
*/
public interface RawChannel {
interface RawChannel {
interface RawEvent {

@ -235,8 +235,11 @@ public class Krb5InitCredential
*/
public int getInitLifetime() throws GSSException {
int retVal = 0;
retVal = (int)(getEndTime().getTime()
- (new Date().getTime()));
Date d = getEndTime();
if (d == null) {
return 0;
}
retVal = (int)(d.getTime() - (new Date().getTime()));
return retVal/1000;
}

@ -0,0 +1,324 @@
/*
* 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 sun.tools.jar;
import jdk.internal.org.objectweb.asm.*;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* A FingerPrint is an abstract representation of a JarFile entry that contains
* information to determine if the entry represents a class or a
* resource, and whether two entries are identical. If the FingerPrint represents
* a class, it also contains information to (1) describe the public API;
* (2) compare the public API of this class with another class; (3) determine
* whether or not it's a nested class and, if so, the name of the associated
* top level class; and (4) for an canonically ordered set of classes determine
* if the class versions are compatible. A set of classes is canonically
* ordered if the classes in the set have the same name, and the base class
* precedes the versioned classes and if each versioned class with version
* {@code n} precedes classes with versions {@code > n} for all versions
* {@code n}.
*/
final class FingerPrint {
private static final MessageDigest MD;
private final byte[] sha1;
private final ClassAttributes attrs;
private final boolean isClassEntry;
private final String entryName;
static {
try {
MD = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException x) {
// log big problem?
throw new RuntimeException(x);
}
}
public FingerPrint(String entryName,byte[] bytes) throws IOException {
this.entryName = entryName;
if (entryName.endsWith(".class") && isCafeBabe(bytes)) {
isClassEntry = true;
sha1 = sha1(bytes, 8); // skip magic number and major/minor version
attrs = getClassAttributes(bytes);
} else {
isClassEntry = false;
sha1 = sha1(bytes);
attrs = new ClassAttributes(); // empty class
}
}
public boolean isClass() {
return isClassEntry;
}
public boolean isNestedClass() {
return attrs.nestedClass;
}
public boolean isPublicClass() {
return attrs.publicClass;
}
public boolean isIdentical(FingerPrint that) {
if (that == null) return false;
if (this == that) return true;
return isEqual(this.sha1, that.sha1);
}
public boolean isCompatibleVersion(FingerPrint that) {
return attrs.version >= that.attrs.version;
}
public boolean isSameAPI(FingerPrint that) {
if (that == null) return false;
return attrs.equals(that.attrs);
}
public String name() {
String name = attrs.name;
return name == null ? entryName : name;
}
public String topLevelName() {
String name = attrs.topLevelName;
return name == null ? name() : name;
}
private byte[] sha1(byte[] entry) {
MD.update(entry);
return MD.digest();
}
private byte[] sha1(byte[] entry, int offset) {
MD.update(entry, offset, entry.length - offset);
return MD.digest();
}
private boolean isEqual(byte[] sha1_1, byte[] sha1_2) {
return MessageDigest.isEqual(sha1_1, sha1_2);
}
private static final byte[] cafeBabe = {(byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe};
private boolean isCafeBabe(byte[] bytes) {
if (bytes.length < 4) return false;
for (int i = 0; i < 4; i++) {
if (bytes[i] != cafeBabe[i]) {
return false;
}
}
return true;
}
private ClassAttributes getClassAttributes(byte[] bytes) {
ClassReader rdr = new ClassReader(bytes);
ClassAttributes attrs = new ClassAttributes();
rdr.accept(attrs, 0);
return attrs;
}
private static final class Field {
private final int access;
private final String name;
private final String desc;
Field(int access, String name, String desc) {
this.access = access;
this.name = name;
this.desc = desc;
}
@Override
public boolean equals(Object that) {
if (that == null) return false;
if (this == that) return true;
if (!(that instanceof Field)) return false;
Field field = (Field)that;
return (access == field.access) && name.equals(field.name)
&& desc.equals(field.desc);
}
@Override
public int hashCode() {
int result = 17;
result = 37 * result + access;
result = 37 * result + name.hashCode();
result = 37 * result + desc.hashCode();
return result;
}
}
private static final class Method {
private final int access;
private final String name;
private final String desc;
private final Set<String> exceptions;
Method(int access, String name, String desc, Set<String> exceptions) {
this.access = access;
this.name = name;
this.desc = desc;
this.exceptions = exceptions;
}
@Override
public boolean equals(Object that) {
if (that == null) return false;
if (this == that) return true;
if (!(that instanceof Method)) return false;
Method method = (Method)that;
return (access == method.access) && name.equals(method.name)
&& desc.equals(method.desc)
&& exceptions.equals(method.exceptions);
}
@Override
public int hashCode() {
int result = 17;
result = 37 * result + access;
result = 37 * result + name.hashCode();
result = 37 * result + desc.hashCode();
result = 37 * result + exceptions.hashCode();
return result;
}
}
private static final class ClassAttributes extends ClassVisitor {
private String name;
private String topLevelName;
private String superName;
private int version;
private int access;
private boolean publicClass;
private boolean nestedClass;
private final Set<Field> fields = new HashSet<>();
private final Set<Method> methods = new HashSet<>();
public ClassAttributes() {
super(Opcodes.ASM5);
}
private boolean isPublic(int access) {
return ((access & Opcodes.ACC_PUBLIC) == Opcodes.ACC_PUBLIC)
|| ((access & Opcodes.ACC_PROTECTED) == Opcodes.ACC_PROTECTED);
}
@Override
public void visit(int version, int access, String name, String signature,
String superName, String[] interfaces) {
this.version = version;
this.access = access;
this.name = name;
this.nestedClass = name.contains("$");
this.superName = superName;
this.publicClass = isPublic(access);
}
@Override
public void visitOuterClass(String owner, String name, String desc) {
if (!this.nestedClass) return;
this.topLevelName = owner;
}
@Override
public void visitInnerClass(String name, String outerName, String innerName,
int access) {
if (!this.nestedClass) return;
if (outerName == null) return;
if (!this.name.equals(name)) return;
if (this.topLevelName == null) this.topLevelName = outerName;
}
@Override
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
if (isPublic(access)) {
fields.add(new Field(access, name, desc));
}
return null;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
if (isPublic(access)) {
Set<String> exceptionSet = new HashSet<>();
if (exceptions != null) {
for (String e : exceptions) {
exceptionSet.add(e);
}
}
// treat type descriptor as a proxy for signature because signature
// is usually null, need to strip off the return type though
int n;
if (desc != null && (n = desc.lastIndexOf(')')) != -1) {
desc = desc.substring(0, n + 1);
methods.add(new Method(access, name, desc, exceptionSet));
}
}
return null;
}
@Override
public void visitEnd() {
this.nestedClass = this.topLevelName != null;
}
@Override
public boolean equals(Object that) {
if (that == null) return false;
if (this == that) return true;
if (!(that instanceof ClassAttributes)) return false;
ClassAttributes clsAttrs = (ClassAttributes)that;
boolean superNameOkay = superName != null
? superName.equals(clsAttrs.superName) : true;
return access == clsAttrs.access
&& superNameOkay
&& fields.equals(clsAttrs.fields)
&& methods.equals(clsAttrs.methods);
}
@Override
public int hashCode() {
int result = 17;
result = 37 * result + access;
result = 37 * result + superName != null ? superName.hashCode() : 0;
result = 37 * result + fields.hashCode();
result = 37 * result + methods.hashCode();
return result;
}
}
}

@ -91,7 +91,7 @@ class GNUStyleOptions {
tool.xflag = true;
}
},
new Option(false, OptionType.MAIN_OPERATION, "--print-module-descriptor", "-p") {
new Option(false, OptionType.MAIN_OPERATION, "--print-module-descriptor", "-d") {
void process(Main tool, String opt, String arg) throws BadArgs {
if (tool.cflag || tool.iflag || tool.tflag || tool.uflag || tool.xflag)
throw new BadArgs("error.multiple.main.operations").showUsage(true);
@ -145,7 +145,7 @@ class GNUStyleOptions {
}
}
},
new Option(true, OptionType.CREATE_UPDATE, "--modulepath", "--mp") {
new Option(true, OptionType.CREATE_UPDATE, "--module-path", "-p") {
void process(Main jartool, String opt, String arg) {
String[] dirs = arg.split(File.pathSeparator);
Path[] paths = new Path[dirs.length];

@ -42,6 +42,7 @@ import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
@ -278,23 +279,20 @@ class Main {
}
}
}
if (cflag) {
Manifest manifest = null;
InputStream in = null;
if (!Mflag) {
if (mname != null) {
in = new FileInputStream(mname);
manifest = new Manifest(new BufferedInputStream(in));
try (InputStream in = new FileInputStream(mname)) {
manifest = new Manifest(new BufferedInputStream(in));
}
} else {
manifest = new Manifest();
}
addVersion(manifest);
addCreatedBy(manifest);
if (isAmbiguousMainClass(manifest)) {
if (in != null) {
in.close();
}
return false;
}
if (ename != null) {
@ -304,11 +302,13 @@ class Main {
addMultiRelease(manifest);
}
}
Map<String,Path> moduleInfoPaths = new HashMap<>();
for (int version : filesMap.keySet()) {
String[] files = filesMap.get(version);
expand(null, files, false, moduleInfoPaths, version);
}
Map<String,byte[]> moduleInfos = new LinkedHashMap<>();
if (!moduleInfoPaths.isEmpty()) {
if (!checkModuleInfos(moduleInfoPaths))
@ -332,84 +332,61 @@ class Main {
return false;
}
OutputStream out;
if (fname != null) {
out = new FileOutputStream(fname);
} else {
out = new FileOutputStream(FileDescriptor.out);
if (vflag) {
// Disable verbose output so that it does not appear
// on stdout along with file data
// error("Warning: -v option ignored");
vflag = false;
}
if (vflag && fname == null) {
// Disable verbose output so that it does not appear
// on stdout along with file data
// error("Warning: -v option ignored");
vflag = false;
}
File tmpfile = null;
final OutputStream finalout = out;
final String tmpbase = (fname == null)
? "tmpjar"
: fname.substring(fname.indexOf(File.separatorChar) + 1);
if (nflag) {
tmpfile = createTemporaryFile(tmpbase, ".jar");
out = new FileOutputStream(tmpfile);
}
create(new BufferedOutputStream(out, 4096), manifest, moduleInfos);
File tmpfile = createTemporaryFile(tmpbase, ".jar");
if (in != null) {
in.close();
try (OutputStream out = new FileOutputStream(tmpfile)) {
create(new BufferedOutputStream(out, 4096), manifest, moduleInfos);
}
out.close();
if (nflag) {
JarFile jarFile = null;
File packFile = null;
JarOutputStream jos = null;
File packFile = createTemporaryFile(tmpbase, ".pack");
try {
Packer packer = Pack200.newPacker();
Map<String, String> p = packer.properties();
p.put(Packer.EFFORT, "1"); // Minimal effort to conserve CPU
jarFile = new JarFile(tmpfile.getCanonicalPath());
packFile = createTemporaryFile(tmpbase, ".pack");
out = new FileOutputStream(packFile);
packer.pack(jarFile, out);
jos = new JarOutputStream(finalout);
Unpacker unpacker = Pack200.newUnpacker();
unpacker.unpack(packFile, jos);
} catch (IOException ioe) {
fatalError(ioe);
} finally {
if (jarFile != null) {
jarFile.close();
try (
JarFile jarFile = new JarFile(tmpfile.getCanonicalPath());
OutputStream pack = new FileOutputStream(packFile)
) {
packer.pack(jarFile, pack);
}
if (out != null) {
out.close();
}
if (jos != null) {
jos.close();
}
if (tmpfile != null && tmpfile.exists()) {
if (tmpfile.exists()) {
tmpfile.delete();
}
if (packFile != null && packFile.exists()) {
packFile.delete();
tmpfile = createTemporaryFile(tmpbase, ".jar");
try (
OutputStream out = new FileOutputStream(tmpfile);
JarOutputStream jos = new JarOutputStream(out)
) {
Unpacker unpacker = Pack200.newUnpacker();
unpacker.unpack(packFile, jos);
}
} finally {
Files.deleteIfExists(packFile.toPath());
}
}
validateAndClose(tmpfile);
} else if (uflag) {
File inputFile = null, tmpFile = null;
FileInputStream in;
FileOutputStream out;
if (fname != null) {
inputFile = new File(fname);
tmpFile = createTempFileInSameDirectoryAs(inputFile);
in = new FileInputStream(inputFile);
out = new FileOutputStream(tmpFile);
} else {
in = new FileInputStream(FileDescriptor.in);
out = new FileOutputStream(FileDescriptor.out);
vflag = false;
tmpFile = createTemporaryFile("tmpjar", ".jar");
}
InputStream manifest = (!Mflag && (mname != null)) ?
(new FileInputStream(mname)) : null;
Map<String,Path> moduleInfoPaths = new HashMap<>();
for (int version : filesMap.keySet()) {
@ -421,8 +398,19 @@ class Main {
for (Map.Entry<String,Path> e : moduleInfoPaths.entrySet())
moduleInfos.put(e.getKey(), readModuleInfo(e.getValue()));
boolean updateOk = update(in, new BufferedOutputStream(out),
manifest, moduleInfos, null);
try (
FileInputStream in = (fname != null) ? new FileInputStream(inputFile)
: new FileInputStream(FileDescriptor.in);
FileOutputStream out = new FileOutputStream(tmpFile);
InputStream manifest = (!Mflag && (mname != null)) ?
(new FileInputStream(mname)) : null;
) {
boolean updateOk = update(in, new BufferedOutputStream(out),
manifest, moduleInfos, null);
if (ok) {
ok = updateOk;
}
}
// Consistency checks for modular jars.
if (!moduleInfos.isEmpty()) {
@ -430,23 +418,8 @@ class Main {
return false;
}
if (ok) {
ok = updateOk;
}
in.close();
out.close();
if (manifest != null) {
manifest.close();
}
if (ok && fname != null) {
// on Win32, we need this delete
inputFile.delete();
if (!tmpFile.renameTo(inputFile)) {
tmpFile.delete();
throw new IOException(getMsg("error.write.file"));
}
tmpFile.delete();
}
validateAndClose(tmpFile);
} else if (tflag) {
replaceFSC(filesMap);
// For the "list table contents" action, access using the
@ -520,6 +493,28 @@ class Main {
return ok;
}
private void validateAndClose(File tmpfile) throws IOException {
if (ok && isMultiRelease) {
ok = validate(tmpfile.getCanonicalPath());
if (!ok) {
error(formatMsg("error.validator.jarfile.invalid", fname));
}
}
Path path = tmpfile.toPath();
try {
if (ok) {
if (fname != null) {
Files.move(path, Paths.get(fname), StandardCopyOption.REPLACE_EXISTING);
} else {
Files.copy(path, new FileOutputStream(FileDescriptor.out));
}
}
} finally {
Files.deleteIfExists(path);
}
}
private String[] filesMapToFiles(Map<Integer,String[]> filesMap) {
if (filesMap.isEmpty()) return null;
return filesMap.entrySet()
@ -534,6 +529,76 @@ class Main {
.map(f -> (new EntryName(f, version)).entryName);
}
// sort base entries before versioned entries, and sort entry classes with
// nested classes so that the top level class appears before the associated
// nested class
private Comparator<JarEntry> entryComparator = (je1, je2) -> {
String s1 = je1.getName();
String s2 = je2.getName();
if (s1.equals(s2)) return 0;
boolean b1 = s1.startsWith(VERSIONS_DIR);
boolean b2 = s2.startsWith(VERSIONS_DIR);
if (b1 && !b2) return 1;
if (!b1 && b2) return -1;
int n = 0; // starting char for String compare
if (b1 && b2) {
// normally strings would be sorted so "10" goes before "9", but
// version number strings need to be sorted numerically
n = VERSIONS_DIR.length(); // skip the common prefix
int i1 = s1.indexOf('/', n);
int i2 = s1.indexOf('/', n);
if (i1 == -1) throw new InvalidJarException(s1);
if (i2 == -1) throw new InvalidJarException(s2);
// shorter version numbers go first
if (i1 != i2) return i1 - i2;
// otherwise, handle equal length numbers below
}
int l1 = s1.length();
int l2 = s2.length();
int lim = Math.min(l1, l2);
for (int k = n; k < lim; k++) {
char c1 = s1.charAt(k);
char c2 = s2.charAt(k);
if (c1 != c2) {
// change natural ordering so '.' comes before '$'
// i.e. top level classes come before nested classes
if (c1 == '$' && c2 == '.') return 1;
if (c1 == '.' && c2 == '$') return -1;
return c1 - c2;
}
}
return l1 - l2;
};
private boolean validate(String fname) {
boolean valid;
try (JarFile jf = new JarFile(fname)) {
Validator validator = new Validator(this, jf);
jf.stream()
.filter(e -> !e.isDirectory())
.filter(e -> !e.getName().equals(MANIFEST_NAME))
.filter(e -> !e.getName().endsWith(MODULE_INFO))
.sorted(entryComparator)
.forEachOrdered(validator);
valid = validator.isValid();
} catch (IOException e) {
error(formatMsg2("error.validator.jarfile.exception", fname, e.getMessage()));
valid = false;
} catch (InvalidJarException e) {
error(formatMsg("error.validator.bad.entry.name", e.getMessage()));
valid = false;
}
return valid;
}
private static class InvalidJarException extends RuntimeException {
private static final long serialVersionUID = -3642329147299217726L;
InvalidJarException(String msg) {
super(msg);
}
}
/**
* Parses command line arguments.
*/

@ -0,0 +1,242 @@
/*
* 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 sun.tools.jar;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
final class Validator implements Consumer<JarEntry> {
private final static boolean DEBUG = Boolean.getBoolean("jar.debug");
private final Map<String,FingerPrint> fps = new HashMap<>();
private final int vdlen = Main.VERSIONS_DIR.length();
private final Main main;
private final JarFile jf;
private int oldVersion = -1;
private String currentTopLevelName;
private boolean isValid = true;
Validator(Main main, JarFile jf) {
this.main = main;
this.jf = jf;
}
boolean isValid() {
return isValid;
}
/*
* Validator has state and assumes entries provided to accept are ordered
* from base entries first and then through the versioned entries in
* ascending version order. Also, to find isolated nested classes,
* classes must be ordered so that the top level class is before the associated
* nested class(es).
*/
public void accept(JarEntry je) {
String entryName = je.getName();
// directories are always accepted
if (entryName.endsWith("/")) {
debug("%s is a directory", entryName);
return;
}
// figure out the version and basename from the JarEntry
int version;
String basename;
if (entryName.startsWith(Main.VERSIONS_DIR)) {
int n = entryName.indexOf("/", vdlen);
if (n == -1) {
main.error(Main.formatMsg("error.validator.version.notnumber", entryName));
isValid = false;
return;
}
String v = entryName.substring(vdlen, n);
try {
version = Integer.parseInt(v);
} catch (NumberFormatException x) {
main.error(Main.formatMsg("error.validator.version.notnumber", entryName));
isValid = false;
return;
}
if (n == entryName.length()) {
main.error(Main.formatMsg("error.validator.entryname.tooshort", entryName));
isValid = false;
return;
}
basename = entryName.substring(n + 1);
} else {
version = 0;
basename = entryName;
}
debug("\n===================\nversion %d %s", version, entryName);
if (oldVersion != version) {
oldVersion = version;
currentTopLevelName = null;
}
// analyze the entry, keeping key attributes
FingerPrint fp;
try (InputStream is = jf.getInputStream(je)) {
fp = new FingerPrint(basename, is.readAllBytes());
} catch (IOException x) {
main.error(x.getMessage());
isValid = false;
return;
}
String internalName = fp.name();
// process a base entry paying attention to nested classes
if (version == 0) {
debug("base entry found");
if (fp.isNestedClass()) {
debug("nested class found");
if (fp.topLevelName().equals(currentTopLevelName)) {
fps.put(internalName, fp);
return;
}
main.error(Main.formatMsg("error.validator.isolated.nested.class", entryName));
isValid = false;
return;
}
// top level class or resource entry
if (fp.isClass()) {
currentTopLevelName = fp.topLevelName();
if (!checkInternalName(entryName, basename, internalName)) {
isValid = false;
return;
}
}
fps.put(internalName, fp);
return;
}
// process a versioned entry, look for previous entry with same name
FingerPrint matchFp = fps.get(internalName);
debug("looking for match");
if (matchFp == null) {
debug("no match found");
if (fp.isClass()) {
if (fp.isNestedClass()) {
if (!checkNestedClass(version, entryName, internalName, fp)) {
isValid = false;
}
return;
}
if (fp.isPublicClass()) {
main.error(Main.formatMsg("error.validator.new.public.class", entryName));
isValid = false;
return;
}
debug("%s is a non-public class entry", entryName);
fps.put(internalName, fp);
currentTopLevelName = fp.topLevelName();
return;
}
debug("%s is a resource entry");
fps.put(internalName, fp);
return;
}
debug("match found");
// are the two classes/resources identical?
if (fp.isIdentical(matchFp)) {
main.error(Main.formatMsg("error.validator.identical.entry", entryName));
return; // it's okay, just takes up room
}
debug("sha1 not equal -- different bytes");
// ok, not identical, check for compatible class version and api
if (fp.isClass()) {
if (fp.isNestedClass()) {
if (!checkNestedClass(version, entryName, internalName, fp)) {
isValid = false;
}
return;
}
debug("%s is a class entry", entryName);
if (!fp.isCompatibleVersion(matchFp)) {
main.error(Main.formatMsg("error.validator.incompatible.class.version", entryName));
isValid = false;
return;
}
if (!fp.isSameAPI(matchFp)) {
main.error(Main.formatMsg("error.validator.different.api", entryName));
isValid = false;
return;
}
if (!checkInternalName(entryName, basename, internalName)) {
isValid = false;
return;
}
debug("fingerprints same -- same api");
fps.put(internalName, fp);
currentTopLevelName = fp.topLevelName();
return;
}
debug("%s is a resource", entryName);
main.error(Main.formatMsg("error.validator.resources.with.same.name", entryName));
fps.put(internalName, fp);
return;
}
private boolean checkInternalName(String entryName, String basename, String internalName) {
String className = className(basename);
if (internalName.equals(className)) {
return true;
}
main.error(Main.formatMsg2("error.validator.names.mismatch",
entryName, internalName.replace("/", ".")));
return false;
}
private boolean checkNestedClass(int version, String entryName, String internalName, FingerPrint fp) {
debug("%s is a nested class entry in top level class %s", entryName, fp.topLevelName());
if (fp.topLevelName().equals(currentTopLevelName)) {
debug("%s (top level class) was accepted", fp.topLevelName());
fps.put(internalName, fp);
return true;
}
debug("top level class was not accepted");
main.error(Main.formatMsg("error.validator.isolated.nested.class", entryName));
return false;
}
private String className(String entryName) {
return entryName.endsWith(".class") ? entryName.substring(0, entryName.length() - 6) : null;
}
private void debug(String fmt, Object... args) {
if (DEBUG) System.err.format(fmt, args);
}
}

@ -85,6 +85,30 @@ error.release.value.notnumber=\
release {0} not valid
error.release.value.toosmall=\
release {0} not valid, must be >= 9
error.validator.jarfile.exception=\
can not validate {0}: {1}
error.validator.jarfile.invalid=\
invalid multi-release jar file {0} deleted
error.validator.bad.entry.name=\
entry name malformed, {0}
error.validator.version.notnumber=\
entry name: {0}, does not have a version number
error.validator.entryname.tooshort=\
entry name: {0}, too short, not a directory
error.validator.isolated.nested.class=\
entry: {0}, is an isolated nested class
error.validator.new.public.class=\
entry: {0}, contains a new public class not found in base entries
error.validator.identical.entry=\
warning - entry: {0} contains a class that is identical to an entry already in the jar
error.validator.incompatible.class.version=\
entry: {0}, has a class version incompatible with an earlier version
error.validator.different.api=\
entry: {0}, contains a class with different api from earlier version
error.validator.resources.with.same.name=\
warning - entry: {0}, multiple resources with same name
error.validator.names.mismatch=\
entry: {0}, contains a class with internal name {1}, names do not match
out.added.manifest=\
added manifest
out.added.module-info=\
@ -177,7 +201,7 @@ main.help.opt.main.update=\
main.help.opt.main.extract=\
\ -x, --extract Extract named (or all) files from the archive
main.help.opt.main.print-module-descriptor=\
\ -p, --print-module-descriptor Print the module descriptor
\ -d, --print-module-descriptor Print the module descriptor
main.help.opt.any=\
\ Operation modifiers valid in any mode:\n\
\n\
@ -208,8 +232,8 @@ main.help.opt.create.update.hash-modules=\
\ matched by the given pattern and that depend upon\n\
\ directly or indirectly on a modular jar being\n\
\ created or a non-modular jar being updated
main.help.opt.create.update.modulepath=\
\ --modulepath Location of module dependence for generating
main.help.opt.create.update.module-path=\
\ -p, --module-path Location of module dependence for generating\n\
\ the hash
main.help.opt.create.update.index=\
\ Operation modifiers valid only in create, update, and generate-index mode:\n
@ -226,7 +250,7 @@ main.help.postopt=\
\ located in the root of the given directories, or the root of the jar archive\n\
\ itself. The following operations are only valid when creating a modular jar,\n\
\ or updating an existing non-modular jar: '--module-version',\n\
\ '--hash-modules', and '--modulepath'.\n\
\ '--hash-modules', and '--module-path'.\n\
\n\
\ Mandatory or optional arguments to long options are also mandatory or optional\n\
\ for any corresponding short options.
\ for any corresponding short options.

@ -61,11 +61,11 @@ class JImageTask {
new Option<JImageTask>(false, (task, option, arg) -> {
task.options.fullVersion = true;
}, true, "--fullversion"),
}, true, "--full-version"),
new Option<JImageTask>(false, (task, option, arg) -> {
task.options.help = true;
}, "--help"),
}, "--help", "-h"),
new Option<JImageTask>(false, (task, option, arg) -> {
task.options.verbose = true;

@ -25,7 +25,7 @@
main.usage.summary=\
Usage: {0} <extract | info | list | verify> <options> jimage...\n\
use --help for a list of possible options.
use -h or --help for a list of possible options.
main.usage=\
Usage: {0} <extract | info | list | verify> <options> jimage...\n\
@ -76,11 +76,11 @@ main.opt.footer=\
\ used, one pattern per line\n\
main.opt.fullversion=\
\ --fullversion Print full version information
main.opt.full-version=\
\ --full-version Print full version information
main.opt.help=\
\ --help Print usage message
\ -h, --help Print usage message
main.opt.verbose=\
\ --verbose Listing prints entry size and offset attributes

@ -84,31 +84,32 @@ public class JlinkTask {
private static final Option<?>[] recognizedOptions = {
new Option<JlinkTask>(false, (task, opt, arg) -> {
task.options.help = true;
}, "--help"),
}, "--help", "-h"),
new Option<JlinkTask>(true, (task, opt, arg) -> {
String[] dirs = arg.split(File.pathSeparator);
int i = 0;
Arrays.stream(dirs)
.map(Paths::get)
.forEach(task.options.modulePath::add);
}, "--modulepath", "--mp"),
}, "--module-path", "-p"),
new Option<JlinkTask>(true, (task, opt, arg) -> {
for (String mn : arg.split(",")) {
if (mn.isEmpty()) {
throw taskHelper.newBadArgs("err.mods.must.be.specified",
"--limitmods");
"--limit-modules");
}
task.options.limitMods.add(mn);
}
}, "--limitmods"),
}, "--limit-modules"),
new Option<JlinkTask>(true, (task, opt, arg) -> {
for (String mn : arg.split(",")) {
if (mn.isEmpty()) {
throw taskHelper.newBadArgs("err.mods.must.be.specified",
"--addmods");
"--add-modules");
}
task.options.addMods.add(mn);
}
}, "--addmods"),
}, "--add-modules"),
new Option<JlinkTask>(true, (task, opt, arg) -> {
Path path = Paths.get(arg);
task.options.output = path;
@ -134,10 +135,10 @@ public class JlinkTask {
}, true, "--keep-packaged-modules"),
new Option<JlinkTask>(true, (task, opt, arg) -> {
task.options.saveoptsfile = arg;
}, "--saveopts"),
}, "--save-opts"),
new Option<JlinkTask>(false, (task, opt, arg) -> {
task.options.fullVersion = true;
}, true, "--fullversion"),};
}, true, "--full-version"),};
private static final String PROGNAME = "jlink";
private final OptionsValues options = new OptionsValues();
@ -294,7 +295,7 @@ public class JlinkTask {
try {
options.addMods = checkAddMods(options.addMods);
} catch (IllegalArgumentException ex) {
throw taskHelper.newBadArgs("err.mods.must.be.specified", "--addmods")
throw taskHelper.newBadArgs("err.mods.must.be.specified", "--add-modules")
.showUsage(true);
}
// First create the image provider

@ -196,7 +196,7 @@ public final class TaskHelper {
// This option is handled prior
// to have the options parsed.
},
"--plugins-modulepath"));
"--plugin-module-path"));
mainOptions.add(new PlugOption(true, (task, opt, arg) -> {
Path path = Paths.get(arg);
if (!Files.exists(path) || !Files.isDirectory(path)) {

@ -25,7 +25,6 @@
package jdk.tools.jlink.internal.plugins;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
@ -33,6 +32,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.JavaLangInvokeAccess;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ResourcePool;
@ -54,9 +55,6 @@ public final class GenerateJLIClassesPlugin implements Plugin {
private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME);
private static final String BMH = "java/lang/invoke/BoundMethodHandle";
private static final Method BMH_FACTORY_METHOD;
private static final String DMH = "java/lang/invoke/DirectMethodHandle$Holder";
private static final String DMH_INVOKE_VIRTUAL = "invokeVirtual";
private static final String DMH_INVOKE_STATIC = "invokeStatic";
@ -64,7 +62,9 @@ public final class GenerateJLIClassesPlugin implements Plugin {
private static final String DMH_NEW_INVOKE_SPECIAL = "newInvokeSpecial";
private static final String DMH_INVOKE_INTERFACE = "invokeInterface";
private static final String DMH_INVOKE_STATIC_INIT = "invokeStaticInit";
private static final Method DMH_FACTORY_METHOD;
private static final JavaLangInvokeAccess JLIA
= SharedSecrets.getJavaLangInvokeAccess();
List<String> speciesTypes;
@ -232,8 +232,8 @@ public final class GenerateJLIClassesPlugin implements Plugin {
private void generateBMHClass(String types, ResourcePoolBuilder out) {
try {
// Generate class
Map.Entry<String, byte[]> result = (Map.Entry<String, byte[]>)
BMH_FACTORY_METHOD.invoke(null, types);
Map.Entry<String, byte[]> result =
JLIA.generateConcreteBMHClassBytes(types);
String className = result.getKey();
byte[] bytes = result.getValue();
@ -264,11 +264,8 @@ public final class GenerateJLIClassesPlugin implements Plugin {
}
}
try {
byte[] bytes = (byte[])DMH_FACTORY_METHOD
.invoke(null,
DMH,
methodTypes,
dmhTypes);
byte[] bytes =
JLIA.generateDMHClassBytes(DMH, methodTypes, dmhTypes);
ResourcePoolEntry ndata = ResourcePoolEntry.create(DMH_ENTRY, bytes);
out.add(ndata);
} catch (Exception ex) {
@ -277,22 +274,6 @@ public final class GenerateJLIClassesPlugin implements Plugin {
}
private static final String DMH_ENTRY = "/java.base/" + DMH + ".class";
static {
try {
Class<?> BMHFactory = Class.forName("java.lang.invoke.BoundMethodHandle$Factory");
BMH_FACTORY_METHOD = BMHFactory.getDeclaredMethod("generateConcreteBMHClassBytes",
String.class);
BMH_FACTORY_METHOD.setAccessible(true);
Class<?> DMHFactory = Class.forName("java.lang.invoke.DirectMethodHandle");
DMH_FACTORY_METHOD = DMHFactory.getDeclaredMethod("generateDMHClassBytes",
String.class, MethodType[].class, int[].class);
DMH_FACTORY_METHOD.setAccessible(true);
} catch (Exception e) {
throw new PluginException(e);
}
}
// Convert LL -> LL, L3 -> LLL
private static String expandSignature(String signature) {
StringBuilder sb = new StringBuilder();

@ -24,30 +24,31 @@
#
main.usage.summary=\
Usage: {0} <options> --modulepath <modulepath> --addmods <mods> --output <path>\n\
Usage: {0} <options> --module-path <modulepath> --add-modules <mods> --output <path>\n\
use --help for a list of possible options
main.usage=\
Usage: {0} <options> --modulepath <modulepath> --addmods <mods> --output <path>\n\
Usage: {0} <options> --module-path <modulepath> --add-modules <mods> --output <path>\n\
\Possible options include:
error.prefix=Error:
warn.prefix=Warning:
main.opt.help=\
\ --help Print this help message
\ -h, --help Print this help message
main.opt.version=\
\ --version Version information
main.opt.modulepath=\
\ --modulepath <modulepath> Module path
main.opt.module-path=\
\ -p <modulepath>\n\
\ --module-path <modulepath> Module path
main.opt.addmods=\
\ --addmods <mod>[,<mod>...] Root modules to resolve
main.opt.add-modules=\
\ --add-modules <mod>[,<mod>...] Root modules to resolve
main.opt.limitmods=\
\ --limitmods <mod>[,<mod>...] Limit the universe of observable modules
main.opt.limit-modules=\
\ --limit-modules <mod>[,<mod>...] Limit the universe of observable modules
main.opt.output=\
\ --output <path> Location of output path
@ -58,8 +59,8 @@ main.command.files=\
main.opt.endian=\
\ --endian <little|big> Byte order of generated jimage (default:native)
main.opt.saveopts=\
\ --saveopts <filename> Save jlink options in the given file
main.opt.save-opts=\
\ --save-opts <filename> Save jlink options in the given file
main.msg.bug=\
An exception has occurred in jlink. \
@ -83,7 +84,7 @@ main.extended.help.footer=\
err.unknown.byte.order:unknown byte order {0}
err.output.must.be.specified:--output must be specified
err.modulepath.must.be.specified:--modulepath must be specified
err.modulepath.must.be.specified:--module-path must be specified
err.mods.must.be.specified:no modules specified to {0}
err.path.not.found=path not found: {0}
err.path.not.valid=invalid path: {0}

@ -115,7 +115,7 @@ include-locales.invalidtag=\
Invalid language tag: %s
include-locales.localedatanotfound=\
jdk.localedata module was not specified with --addmods option
jdk.localedata module was not specified with --add-modules option
main.status.ok=Functional.
@ -133,8 +133,8 @@ plugin.opt.post-process-path=\
plugin.opt.resources-last-sorter=\
\ --resources-last-sorter <name> The last plugin allowed to sort resources
plugin.opt.plugins-modulepath=\
\ --plugin-module-path <modulepath> Custom plugins module path
plugin.opt.plugin-module-path=\
\ --plugin-module-path <modulepath> Custom plugin module path
plugin.opt.c=\
\ -c, --compress=2 Enable compression of resources (level 2)

@ -1181,7 +1181,7 @@ public class JmodTask {
}
}
private final OptionParser parser = new OptionParser();
private final OptionParser parser = new OptionParser("hp");
private void handleOptions(String[] args) {
parser.formatHelpWith(new JmodHelpFormatter());
@ -1218,7 +1218,7 @@ public class JmodTask {
.withValuesConvertedBy(new PatternConverter());
OptionSpec<Void> help
= parser.accepts("help", getMessage("main.opt.help"))
= parser.acceptsAll(Set.of("h", "help"), getMessage("main.opt.help"))
.forHelp();
OptionSpec<Path> libs
@ -1232,9 +1232,9 @@ public class JmodTask {
.withRequiredArg()
.describedAs(getMessage("main.opt.main-class.arg"));
OptionSpec<Path> modulePath // TODO: short version of --mp ??
= parser.acceptsAll(Arrays.asList("mp", "modulepath"),
getMessage("main.opt.modulepath"))
OptionSpec<Path> modulePath
= parser.acceptsAll(Set.of("p", "module-path"),
getMessage("main.opt.module-path"))
.withRequiredArg()
.withValuesSeparatedBy(File.pathSeparatorChar)
.withValuesConvertedBy(DirPathConverter.INSTANCE);

@ -63,7 +63,7 @@ main.opt.os-arch=Operating system architecture
main.opt.os-arch.arg=os-arch
main.opt.os-version=Operating system version
main.opt.os-version.arg=os-version
main.opt.modulepath=Module path
main.opt.module-path=Module path
main.opt.hash-modules=Compute and record hashes to tie a packaged module\
\ with modules matching the given <regex-pattern> and depending upon it directly\
\ or indirectly. The hashes are recorded in the JMOD file being created, or\

@ -343,6 +343,9 @@ com/sun/jdi/GetLocalVariables4Test.sh 8067354 windows-
com/sun/jdi/sde/SourceDebugExtensionTest.java 8158066 windows-all
com/sun/jdi/ClassesByName2Test.java 8160833 generic-all
com/sun/jdi/RedefineCrossEvent.java 8160833 generic-all
############################################################################
# jdk_time

@ -26,12 +26,12 @@ groups=TEST.groups [closed/TEST.groups]
# Allow querying of various System properties in @requires clauses
requires.properties=sun.arch.data.model java.runtime.name
# Tests using jtreg 4.2 b02 features
requiredVersion=4.2 b02
# Tests using jtreg 4.2 b03 features
requiredVersion=4.2 b03
# Path to libraries in the topmost test directory. This is needed so @library
# does not need ../../ notation to reach them
external.lib.roots = ../../
# Use new form of -Xpatch
useNewXpatch=true
# Use new module options
useNewOptions=true

@ -81,9 +81,9 @@ cp ${TESTSRC}${FS}JavaBug.java bug
chmod -fR 777 bug
${COMPILEJAVA}${FS}bin${FS}javac -addmods java.corba -d . bug${FS}*.java
${COMPILEJAVA}${FS}bin${FS}javac --add-modules java.corba -d . bug${FS}*.java
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -addmods java.corba -cp . bug/JavaBug > test.out 2>&1
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} --add-modules java.corba -cp . bug/JavaBug > test.out 2>&1
grep "NullPointerException" test.out

@ -27,8 +27,8 @@
* @summary Four helper classes missing in Sun JDK
* @library /lib/testlibrary
* @build jdk.testlibrary.*
* @compile -addmods java.corba CorbaExceptionsCompileTest.java
* @run main/othervm -addmods java.corba CorbaExceptionsCompileTest
* @modules java.corba
* @run main CorbaExceptionsCompileTest
*/
import java.io.*;

@ -25,8 +25,8 @@
* @test
* @bug 7095856
* @summary OutputStreamHook doesn't handle null values
* @compile -addmods java.corba HookPutFieldsTest.java
* @run main/othervm -addmods java.corba HookPutFieldsTest
* @modules java.corba
* @run main HookPutFieldsTest
*/
import java.net.InetAddress;

@ -25,8 +25,8 @@
* @test
* @bug 8028215
* @summary SetDefaultORBTest setting ORB impl via properties test
* @compile -addmods java.corba SetDefaultORBTest.java
* @run main/othervm -addmods java.corba SetDefaultORBTest
* @modules java.corba
* @run main SetDefaultORBTest
*
*/

@ -99,11 +99,11 @@ env
set -vx
#
# Compile test class
${TESTJAVA}/bin/javac -XaddExports:jdk.jdi/com.sun.tools.example.debug.tty=ALL-UNNAMED \
${TESTJAVA}/bin/javac --add-exports jdk.jdi/com.sun.tools.example.debug.tty=ALL-UNNAMED \
-d "${TESTCLASSES}" ${CP} -g "${TESTSRC}"/"${TARGETCLASS}".java
#
# Run the test class, again with the classpath we need:
${TESTJAVA}/bin/java -XaddExports:jdk.jdi/com.sun.tools.example.debug.tty=ALL-UNNAMED \
${TESTJAVA}/bin/java --add-exports jdk.jdi/com.sun.tools.example.debug.tty=ALL-UNNAMED \
${CP} ${TARGETCLASS}
status=$?
echo "test status was: $status"

@ -26,6 +26,7 @@
* @summary Tests that JNDI/COS naming parser supports the syntax
* defined in the new INS standard.
* @modules java.corba/com.sun.jndi.cosnaming
* @run main/othervm CNNameParser
*/
import javax.naming.*;

@ -25,6 +25,7 @@
* @bug 5042453
* @summary Ipv6 address throws Non-numeric port number error
* @modules java.corba/com.sun.jndi.cosnaming
* @run main/othervm IiopUrlIPv6
*/
import com.sun.jndi.cosnaming.*;

@ -61,7 +61,7 @@ public class CheckOrigin {
ProcessBuilder pb = ProcessTools.
createJavaProcessBuilder(
"-XaddExports:jdk.attach/sun.tools.attach=ALL-UNNAMED",
"--add-exports", "jdk.attach/sun.tools.attach=ALL-UNNAMED",
"-XX:+UseConcMarkSweepGC", // this will cause UseParNewGC to be FLAG_SET_ERGO
"-XX:+UseCodeAging",
"-XX:+UseCerealGC", // Should be ignored.

@ -55,7 +55,7 @@ public class GtkVersionTest {
"/bin/java " +
(version == null ? "" : "-Djdk.gtk.version=" + version) +
" -Djdk.gtk.verbose=true " +
"-XaddExports:java.desktop/sun.awt=ALL-UNNAMED " +
"--add-exports=java.desktop/sun.awt=ALL-UNNAMED " +
"-cp " + System.getProperty("java.class.path", ".") +
" GtkVersionTest$LoadGtk");
p.waitFor();

@ -113,8 +113,8 @@ fi
case "$OS" in
Windows* | CYGWIN* )
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \
-XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
-XaddExports:java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
*.java
status=$?
if [ ! $status -eq "0" ]; then
@ -124,8 +124,8 @@ case "$OS" in
SunOS | Linux )
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \
-XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
-XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
*.java
status=$?
if [ ! $status -eq "0" ]; then
@ -135,8 +135,8 @@ case "$OS" in
Darwin)
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \
-XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
-XaddExports:java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
*.java
status=$?
if [ ! $status -eq "0" ]; then
@ -154,16 +154,16 @@ chmod 777 ./*
case "$OS" in
Windows* | CYGWIN* )
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
-XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
-XaddExports:java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
TestWrapped sun.awt.windows.WToolkit
status=$?
if [ ! $status -eq "0" ]; then
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.windows.WToolkit";
fi
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
-XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
-XaddExports:java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
-Dawt.toolkit=sun.awt.windows.WToolkit \
TestWrapped sun.awt.windows.WToolkit
status=$?
@ -174,8 +174,8 @@ case "$OS" in
SunOS | Linux )
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
-XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
-XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
-Dawt.toolkit=sun.awt.X11.XToolkit \
TestWrapped sun.awt.X11.XToolkit
status=$?
@ -183,8 +183,8 @@ case "$OS" in
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.xawt.XToolkit";
fi
AWT_TOOLKIT=XToolkit ${TESTJAVA}/bin/java ${TESTVMOPTS} \
-XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
-XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
-Djava.awt.headless=true \
TestWrapped sun.awt.X11.XToolkit
status=$?
@ -195,16 +195,16 @@ case "$OS" in
Darwin)
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
-XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
-XaddExports:java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
TestWrapped sun.lwawt.macosx.LWCToolkit
status=$?
if [ ! $status -eq "0" ]; then
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.lwawt.macosx.LWCToolkit";
fi
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
-XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
-XaddExports:java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
--add-exports java.desktop/sun.awt=ALL-UNNAMED \
--add-exports java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
-Dawt.toolkit=sun.lwawt.macosx.LWCToolkit \
TestWrapped sun.lwawt.macosx.LWCToolkit
status=$?

@ -73,10 +73,11 @@ public class RunTestXEmbed extends TestXEmbedServer {
enva[ind++] = "AWT_TOOLKIT=sun.awt.X11.XToolkit";
}
}
Process proc = Runtime.getRuntime().exec(java_home +
"/bin/java -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED -Dawt.toolkit=sun.awt.X11.XToolkit TesterClient "
+ test.getName() + " " + window + buf,
enva);
Process proc = Runtime.getRuntime().
exec(java_home +
"/bin/java --add-exports java.desktop/sun.awt.X11=ALL-UNNAMED -Dawt.toolkit=sun.awt.X11.XToolkit TesterClient "
+ test.getName() + " " + window + buf,
enva);
System.err.println("Test for " + test.getName() + " has started.");
log.fine("Test for " + test.getName() + " has started.");
new InputReader(proc.getInputStream());

@ -84,11 +84,11 @@ public class TestXEmbedServerJava extends TestXEmbedServer {
}
if (hasModules) {
System.out.println(java_home +
"/bin/java -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED "+
"-XaddExports:java.desktop/sun.awt=ALL-UNNAMED JavaClient " + window);
"/bin/java --add-exports java.desktop/sun.awt.X11=ALL-UNNAMED "+
"--add-exports java.desktop/sun.awt=ALL-UNNAMED JavaClient " + window);
return Runtime.getRuntime().exec(java_home +
"/bin/java -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED "+
"-XaddExports:java.desktop/sun.awt=ALL-UNNAMED JavaClient " + window);
"/bin/java --add-exports java.desktop/sun.awt.X11=ALL-UNNAMED "+
"--add-exports java.desktop/sun.awt=ALL-UNNAMED JavaClient " + window);
}else{
System.out.println(java_home + "/bin/java JavaClient " + window);
return Runtime.getRuntime().exec(java_home + "/bin/java JavaClient " + window);

@ -39,7 +39,7 @@ import java.util.List;
* java.corba
* java.xml.bind
* @compile -XDignore.symbol.file TestConstructorFinder.java
* @run main/othervm -addmods java.activation -addmods java.transaction -addmods java.corba -addmods java.xml.bind TestConstructorFinder
* @run main/othervm --add-modules=java.activation,java.transaction,java.corba,java.xml.bind TestConstructorFinder
*/
public class TestConstructorFinder {

@ -39,7 +39,7 @@ import java.util.List;
* java.corba
* java.xml.bind
* @compile -XDignore.symbol.file TestMethodFinder.java
* @run main/othervm -addmods java.activation -addmods java.transaction -addmods java.corba -addmods java.xml.bind TestMethodFinder
* @run main/othervm --add-modules=java.activation,java.transaction,java.corba,java.xml.bind TestMethodFinder
*/
public class TestMethodFinder {

@ -0,0 +1,50 @@
/*
* 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.
*
* 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.
*/
/* @test
* @bug 8163518
* @summary Integer overflow when reading in large buffer
* @requires (os.simpleArch == "x64" & os.maxMemory > 8g)
* @run main/othervm -Xmx8g OverflowInRead
*/
import java.io.CharArrayReader;
public class OverflowInRead {
public static void main(String[] args) throws Exception {
char[] a = "_123456789_123456789_123456789_123456789"
.toCharArray(); // a.length > 33
try (CharArrayReader car = new CharArrayReader(a)) {
int len1 = 33;
char[] buf1 = new char[len1];
if (car.read(buf1, 0, len1) != len1)
throw new Exception("Expected to read " + len1 + " chars");
int len2 = Integer.MAX_VALUE - 32;
char[] buf2 = new char[len2];
int expLen2 = a.length - len1;
if (car.read(buf2, 0, len2) != expLen2)
throw new Exception("Expected to read " + expLen2 + " chars");
}
}
}

@ -0,0 +1,51 @@
/*
* 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.
*
* 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.
*/
/* @test
* @bug 8163518
* @summary Integer overflow when skipping a lot
*/
import java.io.CharArrayReader;
public class OverflowInSkip {
public static void main(String[] args) throws Exception {
char[] a = "_123456789_123456789_123456789_123456789"
.toCharArray(); // a.length > 33
try (CharArrayReader car = new CharArrayReader(a)) {
long small = 33;
long big = Long.MAX_VALUE;
long smallSkip = car.skip(small);
if (smallSkip != small)
throw new Exception("Expected to skip " + small
+ " chars, but skipped " + smallSkip);
long expSkip = a.length - small;
long bigSkip = car.skip(big);
if (bigSkip != expSkip)
throw new Exception("Expected to skip " + expSkip
+ " chars, but skipped " + bigSkip);
}
}
}

@ -0,0 +1,49 @@
/*
* 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.
*
* 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.
*/
/* @test
* @bug 8163518
* @summary Integer overflow when reading in large buffer
* @requires (os.simpleArch == "x64" & os.maxMemory > 4g)
* @run main/othervm -Xmx4g OverflowInRead
*/
import java.io.StringBufferInputStream;
public class OverflowInRead {
public static void main(String[] args) throws Exception {
String s = "_123456789_123456789_123456789_123456789"; // s.length() > 33
try (StringBufferInputStream sbis = new StringBufferInputStream(s)) {
int len1 = 33;
byte[] buf1 = new byte[len1];
if (sbis.read(buf1, 0, len1) != len1)
throw new Exception("Expected to read " + len1 + " bytes");
int len2 = Integer.MAX_VALUE - 32;
byte[] buf2 = new byte[len2];
int expLen2 = s.length() - len1;
if (sbis.read(buf2, 0, len2) != expLen2)
throw new Exception("Expected to read " + expLen2 + " bytes");
}
}
}

@ -65,7 +65,7 @@ public class TestDriver {
public void setup() throws Exception {
assertTrue(CompilerUtils.compile(
MOD_SRC_DIR, MOD_DEST_DIR,
"-modulesourcepath",
"--module-source-path",
MOD_SRC_DIR.toString()));
copyDirectories(MOD_DEST_DIR.resolve("m1"), Paths.get("mods1"));
@ -76,8 +76,8 @@ public class TestDriver {
public void test() throws Exception {
String[] options = new String[] {
"-cp", TEST_CLASSES,
"-mp", MOD_DEST_DIR.toString(),
"-addmods", String.join(",", modules),
"--module-path", MOD_DEST_DIR.toString(),
"--add-modules", String.join(",", modules),
"-m", "m2/p2.test.Main"
};
runTest(options);
@ -87,8 +87,8 @@ public class TestDriver {
public void testUnnamedModule() throws Exception {
String[] options = new String[] {
"-cp", TEST_CLASSES,
"-mp", MOD_DEST_DIR.toString(),
"-addmods", String.join(",", modules),
"--module-path", MOD_DEST_DIR.toString(),
"--add-modules", String.join(",", modules),
"TestMain"
};
runTest(options);
@ -107,8 +107,8 @@ public class TestDriver {
@Test
public void testDeniedClassLoaderAccess() throws Exception {
String[] options = new String[] {
"-mp", MOD_DEST_DIR.toString(),
"-addmods", String.join(",", modules),
"--module-path", MOD_DEST_DIR.toString(),
"--add-modules", String.join(",", modules),
"-m", "m3/p3.NoGetClassLoaderAccess"
};
assertTrue(executeTestJava(options)
@ -124,8 +124,8 @@ public class TestDriver {
String[] options = new String[] {
"-Djava.security.manager",
"-Djava.security.policy=" + policyFile.toString(),
"-mp", MOD_DEST_DIR.toString(),
"-addmods", String.join(",", modules),
"--module-path", MOD_DEST_DIR.toString(),
"--add-modules", String.join(",", modules),
"-m", "m3/p3.NoAccess"
};
assertTrue(executeTestJava(options)

@ -63,8 +63,8 @@ import jdk.internal.module.Modules;
* loads all the classes in the BCL, get their declared fields,
* and call setAccessible(false) followed by setAccessible(true);
* @modules java.base/jdk.internal.module
* @run main/othervm -Djdk.launcher.addmods=ALL-SYSTEM FieldSetAccessibleTest UNSECURE
* @run main/othervm -Djdk.launcher.addmods=ALL-SYSTEM FieldSetAccessibleTest SECURE
* @run main/othervm --add-modules=ALL-SYSTEM FieldSetAccessibleTest UNSECURE
* @run main/othervm --add-modules=ALL-SYSTEM FieldSetAccessibleTest SECURE
*
* @author danielfuchs
*/

@ -60,15 +60,15 @@ public class ResourcesTest {
compiled = CompilerUtils
.compile(SRC_DIR,
MODS_DIR,
"-modulesourcepath", SRC_DIR.toString());
"--module-source-path", SRC_DIR.toString());
assertTrue(compiled);
// javac -mp mods -d classes Main.java
// javac --module-path mods -d classes Main.java
compiled = CompilerUtils
.compile(Paths.get(TEST_SRC, "Main.java"),
CLASSES_DIR,
"-mp", MODS_DIR.toString(),
"-addmods", "m1,m2,m3");
"--module-path", MODS_DIR.toString(),
"--add-modules", "m1,m2,m3");
assertTrue(compiled);
}
@ -79,8 +79,8 @@ public class ResourcesTest {
public void runTest() throws Exception {
int exitValue
= executeTestJava("-mp", MODS_DIR.toString(),
"-addmods", "m1,m2,m3",
= executeTestJava("--module-path", MODS_DIR.toString(),
"--add-modules", "m1,m2,m3",
"-cp", CLASSES_DIR.toString(),
"Main")
.outputTo(System.out)

@ -56,19 +56,19 @@ public class ResourcesTest {
public void compileAll() throws Exception {
boolean compiled;
// javac -modulesource mods -d mods src/**
// javac --module-source-path mods -d mods src/**
compiled = CompilerUtils
.compile(SRC_DIR,
MODS_DIR,
"-modulesourcepath", SRC_DIR.toString());
"--module-source-path", SRC_DIR.toString());
assertTrue(compiled);
// javac -mp mods -d classes Main.java
// javac --module-path mods -d classes Main.java
compiled = CompilerUtils
.compile(Paths.get(TEST_SRC, "Main.java"),
CLASSES_DIR,
"-mp", MODS_DIR.toString(),
"-addmods", "m1,m2,m3");
"--module-path", MODS_DIR.toString(),
"--add-modules", "m1,m2,m3");
assertTrue(compiled);
}
@ -77,8 +77,8 @@ public class ResourcesTest {
*/
public void runTest() throws Exception {
int exitValue
= executeTestJava("-mp", MODS_DIR.toString(),
"-addmods", "m1,m2,m3",
= executeTestJava("--module-path", MODS_DIR.toString(),
"--add-modules", "m1,m2,m3",
"-cp", CLASSES_DIR.toString(),
"Main")
.outputTo(System.out)

@ -51,15 +51,15 @@ JAVAC="$COMPILEJAVA/bin/javac"
JAVA="$TESTJAVA/bin/java ${TESTVMOPTS}"
mkdir -p mods
$JAVAC -d mods -modulesourcepath ${TESTSRC} `find ${TESTSRC}/m -name "*.java"`
$JAVAC -d mods --module-source-path ${TESTSRC} `find ${TESTSRC}/m -name "*.java"`
mkdir -p classes
$JAVAC -d classes ${TESTSRC}/Test.java
$JAVA -cp classes -mp mods -addmods m \
$JAVA -cp classes --module-path mods --add-modules m \
-Djava.security.manager \
-Djava.security.policy=${TESTSRC}/test.policy Test
$JAVA -cp classes -mp mods -addmods m \
$JAVA -cp classes --module-path mods --add-modules m \
-Djava.security.manager=p.CustomSecurityManager \
-Djava.security.policy=${TESTSRC}/test.policy Test

@ -38,13 +38,13 @@ import java.security.Permission;
* @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT WithSecurityManager
* @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT WithSecurityManager
*
* @run main/othervm -Xverify:all -limitmods java.base WithSecurityManager
* @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB WithSecurityManager
* @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB_SIZED WithSecurityManager
* @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_SB_SIZED WithSecurityManager
* @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT WithSecurityManager
* @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT WithSecurityManager
* @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT WithSecurityManager
* @run main/othervm -Xverify:all --limit-modules=java.base WithSecurityManager
* @run main/othervm -Xverify:all --limit-modules=java.base -Djava.lang.invoke.stringConcat=BC_SB WithSecurityManager
* @run main/othervm -Xverify:all --limit-modules=java.base -Djava.lang.invoke.stringConcat=BC_SB_SIZED WithSecurityManager
* @run main/othervm -Xverify:all --limit-modules=java.base -Djava.lang.invoke.stringConcat=MH_SB_SIZED WithSecurityManager
* @run main/othervm -Xverify:all --limit-modules=java.base -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT WithSecurityManager
* @run main/othervm -Xverify:all --limit-modules=java.base -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT WithSecurityManager
* @run main/othervm -Xverify:all --limit-modules=java.base -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT WithSecurityManager
*/
public class WithSecurityManager {
public static void main(String[] args) throws Throwable {

@ -87,7 +87,7 @@ ${JAVAC} ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} bootreporter/*.java
cd ..
${JAVAC} ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
-XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED ${AGENT}.java asmlib/*.java
--add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED ${AGENT}.java asmlib/*.java
${JAVAC} ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -classpath .${PATHSEP}bootpath ${APP}.java
echo "Manifest-Version: 1.0" > ${AGENT}.mf

@ -60,7 +60,7 @@ public class ModuleAccessControlTest {
for (String mn : modules) {
Path msrc = SRC_DIR.resolve(mn);
assertTrue(CompilerUtils
.compile(msrc, MODS_DIR, "-modulesourcepath", SRC_DIR.toString()));
.compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString()));
}
}
@ -69,7 +69,7 @@ public class ModuleAccessControlTest {
*/
@Test
public void runTest() throws Exception {
int exitValue = executeTestJava("-mp", MODS_DIR.toString(),
int exitValue = executeTestJava("--module-path", MODS_DIR.toString(),
"-m", "m1/p1.Main")
.outputTo(System.out)
.errorTo(System.out)

@ -63,9 +63,9 @@ public class LayerAndLoadersTest {
@BeforeTest
public void setup() throws Exception {
// javac -d mods -modulesourcepath src src/**
// javac -d mods --module-source-path src src/**
assertTrue(CompilerUtils.compile(SRC_DIR, MODS_DIR,
"-modulesourcepath", SRC_DIR.toString()));
"--module-source-path", SRC_DIR.toString()));
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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,29 +23,44 @@
/**
* @test
* @modules java.desktop
* @run main/othervm -XaddExports:java.desktop/sun.awt=java.base AddExportsTest
* @run main/othervm -XaddExports:java.desktop/sun.awt=ALL-UNNAMED AddExportsTest
* @modules java.base/jdk.internal.misc
* java.desktop
* @run main/othervm --add-exports=java.desktop/sun.awt=java.base AddExportsTest
* @run main/othervm --add-exports=java.desktop/sun.awt=ALL-UNNAMED AddExportsTest
* @summary Test Module isExported methods with exports changed by -AddExportsTest
*/
import java.lang.reflect.Layer;
import java.lang.reflect.Module;
import java.util.Optional;
import java.util.stream.Stream;
import jdk.internal.misc.VM;
public class AddExportsTest {
/*
* jtreg sets -Dtest.modules system property to the internal APIs
* specified at @modules tag. The test will exclude --add-exports set
* for @modules.
*/
private static final String TEST_MODULES = System.getProperty("test.modules");
public static void main(String[] args) {
String addExports = System.getProperty("jdk.launcher.addexports.0");
assertTrue(addExports != null, "Expected to be run with -XaddExports");
Optional<String> oaddExports = Stream.of(VM.getRuntimeArguments())
.filter(arg -> arg.startsWith("--add-exports="))
.filter(arg -> !arg.equals("--add-exports=" + TEST_MODULES + "=ALL-UNNAMED"))
.map(arg -> arg.substring("--add-exports=".length(), arg.length()))
.findFirst();
assertTrue(oaddExports.isPresent());
Layer bootLayer = Layer.boot();
Module unnamedModule = AddExportsTest.class.getModule();
assertFalse(unnamedModule.isNamed());
for (String expr : addExports.split(",")) {
for (String expr : oaddExports.get().split(",")) {
String[] s = expr.split("=");
assertTrue(s.length == 2);

@ -72,8 +72,8 @@ public class AccessTest {
*/
public void runTest() throws Exception {
int exitValue
= executeTestJava("-mp", MODS_DIR.toString(),
"-addmods", "target",
= executeTestJava("--module-path", MODS_DIR.toString(),
"--add-modules", "target",
"-m", "test/test.Main")
.outputTo(System.out)
.errorTo(System.out)

@ -64,7 +64,7 @@ public class ProxyClassAccessTest {
public void compileAll() throws Exception {
for (String mn : modules) {
Path msrc = SRC_DIR.resolve(mn);
assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "-modulesourcepath", SRC_DIR.toString()));
assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString()));
}
}
@ -73,7 +73,7 @@ public class ProxyClassAccessTest {
*/
@Test
public void runTest() throws Exception {
int exitValue = executeTestJava("-mp", MODS_DIR.toString(),
int exitValue = executeTestJava("--module-path", MODS_DIR.toString(),
"-m", "test/jdk.test.ProxyClassAccess")
.outputTo(System.out)
.errorTo(System.out)

@ -65,7 +65,7 @@ public class ProxyLayerTest {
public void compileAll() throws Exception {
for (String mn : modules) {
Path msrc = SRC_DIR.resolve(mn);
assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "-modulesourcepath", SRC_DIR.toString()));
assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString()));
}
}

@ -38,7 +38,7 @@ public class ProxyModuleMapping {
Module unnamed = ld.getUnnamedModule();
new ProxyModuleMapping(unnamed, Runnable.class).test();
// unnamed module gets access to sun.invoke package (e.g. via -XaddExports)
// unnamed module gets access to sun.invoke package (e.g. via --add-exports)
new ProxyModuleMapping(sun.invoke.WrapperInstance.class).test();
Class<?> modulePrivateIntf = Class.forName("sun.net.ProgressListener");

@ -61,7 +61,7 @@ public class ProxyTest {
public void compileAll() throws Exception {
for (String mn : modules) {
Path msrc = SRC_DIR.resolve(mn);
assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "-modulesourcepath", SRC_DIR.toString()));
assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString()));
}
}
@ -71,7 +71,7 @@ public class ProxyTest {
@Test
public void runTest() throws Exception {
int exitValue = executeTestJava("-cp", CPATH_DIR.toString(),
"-mp", MODS_DIR.toString(),
"--module-path", MODS_DIR.toString(),
"-m", "test/jdk.test.Main")
.outputTo(System.out)
.errorTo(System.out)

@ -44,7 +44,7 @@ case "$OS" in
;;
esac
EXTRAOPTS="-XaddExports:java.base/sun.net.www=ALL-UNNAMED -XaddExports:java.base/sun.net.www.protocol.http=ALL-UNNAMED"
EXTRAOPTS="--add-exports java.base/sun.net.www=ALL-UNNAMED --add-exports java.base/sun.net.www.protocol.http=ALL-UNNAMED"
export EXTRAOPTS
${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} ${EXTRAOPTS} -d . \

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