This commit is contained in:
Lana Steuck 2016-08-18 21:34:03 +00:00
commit 591154e8ac
80 changed files with 1182 additions and 396 deletions
jdk
make/copy
src
java.base/share/classes
java.compact1/share/classes
java.compact2/share/classes
java.compact3/share/classes
java.datatransfer/share/classes
java.desktop/share/classes
java.httpclient/share/classes
java.instrument/share/classes
java.logging/share/classes
java.management/share/classes
java.naming/share/classes
java.prefs/share/classes
java.rmi/share/classes
java.scripting/share/classes
java.se.ee/share/classes
java.se/share/classes
java.security.jgss/share/classes
java.security.sasl/share/classes
java.smartcardio/share/classes
java.sql.rowset/share/classes
java.sql/share/classes
java.transaction/share/classes
java.xml.crypto/share/classes
jdk.crypto.mscapi/windows/classes/sun/security/mscapi
jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins
test
MakefileProblemList.txt
java
lang/StackWalker
security
javax
net/ssl/Stapling
xml/crypto/dsig
sun

@ -183,7 +183,7 @@ DEF_POLICY_DST := $(LIB_DST_DIR)/security/default.policy
DEF_POLICY_SRC_LIST := $(DEF_POLICY_SRC)
ifeq ($(OPENJDK_TARGET_OS), windows)
ifneq ($(filter $(OPENJDK_TARGET_OS), windows solaris), )
DEF_POLICY_SRC_LIST += $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/lib/security/default.policy
endif

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 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
@ -107,7 +107,7 @@ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
throw new InvalidKeySpecException("Key length is negative");
}
try {
this.prf = Mac.getInstance(prfAlgo, SunJCE.getInstance());
this.prf = Mac.getInstance(prfAlgo);
} catch (NoSuchAlgorithmException nsae) {
// not gonna happen; re-throw just in case
InvalidKeySpecException ike = new InvalidKeySpecException();

@ -560,7 +560,7 @@ public class BufferedReader extends Reader {
* @since 1.8
*/
public Stream<String> lines() {
Iterator<String> iter = new Iterator<String>() {
Iterator<String> iter = new Iterator<>() {
String nextLine = null;
@Override

@ -187,7 +187,7 @@ public class ByteArrayOutputStream extends OutputStream {
* @return the current contents of this output stream, as a byte array.
* @see java.io.ByteArrayOutputStream#size()
*/
public synchronized byte toByteArray()[] {
public synchronized byte[] toByteArray() {
return Arrays.copyOf(buf, count);
}

@ -165,7 +165,7 @@ class CharArrayWriter extends Writer {
*
* @param csq
* The character sequence to append. If {@code csq} is
* {@code null}, then the four characters "{@code null}" are
* {@code null}, then the four characters {@code "null"} are
* appended to this writer.
*
* @return This writer
@ -173,7 +173,7 @@ class CharArrayWriter extends Writer {
* @since 1.5
*/
public CharArrayWriter append(CharSequence csq) {
String s = (csq == null ? "null" : csq.toString());
String s = String.valueOf(csq);
write(s, 0, s.length());
return this;
}
@ -193,7 +193,7 @@ class CharArrayWriter extends Writer {
* The character sequence from which a subsequence will be
* appended. If {@code csq} is {@code null}, then characters
* will be appended as if {@code csq} contained the four
* characters "{@code null}".
* characters {@code "null"}.
*
* @param start
* The index of the first character in the subsequence
@ -212,9 +212,8 @@ class CharArrayWriter extends Writer {
* @since 1.5
*/
public CharArrayWriter append(CharSequence csq, int start, int end) {
String s = (csq == null ? "null" : csq).subSequence(start, end).toString();
write(s, 0, s.length());
return this;
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
/**
@ -251,7 +250,7 @@ class CharArrayWriter extends Writer {
*
* @return an array of chars copied from the input data.
*/
public char toCharArray()[] {
public char[] toCharArray() {
synchronized (lock) {
return Arrays.copyOf(buf, count);
}

@ -228,13 +228,8 @@ abstract class FileSystem {
static boolean useCanonPrefixCache = true;
private static boolean getBooleanProperty(String prop, boolean defaultVal) {
String val = System.getProperty(prop);
if (val == null) return defaultVal;
if (val.equalsIgnoreCase("true")) {
return true;
} else {
return false;
}
return Boolean.parseBoolean(System.getProperty(prop,
String.valueOf(defaultVal)));
}
static {

@ -1265,22 +1265,21 @@ public class ObjectInputStream
WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
Boolean result = Caches.subclassAudits.get(key);
if (result == null) {
result = Boolean.valueOf(auditSubclass(cl));
result = auditSubclass(cl);
Caches.subclassAudits.putIfAbsent(key, result);
}
if (result.booleanValue()) {
return;
if (!result) {
sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
/**
* Performs reflective checks on given subclass to verify that it doesn't
* override security-sensitive non-final methods. Returns true if subclass
* is "safe", false otherwise.
* override security-sensitive non-final methods. Returns TRUE if subclass
* is "safe", FALSE otherwise.
*/
private static boolean auditSubclass(final Class<?> subcl) {
Boolean result = AccessController.doPrivileged(
private static Boolean auditSubclass(Class<?> subcl) {
return AccessController.doPrivileged(
new PrivilegedAction<>() {
public Boolean run() {
for (Class<?> cl = subcl;
@ -1303,7 +1302,6 @@ public class ObjectInputStream
}
}
);
return result.booleanValue();
}
/**

@ -1050,22 +1050,21 @@ public class ObjectOutputStream
WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
Boolean result = Caches.subclassAudits.get(key);
if (result == null) {
result = Boolean.valueOf(auditSubclass(cl));
result = auditSubclass(cl);
Caches.subclassAudits.putIfAbsent(key, result);
}
if (result.booleanValue()) {
return;
if (!result) {
sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
/**
* Performs reflective checks on given subclass to verify that it doesn't
* override security-sensitive non-final methods. Returns true if subclass
* is "safe", false otherwise.
* override security-sensitive non-final methods. Returns TRUE if subclass
* is "safe", FALSE otherwise.
*/
private static boolean auditSubclass(final Class<?> subcl) {
Boolean result = AccessController.doPrivileged(
private static Boolean auditSubclass(Class<?> subcl) {
return AccessController.doPrivileged(
new PrivilegedAction<>() {
public Boolean run() {
for (Class<?> cl = subcl;
@ -1088,7 +1087,6 @@ public class ObjectOutputStream
}
}
);
return result.booleanValue();
}
/**

@ -1509,11 +1509,9 @@ public class ObjectStreamClass implements Serializable {
private static String getPackageName(Class<?> cl) {
String s = cl.getName();
int i = s.lastIndexOf('[');
if (i >= 0) {
s = s.substring(i + 2);
}
i = s.lastIndexOf('.');
return (i >= 0) ? s.substring(0, i) : "";
i = (i < 0) ? 0 : i + 2;
int j = s.lastIndexOf('.');
return (i < j) ? s.substring(i, j) : "";
}
/**
@ -1535,14 +1533,14 @@ public class ObjectStreamClass implements Serializable {
private static String getMethodSignature(Class<?>[] paramTypes,
Class<?> retType)
{
StringBuilder sbuf = new StringBuilder();
sbuf.append('(');
StringBuilder sb = new StringBuilder();
sb.append('(');
for (int i = 0; i < paramTypes.length; i++) {
appendClassSignature(sbuf, paramTypes[i]);
appendClassSignature(sb, paramTypes[i]);
}
sbuf.append(')');
appendClassSignature(sbuf, retType);
return sbuf.toString();
sb.append(')');
appendClassSignature(sb, retType);
return sb.toString();
}
/**

@ -233,22 +233,16 @@ public class OutputStreamWriter extends Writer {
@Override
public Writer append(CharSequence csq, int start, int end) throws IOException {
if (csq == null) {
write("null".subSequence(start, end).toString());
return this;
} else {
return append(csq.subSequence(start, end));
}
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
@Override
public Writer append(CharSequence csq) throws IOException {
if (csq == null) {
se.write("null");
} else if (csq instanceof CharBuffer) {
if (csq instanceof CharBuffer) {
se.write((CharBuffer) csq);
} else {
se.write(csq.toString());
se.write(String.valueOf(csq));
}
return this;
}

@ -568,7 +568,7 @@ public class PrintStream extends FilterOutputStream
* @param b The {@code boolean} to be printed
*/
public void print(boolean b) {
write(b ? "true" : "false");
write(String.valueOf(b));
}
/**
@ -663,10 +663,7 @@ public class PrintStream extends FilterOutputStream
* @param s The {@code String} to be printed
*/
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
write(String.valueOf(s));
}
/**
@ -1068,10 +1065,7 @@ public class PrintStream extends FilterOutputStream
* @since 1.5
*/
public PrintStream append(CharSequence csq) {
if (csq == null)
print("null");
else
print(csq.toString());
print(String.valueOf(csq));
return this;
}
@ -1111,9 +1105,8 @@ public class PrintStream extends FilterOutputStream
* @since 1.5
*/
public PrintStream append(CharSequence csq, int start, int end) {
CharSequence cs = (csq == null ? "null" : csq);
write(cs.subSequence(start, end).toString());
return this;
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
/**

@ -504,7 +504,7 @@ public class PrintWriter extends Writer {
* @param b The {@code boolean} to be printed
*/
public void print(boolean b) {
write(b ? "true" : "false");
write(String.valueOf(b));
}
/**
@ -599,10 +599,7 @@ public class PrintWriter extends Writer {
* @param s The {@code String} to be printed
*/
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
write(String.valueOf(s));
}
/**
@ -1005,10 +1002,7 @@ public class PrintWriter extends Writer {
* @since 1.5
*/
public PrintWriter append(CharSequence csq) {
if (csq == null)
write("null");
else
write(csq.toString());
write(String.valueOf(csq));
return this;
}
@ -1047,9 +1041,8 @@ public class PrintWriter extends Writer {
* @since 1.5
*/
public PrintWriter append(CharSequence csq, int start, int end) {
CharSequence cs = (csq == null ? "null" : csq);
write(cs.subSequence(start, end).toString());
return this;
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
/**

@ -65,12 +65,7 @@ class SequenceInputStream extends InputStream {
*/
public SequenceInputStream(Enumeration<? extends InputStream> e) {
this.e = e;
try {
nextStream();
} catch (IOException ex) {
// This should never happen
throw new Error("panic");
}
peekNextStream();
}
/**
@ -86,16 +81,10 @@ class SequenceInputStream extends InputStream {
*/
public SequenceInputStream(InputStream s1, InputStream s2) {
Vector<InputStream> v = new Vector<>(2);
v.addElement(s1);
v.addElement(s2);
e = v.elements();
try {
nextStream();
} catch (IOException ex) {
// This should never happen
throw new Error("panic");
}
peekNextStream();
}
/**
@ -105,14 +94,17 @@ class SequenceInputStream extends InputStream {
if (in != null) {
in.close();
}
peekNextStream();
}
private void peekNextStream() {
if (e.hasMoreElements()) {
in = (InputStream) e.nextElement();
if (in == null)
throw new NullPointerException();
} else {
in = null;
}
else in = null;
}
/**

@ -108,6 +108,7 @@ class StringBufferInputStream extends InputStream {
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
*/
@SuppressWarnings("deprecation")
public synchronized int read(byte b[], int off, int len) {
if (b == null) {
throw new NullPointerException();
@ -126,12 +127,8 @@ class StringBufferInputStream extends InputStream {
if (len <= 0) {
return 0;
}
String s = buffer;
int cnt = len;
while (--cnt >= 0) {
b[off++] = (byte)s.charAt(pos++);
}
buffer.getBytes(pos, pos + len, b, off);
pos += len;
return len;
}

@ -142,8 +142,8 @@ public class StringReader extends Reader {
*/
public boolean ready() throws IOException {
synchronized (lock) {
ensureOpen();
return true;
ensureOpen();
return true;
}
}

@ -139,7 +139,7 @@ public class StringWriter extends Writer {
*
* @param csq
* The character sequence to append. If {@code csq} is
* {@code null}, then the four characters "{@code null}" are
* {@code null}, then the four characters {@code "null"} are
* appended to this writer.
*
* @return This writer
@ -147,10 +147,7 @@ public class StringWriter extends Writer {
* @since 1.5
*/
public StringWriter append(CharSequence csq) {
if (csq == null)
write("null");
else
write(csq.toString());
write(String.valueOf(csq));
return this;
}
@ -170,7 +167,7 @@ public class StringWriter extends Writer {
* The character sequence from which a subsequence will be
* appended. If {@code csq} is {@code null}, then characters
* will be appended as if {@code csq} contained the four
* characters "{@code null}".
* characters {@code "null"}.
*
* @param start
* The index of the first character in the subsequence
@ -189,9 +186,8 @@ public class StringWriter extends Writer {
* @since 1.5
*/
public StringWriter append(CharSequence csq, int start, int end) {
CharSequence cs = (csq == null ? "null" : csq);
write(cs.subSequence(start, end).toString());
return this;
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
/**

@ -221,7 +221,7 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
*
* @param csq
* The character sequence to append. If {@code csq} is
* {@code null}, then the four characters "{@code null}" are
* {@code null}, then the four characters {@code "null"} are
* appended to this writer.
*
* @return This writer
@ -232,10 +232,7 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
* @since 1.5
*/
public Writer append(CharSequence csq) throws IOException {
if (csq == null)
write("null");
else
write(csq.toString());
write(String.valueOf(csq));
return this;
}
@ -256,7 +253,7 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
* The character sequence from which a subsequence will be
* appended. If {@code csq} is {@code null}, then characters
* will be appended as if {@code csq} contained the four
* characters "{@code null}".
* characters {@code "null"}.
*
* @param start
* The index of the first character in the subsequence
@ -278,9 +275,8 @@ public abstract class Writer implements Appendable, Closeable, Flushable {
* @since 1.5
*/
public Writer append(CharSequence csq, int start, int end) throws IOException {
CharSequence cs = (csq == null ? "null" : csq);
write(cs.subSequence(start, end).toString());
return this;
if (csq == null) csq = "null";
return append(csq.subSequence(start, end));
}
/**

@ -36,7 +36,6 @@ import sun.invoke.util.Wrapper;
import java.lang.invoke.LambdaForm.NamedFunction;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
@ -308,7 +307,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
/*non-public*/ char fieldTypeChar(int i) {
return typeChars.charAt(i);
}
Object fieldSignature() {
String fieldSignature() {
return typeChars;
}
public Class<? extends BoundMethodHandle> fieldHolder() {

@ -27,6 +27,7 @@ package java.lang.invoke;
import java.util.Arrays;
import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.LambdaForm.Kind.*;
import static java.lang.invoke.MethodHandleStatics.*;
/**
@ -96,14 +97,8 @@ abstract class DelegatingMethodHandle extends MethodHandle {
int whichCache,
Object constraint,
NamedFunction getTargetFn) {
String debugString;
switch(whichCache) {
case MethodTypeForm.LF_REBIND: debugString = "BMH.reinvoke"; break;
case MethodTypeForm.LF_DELEGATE: debugString = "MH.delegate"; break;
default: debugString = "MH.reinvoke"; break;
}
// No pre-action needed.
return makeReinvokerForm(target, whichCache, constraint, debugString, true, getTargetFn, null);
return makeReinvokerForm(target, whichCache, constraint, null, true, getTargetFn, null);
}
/** Create a LF which simply reinvokes a target of the given basic type. */
static LambdaForm makeReinvokerForm(MethodHandle target,
@ -114,6 +109,10 @@ abstract class DelegatingMethodHandle extends MethodHandle {
NamedFunction getTargetFn,
NamedFunction preActionFn) {
MethodType mtype = target.type().basicType();
Kind kind = whichKind(whichCache);
if (debugString == null) {
debugString = kind.defaultLambdaName;
}
boolean customized = (whichCache < 0 ||
mtype.parameterSlotCount() > MethodType.MAX_MH_INVOKER_ARITY);
boolean hasPreAction = (preActionFn != null);
@ -145,13 +144,21 @@ abstract class DelegatingMethodHandle extends MethodHandle {
targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH
names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs);
}
form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline);
form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline, kind);
if (!customized) {
form = mtype.form().setCachedLambdaForm(whichCache, form);
}
return form;
}
private static Kind whichKind(int whichCache) {
switch(whichCache) {
case MethodTypeForm.LF_REBIND: return BOUND_REINVOKER;
case MethodTypeForm.LF_DELEGATE: return DELEGATE;
default: return REINVOKER;
}
}
static final NamedFunction NF_getTarget;
static {
try {
@ -160,5 +167,13 @@ abstract class DelegatingMethodHandle extends MethodHandle {
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
// The Holder class will contain pre-generated DelegatingMethodHandles resolved
// speculatively using MemberName.getFactory().resolveOrNull. However, that
// doesn't initialize the class, which subtly breaks inlining etc. By forcing
// initialization of the Holder class we avoid these issues.
UNSAFE.ensureClassInitialized(Holder.class);
}
/* Placeholder class for DelegatingMethodHandles generated ahead of time */
final class Holder {}
}

@ -38,6 +38,7 @@ import java.util.Arrays;
import java.util.Objects;
import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.LambdaForm.Kind.*;
import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.MethodHandleStatics.UNSAFE;
import static java.lang.invoke.MethodHandleStatics.newInternalError;
@ -189,14 +190,15 @@ class DirectMethodHandle extends MethodHandle {
static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
boolean needsInit = (which == LF_INVSTATIC_INIT);
boolean doesAlloc = (which == LF_NEWINVSPECIAL);
String linkerName, lambdaName;
String linkerName;
LambdaForm.Kind kind;
switch (which) {
case LF_INVVIRTUAL: linkerName = "linkToVirtual"; lambdaName = "DMH.invokeVirtual"; break;
case LF_INVSTATIC: linkerName = "linkToStatic"; lambdaName = "DMH.invokeStatic"; break;
case LF_INVSTATIC_INIT:linkerName = "linkToStatic"; lambdaName = "DMH.invokeStaticInit"; break;
case LF_INVSPECIAL: linkerName = "linkToSpecial"; lambdaName = "DMH.invokeSpecial"; break;
case LF_INVINTERFACE: linkerName = "linkToInterface"; lambdaName = "DMH.invokeInterface"; break;
case LF_NEWINVSPECIAL: linkerName = "linkToSpecial"; lambdaName = "DMH.newInvokeSpecial"; break;
case LF_INVVIRTUAL: linkerName = "linkToVirtual"; kind = DIRECT_INVOKE_VIRTUAL; break;
case LF_INVSTATIC: linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC; break;
case LF_INVSTATIC_INIT:linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC_INIT; break;
case LF_INVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_INVOKE_SPECIAL; break;
case LF_INVINTERFACE: linkerName = "linkToInterface"; kind = DIRECT_INVOKE_INTERFACE; break;
case LF_NEWINVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_NEW_INVOKE_SPECIAL; break;
default: throw new InternalError("which="+which);
}
@ -240,11 +242,11 @@ class DirectMethodHandle extends MethodHandle {
result = NEW_OBJ;
}
names[LINKER_CALL] = new Name(linker, outArgs);
lambdaName += "_" + shortenSignature(basicTypeSignature(mtype));
LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
String lambdaName = kind.defaultLambdaName + "_" + shortenSignature(basicTypeSignature(mtype));
LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result, kind);
// This is a tricky bit of code. Don't send it through the LF interpreter.
lform.compileToBytecode(Holder.class);
lform.compileToBytecode();
return lform;
}
@ -705,7 +707,7 @@ class DirectMethodHandle extends MethodHandle {
}
static {
// The DMH class will contain pre-generated DirectMethodHandles resolved
// The Holder class will contain pre-generated DirectMethodHandles resolved
// speculatively using MemberName.getFactory().resolveOrNull. However, that
// doesn't initialize the class, which subtly breaks inlining etc. By forcing
// initialization of the Holder class we avoid these issues.
@ -713,5 +715,5 @@ class DirectMethodHandle extends MethodHandle {
}
/* Placeholder class for DirectMethodHandles generated ahead of time */
private final class Holder {}
final class Holder {}
}

@ -29,21 +29,56 @@ import java.util.Map;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
import java.util.ArrayList;
import java.util.HashSet;
/**
* Helper class to assist the GenerateJLIClassesPlugin to get access to
* generate classes ahead of time.
*/
class GenerateJLIClassesHelper {
static byte[] generateDMHClassBytes(String className,
static byte[] generateDirectMethodHandleHolderClassBytes(String className,
MethodType[] methodTypes, int[] types) {
LambdaForm[] forms = new LambdaForm[methodTypes.length];
String[] names = new String[methodTypes.length];
for (int i = 0; i < forms.length; i++) {
forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i],
types[i]);
methodTypes[i] = forms[i].methodType();
names[i] = forms[i].kind.defaultLambdaName;
}
return generateCodeBytesForLFs(className, forms, methodTypes);
return generateCodeBytesForLFs(className, names, forms);
}
static byte[] generateDelegatingMethodHandleHolderClassBytes(String className,
MethodType[] methodTypes) {
HashSet<MethodType> dedupSet = new HashSet<>();
ArrayList<LambdaForm> forms = new ArrayList<>();
ArrayList<String> names = new ArrayList<>();
for (int i = 0; i < methodTypes.length; i++) {
// generate methods representing the DelegatingMethodHandle
if (dedupSet.add(methodTypes[i])) {
// reinvokers are variant with the associated SpeciesData
// and shape of the target LF, but we can easily pregenerate
// the basic reinvokers associated with Species_L. Ultimately we
// may want to consider pregenerating more of these, which will
// require an even more complex naming scheme
LambdaForm reinvoker = makeReinvokerFor(methodTypes[i]);
forms.add(reinvoker);
String speciesSig = BoundMethodHandle
.speciesData(reinvoker).fieldSignature();
assert(speciesSig.equals("L"));
names.add(reinvoker.kind.defaultLambdaName + "_" + speciesSig);
LambdaForm delegate = makeDelegateFor(methodTypes[i]);
forms.add(delegate);
names.add(delegate.kind.defaultLambdaName);
}
}
return generateCodeBytesForLFs(className,
names.toArray(new String[0]),
forms.toArray(new LambdaForm[0]));
}
/*
@ -51,22 +86,45 @@ class GenerateJLIClassesHelper {
* a class with a specified name.
*/
private static byte[] generateCodeBytesForLFs(String className,
LambdaForm[] forms, MethodType[] types) {
assert(forms.length == types.length);
String[] names, LambdaForm[] forms) {
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();
addMethod(className, names[i], forms[i],
forms[i].methodType(), cw);
}
return cw.toByteArray();
}
private static void addMethod(String className, String methodName, LambdaForm form,
MethodType type, ClassWriter cw) {
InvokerBytecodeGenerator g
= new InvokerBytecodeGenerator(className, methodName, form, type);
g.setClassWriter(cw);
g.addMethod();
}
private static LambdaForm makeReinvokerFor(MethodType type) {
MethodHandle emptyHandle = MethodHandles.empty(type);
return DelegatingMethodHandle.makeReinvokerForm(emptyHandle,
MethodTypeForm.LF_REBIND,
BoundMethodHandle.speciesData_L(),
BoundMethodHandle.speciesData_L().getterFunction(0));
}
private static LambdaForm makeDelegateFor(MethodType type) {
MethodHandle handle = MethodHandles.empty(type);
return DelegatingMethodHandle.makeReinvokerForm(
handle,
MethodTypeForm.LF_DELEGATE,
DelegatingMethodHandle.class,
DelegatingMethodHandle.NF_getTarget);
}
static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
final String types) {
for (char c : types.toCharArray()) {

@ -46,6 +46,7 @@ import java.util.stream.Stream;
import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.LambdaForm.BasicType.*;
import static java.lang.invoke.LambdaForm.Kind.*;
import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.MethodHandleStatics.*;
@ -125,9 +126,15 @@ class InvokerBytecodeGenerator {
}
/** For generating customized code for a single LambdaForm. */
InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
this(className, form.debugName, form, invokerType);
}
/** For generating customized code for a single LambdaForm. */
InvokerBytecodeGenerator(String className, String invokerName,
LambdaForm form, MethodType invokerType) {
this(form, form.names.length,
className, form.debugName, invokerType);
className, invokerName, invokerType);
// Create an array to map name indexes to locals indexes.
Name[] names = form.names;
for (int i = 0, index = 0; i < localsMap.length; i++) {
@ -597,10 +604,42 @@ class InvokerBytecodeGenerator {
return c.getName().replace('.', '/');
}
private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
return resolvedMember;
}
private static MemberName lookupPregenerated(LambdaForm form) {
if (form.customized != null) {
// No pre-generated version for customized LF
return null;
}
MethodType invokerType = form.methodType();
String name = form.kind.methodName;
switch (form.kind) {
case BOUND_REINVOKER: {
name = name + "_" + BoundMethodHandle.speciesData(form).fieldSignature();
return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class);
}
case DELEGATE: return resolveFrom(name, invokerType, DelegatingMethodHandle.Holder.class);
case DIRECT_INVOKE_INTERFACE: // fall-through
case DIRECT_INVOKE_SPECIAL: // fall-through
case DIRECT_INVOKE_STATIC: // fall-through
case DIRECT_INVOKE_STATIC_INIT: // fall-through
case DIRECT_INVOKE_VIRTUAL: return resolveFrom(name, invokerType, DirectMethodHandle.Holder.class);
}
return null;
}
/**
* Generate customized bytecode for a given LambdaForm.
*/
static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) {
MemberName pregenerated = lookupPregenerated(form);
if (pregenerated != null) return pregenerated; // pre-generated bytecode
InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType);
return g.loadMethod(g.generateCustomizedCodeBytes());
}

@ -41,6 +41,7 @@ import java.util.HashMap;
import static java.lang.invoke.LambdaForm.BasicType.*;
import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
import static java.lang.invoke.MethodHandleStatics.*;
import java.util.Objects;
/**
* The symbolic, non-executable form of a method handle's invocation semantics.
@ -127,6 +128,7 @@ class LambdaForm {
final MethodHandle customized;
@Stable final Name[] names;
final String debugName;
final Kind kind;
MemberName vmentry; // low-level behavior, or null if not yet prepared
private boolean isCompiled;
@ -266,12 +268,46 @@ class LambdaForm {
}
}
enum Kind {
GENERIC(""),
BOUND_REINVOKER("BMH.reinvoke"),
REINVOKER("MH.reinvoke"),
DELEGATE("MH.delegate"),
DIRECT_INVOKE_VIRTUAL("DMH.invokeVirtual"),
DIRECT_INVOKE_SPECIAL("DMH.invokeSpecial"),
DIRECT_INVOKE_STATIC("DMH.invokeStatic"),
DIRECT_NEW_INVOKE_SPECIAL("DMH.newInvokeSpecial"),
DIRECT_INVOKE_INTERFACE("DMH.invokeInterface"),
DIRECT_INVOKE_STATIC_INIT("DMH.invokeStaticInit");
final String defaultLambdaName;
final String methodName;
private Kind(String defaultLambdaName) {
this.defaultLambdaName = defaultLambdaName;
int p = defaultLambdaName.indexOf('.');
if (p > -1) {
this.methodName = defaultLambdaName.substring(p + 1);
} else {
this.methodName = defaultLambdaName;
}
}
}
LambdaForm(String debugName,
int arity, Name[] names, int result) {
this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null);
this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
}
LambdaForm(String debugName,
int arity, Name[] names, int result, Kind kind) {
this(debugName, arity, names, result, /*forceInline=*/true, /*customized=*/null, kind);
}
LambdaForm(String debugName,
int arity, Name[] names, int result, boolean forceInline, MethodHandle customized) {
this(debugName, arity, names, result, forceInline, customized, Kind.GENERIC);
}
LambdaForm(String debugName,
int arity, Name[] names, int result, boolean forceInline, MethodHandle customized, Kind kind) {
assert(namesOK(arity, names));
this.arity = arity;
this.result = fixResult(result, names);
@ -279,6 +315,7 @@ class LambdaForm {
this.debugName = fixDebugName(debugName);
this.forceInline = forceInline;
this.customized = customized;
this.kind = kind;
int maxOutArity = normalize();
if (maxOutArity > MethodType.MAX_MH_INVOKER_ARITY) {
// Cannot use LF interpreter on very high arity expressions.
@ -288,11 +325,15 @@ class LambdaForm {
}
LambdaForm(String debugName,
int arity, Name[] names) {
this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null);
this(debugName, arity, names, LAST_RESULT, /*forceInline=*/true, /*customized=*/null, Kind.GENERIC);
}
LambdaForm(String debugName,
int arity, Name[] names, boolean forceInline) {
this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null);
this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, Kind.GENERIC);
}
LambdaForm(String debugName,
int arity, Name[] names, boolean forceInline, Kind kind) {
this(debugName, arity, names, LAST_RESULT, forceInline, /*customized=*/null, kind);
}
LambdaForm(String debugName,
Name[] formals, Name[] temps, Name result) {
@ -325,6 +366,7 @@ class LambdaForm {
this.debugName = "LF.zero";
this.forceInline = true;
this.customized = null;
this.kind = Kind.GENERIC;
assert(nameRefsAreLegal());
assert(isEmpty());
String sig = null;
@ -395,7 +437,7 @@ class LambdaForm {
/** Customize LambdaForm for a particular MethodHandle */
LambdaForm customize(MethodHandle mh) {
LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh);
LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh, kind);
if (COMPILE_THRESHOLD >= 0 && isCompiled) {
// If shared LambdaForm has been compiled, compile customized version as well.
customForm.compileToBytecode();
@ -773,28 +815,6 @@ class LambdaForm {
}
}
/**
* Generate optimizable bytecode for this form after first looking for a
* pregenerated version in a specified class.
*/
void compileToBytecode(Class<?> lookupClass) {
if (vmentry != null && isCompiled) {
return; // already compiled somehow
}
MethodType invokerType = methodType();
assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType));
int dot = debugName.indexOf('.');
String methodName = (dot > 0) ? debugName.substring(dot + 1) : debugName;
MemberName member = new MemberName(lookupClass, methodName, invokerType, REF_invokeStatic);
MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, lookupClass);
if (resolvedMember != null) {
vmentry = resolvedMember;
isCompiled = true;
} else {
compileToBytecode();
}
}
private static void computeInitialPreparedForms() {
// Find all predefined invokers and associate them with canonical empty lambda forms.
for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) {

@ -1718,10 +1718,19 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
}
@Override
public byte[] generateDMHClassBytes(String className,
MethodType[] methodTypes, int[] types) {
public byte[] generateDirectMethodHandleHolderClassBytes(
String className, MethodType[] methodTypes, int[] types) {
return GenerateJLIClassesHelper
.generateDMHClassBytes(className, methodTypes, types);
.generateDirectMethodHandleHolderClassBytes(
className, methodTypes, types);
}
@Override
public byte[] generateDelegatingMethodHandleHolderClassBytes(
String className, MethodType[] methodTypes) {
return GenerateJLIClassesHelper
.generateDelegatingMethodHandleHolderClassBytes(
className, methodTypes);
}
@Override

@ -601,7 +601,7 @@ public abstract class Provider extends Properties {
public synchronized Object compute(Object key, BiFunction<? super Object,
? super Object, ? extends Object> remappingFunction) {
check("putProviderProperty." + name);
check("removeProviderProperty" + name);
check("removeProviderProperty." + name);
if (debug != null) {
debug.println("Compute " + name + " provider property " + key);
@ -632,7 +632,7 @@ public abstract class Provider extends Properties {
public synchronized Object computeIfAbsent(Object key, Function<? super Object,
? extends Object> mappingFunction) {
check("putProviderProperty." + name);
check("removeProviderProperty" + name);
check("removeProviderProperty." + name);
if (debug != null) {
debug.println("ComputeIfAbsent " + name + " provider property " +
@ -662,7 +662,7 @@ public abstract class Provider extends Properties {
public synchronized Object computeIfPresent(Object key, BiFunction<? super Object,
? super Object, ? extends Object> remappingFunction) {
check("putProviderProperty." + name);
check("removeProviderProperty" + name);
check("removeProviderProperty." + name);
if (debug != null) {
debug.println("ComputeIfPresent " + name + " provider property " +
@ -695,7 +695,7 @@ public abstract class Provider extends Properties {
public synchronized Object merge(Object key, Object value, BiFunction<? super Object,
? super Object, ? extends Object> remappingFunction) {
check("putProviderProperty." + name);
check("removeProviderProperty" + name);
check("removeProviderProperty." + name);
if (debug != null) {
debug.println("Merge " + name + " provider property " + key);
@ -904,8 +904,8 @@ public abstract class Provider extends Properties {
if (!checkLegacy(key)) {
return null;
}
legacyStrings.computeIfAbsent((String) key,
(Function<? super String, ? extends String>) remappingFunction);
legacyStrings.compute((String) key,
(BiFunction<? super String,? super String, ? extends String>) remappingFunction);
}
return super.compute(key, remappingFunction);
}

@ -399,7 +399,10 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* Calendar Elements in the Unicode Locale Data Markup Language
* (LDML) specification</a> for more details.
*
* @return the month strings.
* @return the month strings. Use
* {@link java.util.Calendar#JANUARY Calendar.JANUARY},
* {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY},
* etc. to index the result array.
*/
public String[] getMonths() {
return Arrays.copyOf(months, months.length);
@ -407,7 +410,9 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* Sets month strings. For example: "January", "February", etc.
* @param newMonths the new month strings.
* @param newMonths the new month strings. The array should
* be indexed by {@link java.util.Calendar#JANUARY Calendar.JANUARY},
* {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, etc.
*/
public void setMonths(String[] newMonths) {
months = Arrays.copyOf(newMonths, newMonths.length);
@ -427,7 +432,10 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* Calendar Elements in the Unicode Locale Data Markup Language
* (LDML) specification</a> for more details.
*
* @return the short month strings.
* @return the short month strings. Use
* {@link java.util.Calendar#JANUARY Calendar.JANUARY},
* {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY},
* etc. to index the result array.
*/
public String[] getShortMonths() {
return Arrays.copyOf(shortMonths, shortMonths.length);
@ -435,7 +443,9 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* Sets short month strings. For example: "Jan", "Feb", etc.
* @param newShortMonths the new short month strings.
* @param newShortMonths the new short month strings. The array should
* be indexed by {@link java.util.Calendar#JANUARY Calendar.JANUARY},
* {@link java.util.Calendar#FEBRUARY Calendar.FEBRUARY}, etc.
*/
public void setShortMonths(String[] newShortMonths) {
shortMonths = Arrays.copyOf(newShortMonths, newShortMonths.length);
@ -444,8 +454,10 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* Gets weekday strings. For example: "Sunday", "Monday", etc.
* @return the weekday strings. Use <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc. to index the result array.
* @return the weekday strings. Use
* {@link java.util.Calendar#SUNDAY Calendar.SUNDAY},
* {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. to index
* the result array.
*/
public String[] getWeekdays() {
return Arrays.copyOf(weekdays, weekdays.length);
@ -454,8 +466,8 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* Sets weekday strings. For example: "Sunday", "Monday", etc.
* @param newWeekdays the new weekday strings. The array should
* be indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
* be indexed by {@link java.util.Calendar#SUNDAY Calendar.SUNDAY},
* {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc.
*/
public void setWeekdays(String[] newWeekdays) {
weekdays = Arrays.copyOf(newWeekdays, newWeekdays.length);
@ -464,8 +476,10 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* Gets short weekday strings. For example: "Sun", "Mon", etc.
* @return the short weekday strings. Use <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc. to index the result array.
* @return the short weekday strings. Use
* {@link java.util.Calendar#SUNDAY Calendar.SUNDAY},
* {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc. to index
* the result array.
*/
public String[] getShortWeekdays() {
return Arrays.copyOf(shortWeekdays, shortWeekdays.length);
@ -474,8 +488,8 @@ public class DateFormatSymbols implements Serializable, Cloneable {
/**
* Sets short weekday strings. For example: "Sun", "Mon", etc.
* @param newShortWeekdays the new short weekday strings. The array should
* be indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
* be indexed by {@link java.util.Calendar#SUNDAY Calendar.SUNDAY},
* {@link java.util.Calendar#MONDAY Calendar.MONDAY}, etc.
*/
public void setShortWeekdays(String[] newShortWeekdays) {
shortWeekdays = Arrays.copyOf(newShortWeekdays, newShortWeekdays.length);

@ -861,6 +861,13 @@ public abstract class SSLEngine {
* be enabled by default, since this list may include cipher suites which
* do not meet quality of service requirements for those defaults. Such
* cipher suites might be useful in specialized applications.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suite names
* @see #getEnabledCipherSuites()
@ -880,6 +887,13 @@ public abstract class SSLEngine {
* or the requisite certificates (and private keys) for the suite are
* not available, or an anonymous suite is enabled but authentication
* is required.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suite names
* @see #getSupportedCipherSuites()
@ -896,6 +910,14 @@ public abstract class SSLEngine {
* fail. Following a successful call to this method, only suites
* listed in the {@code suites} parameter are enabled for use.
* <P>
* Note that the standard list of cipher suite names may be found in the
* <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation. Providers
* may support cipher suite names not found in this list or might not
* use the recommended name for a certain cipher suite.
* <P>
* See {@link #getEnabledCipherSuites()} for more information
* on why a specific cipher suite may never be used on a engine.
*

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 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
@ -108,7 +108,12 @@ public class SSLParameters {
* <p>
* Calling this constructor is equivalent to calling the no-args
* constructor followed by
* {@code setCipherSuites(cipherSuites);}.
* {@code setCipherSuites(cipherSuites);}. Note that the
* standard list of cipher suite names may be found in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation. Providers
* may support cipher suite names not found in this list.
*
* @param cipherSuites the array of ciphersuites (or null)
*/
@ -123,6 +128,12 @@ public class SSLParameters {
* Calling this constructor is equivalent to calling the no-args
* constructor followed by
* {@code setCipherSuites(cipherSuites); setProtocols(protocols);}.
* Note that the standard list of cipher suite names may be found in the
* <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation. Providers
* may support cipher suite names not found in this list.
*
* @param cipherSuites the array of ciphersuites (or null)
* @param protocols the array of protocols (or null)
@ -139,6 +150,13 @@ public class SSLParameters {
/**
* Returns a copy of the array of ciphersuites or null if none
* have been set.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return a copy of the array of ciphersuites or null if none
* have been set.
@ -150,7 +168,13 @@ public class SSLParameters {
/**
* Sets the array of ciphersuites.
*
* @param cipherSuites the array of ciphersuites (or null)
* @param cipherSuites the array of ciphersuites (or null). Note that the
* standard list of cipher suite names may be found in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation. Providers
* may support cipher suite names not found in this list or might not
* use the recommended name for a certain cipher suite.
*/
public void setCipherSuites(String[] cipherSuites) {
this.cipherSuites = clone(cipherSuites);

@ -195,6 +195,13 @@ public abstract class SSLServerSocket extends ServerSocket {
* or the requisite certificates (and private keys) for the suite are
* not available, or an anonymous suite is enabled but authentication
* is required.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suites enabled
* @see #getSupportedCipherSuites()
@ -215,6 +222,14 @@ public abstract class SSLServerSocket extends ServerSocket {
* in this ServerSocket's authentication context will not be used
* in any case, even if they are enabled.
* <P>
* Note that the standard list of cipher suite names may be found in the
* <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation. Providers
* may support cipher suite names not found in this list or might not
* use the recommended name for a certain cipher suite.
* <P>
* <code>SSLSocket</code>s returned from <code>accept()</code>
* inherit this setting.
*
@ -236,6 +251,13 @@ public abstract class SSLServerSocket extends ServerSocket {
* be enabled by default, since this list may include cipher suites which
* do not meet quality of service requirements for those defaults. Such
* cipher suites are useful in specialized applications.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suite names
* @see #getEnabledCipherSuites()

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -123,6 +123,13 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory
* will use one of these cipher suites. The minimum quality of service
* for these defaults requires confidentiality protection and server
* authentication (that is, no anonymous cipher suites).
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @see #getSupportedCipherSuites()
* @return array of the cipher suites enabled by default
@ -137,6 +144,13 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory
* be enabled by default, since this list may include cipher suites which
* do not meet quality of service requirements for those defaults. Such
* cipher suites are useful in specialized applications.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suite names
* @see #getDefaultCipherSuites()

@ -265,6 +265,13 @@ public abstract class SSLSocket extends Socket
* be enabled by default, since this list may include cipher suites which
* do not meet quality of service requirements for those defaults. Such
* cipher suites might be useful in specialized applications.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suite names
* @see #getEnabledCipherSuites()
@ -284,6 +291,13 @@ public abstract class SSLSocket extends Socket
* or the requisite certificates (and private keys) for the suite are
* not available, or an anonymous suite is enabled but authentication
* is required.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suite names
* @see #getSupportedCipherSuites()
@ -300,6 +314,14 @@ public abstract class SSLSocket extends Socket
* fail. Following a successful call to this method, only suites
* listed in the <code>suites</code> parameter are enabled for use.
* <P>
* Note that the standard list of cipher suite names may be found in the
* <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation. Providers
* may support cipher suite names not found in this list or might not
* use the recommended name for a certain cipher suite.
* <P>
* See {@link #getEnabledCipherSuites()} for more information
* on why a specific ciphersuite may never be used on a connection.
*

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -148,6 +148,13 @@ public abstract class SSLSocketFactory extends SocketFactory
* will use one of these cipher suites. The minimum quality of service
* for these defaults requires confidentiality protection and server
* authentication (that is, no anonymous cipher suites).
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @see #getSupportedCipherSuites()
* @return array of the cipher suites enabled by default
@ -160,6 +167,13 @@ public abstract class SSLSocketFactory extends SocketFactory
* be enabled by default, since this list may include cipher suites which
* do not meet quality of service requirements for those defaults. Such
* cipher suites are useful in specialized applications.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#ciphersuites">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @see #getDefaultCipherSuites()
* @return an array of cipher suite names

@ -51,8 +51,17 @@ public interface JavaLangInvokeAccess {
* 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);
byte[] generateDirectMethodHandleHolderClassBytes(String className,
MethodType[] methodTypes, int[] types);
/**
* Returns a {@code byte[]} containing the bytecode for a class implementing
* DelegatingMethodHandles of each {@code MethodType} kind in the
* {@code methodTypes} argument. Used by GenerateJLIClassesPlugin to
* generate such a class during the jlink phase.
*/
byte[] generateDelegatingMethodHandleHolderClassBytes(String className,
MethodType[] methodTypes);
/**
* Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle

@ -24,9 +24,8 @@
*/
/**
* java.base defines and exports the core APIs of the Java SE platform.
* Defines the foundational APIs of the Java SE Platform.
*/
module java.base {
exports java.io;

@ -3631,8 +3631,8 @@ public final class Main {
if (time != null) {
if (time.matches("\\d\\d:\\d\\d:\\d\\d")) {
c.set(Calendar.HOUR_OF_DAY, Integer.valueOf(time.substring(0, 2)));
c.set(Calendar.MINUTE, Integer.valueOf(time.substring(0, 2)));
c.set(Calendar.SECOND, Integer.valueOf(time.substring(0, 2)));
c.set(Calendar.MINUTE, Integer.valueOf(time.substring(3, 5)));
c.set(Calendar.SECOND, Integer.valueOf(time.substring(6, 8)));
c.set(Calendar.MILLISECOND, 0);
} else {
throw ioe;

@ -23,6 +23,9 @@
* questions.
*/
/**
* Aggregates {@code java.base}, {@code java.logging}, and {@code java.scripting}.
*/
module java.compact1 {
requires public java.logging;
requires public java.scripting;

@ -23,6 +23,9 @@
* questions.
*/
/**
* Supplements {@code java.compact1} with JDBC, JAXP, and RMI.
*/
module java.compact2 {
requires public java.compact1;
requires public java.rmi;

@ -23,6 +23,10 @@
* questions.
*/
/**
* Supplements {@code java.compact2} with JDBC RowSet, JMX, JNDI, Compiler,
* Instrumentation, Preferences, Security, and XML cryptography APIs.
*/
module java.compact3 {
requires public java.compact2;
requires public java.compiler;

@ -24,10 +24,8 @@
*/
/**
* Provides interfaces and classes for transferring data between and
* within applications.
* Defines an API for transferring data between and within applications.
*/
module java.datatransfer {
exports java.awt.datatransfer;
exports sun.datatransfer to java.desktop;

@ -24,9 +24,9 @@
*/
/**
* java.desktop defines and exports the user interface, graphics
* and imaging APIs of the Java SE platform.
*/
* Defines the AWT and Swing user interface toolkits, plus APIs for
* accessibility, audio, imaging, printing, and JavaBeans.
*/
module java.desktop {
requires public java.datatransfer;
requires public java.xml;

@ -23,6 +23,9 @@
* questions.
*/
/**
* Defines the high-level HTTP and WebSocket API.
*/
module java.httpclient {
requires java.base;
exports java.net.http;

@ -23,6 +23,10 @@
* questions.
*/
/**
* Defines services that allow agents to
* instrument programs running on the JVM.
*/
module java.instrument {
exports java.lang.instrument;
}

@ -23,6 +23,9 @@
* questions.
*/
/**
* Defines the Java Logging API.
*/
module java.logging {
exports java.util.logging;
provides jdk.internal.logger.DefaultLoggerFinder with

@ -23,6 +23,12 @@
* questions.
*/
/**
* Defines the Java Management Extensions (JMX) API.
* <P>
* The JMX API consists of interfaces for monitoring and management of the
* JVM and other components in the Java runtime.
*/
module java.management {
requires public java.rmi;
requires java.logging;

@ -23,6 +23,9 @@
* questions.
*/
/**
* Defines the Java Naming and Directory Interface (JNDI) API.
*/
module java.naming {
requires java.security.sasl;

@ -23,6 +23,9 @@
* questions.
*/
/**
* Defines the Preferences API.
*/
module java.prefs {
requires java.xml;

@ -23,6 +23,9 @@
* questions.
*/
/**
* Defines the Remote Method Invocation (RMI) API.
*/
module java.rmi {
requires java.logging;

@ -23,6 +23,9 @@
* questions.
*/
/**
* Defines the Scripting API.
*/
module java.scripting {
exports javax.script;
uses javax.script.ScriptEngineFactory;

@ -23,6 +23,12 @@
* questions.
*/
/**
* Defines the full API of the Java SE Platform.
* <P>
* This module requires {@code java.se} and supplements it with modules
* that define CORBA and Java EE APIs. These modules are upgradeable.
*/
module java.se.ee {
requires public java.se;

@ -23,6 +23,13 @@
* questions.
*/
/**
* Defines the core Java SE API.
* <P>
* The modules defining
* CORBA and Java EE APIs are not required by this module, but they are
* required by {@code java.se.ee}.
*/
module java.se {
requires public java.compact3;
requires public java.datatransfer;

@ -23,6 +23,11 @@
* questions.
*/
/**
* Defines the Java binding of the IETF Generic Security Services API (GSS-API).
* <P>
* This module also contains GSS-API mechanisms including Kerberos v5 and SPNEGO.
*/
module java.security.jgss {
requires java.naming;
exports javax.security.auth.kerberos;

@ -23,6 +23,13 @@
* questions.
*/
/**
* Defines Java support for the IETF Simple Authentication and Security Layer
* (SASL).
* <P>
* This module also contains SASL mechanisms including DIGEST-MD5,
* CRAM-MD5, and NTLM.
*/
module java.security.sasl {
requires java.logging;

@ -23,6 +23,9 @@
* questions.
*/
/**
* Defines the Java Smart Card I/O API.
*/
module java.smartcardio {
exports javax.smartcardio;
provides java.security.Provider with sun.security.smartcardio.SunPCSC;

@ -23,6 +23,9 @@
* questions.
*/
/**
* Defines the JDBC RowSet API.
*/
module java.sql.rowset {
requires public java.logging;
requires public java.naming;

@ -64,7 +64,7 @@ import java.sql.Wrapper;
* <P>
* A driver that is accessed via a {@code DataSource} object does not
* register itself with the {@code DriverManager}. Rather, a
* {@code DataSource} object is retrieved though a lookup operation
* {@code DataSource} object is retrieved through a lookup operation
* and then used to create a {@code Connection} object. With a basic
* implementation, the connection obtained through a {@code DataSource}
* object is identical to a connection obtained through the

@ -23,6 +23,9 @@
* questions.
*/
/**
* Defines the JDBC API.
*/
module java.sql {
requires public java.logging;
requires public java.xml;

@ -23,6 +23,12 @@
* questions.
*/
/**
* Defines a subset of the Java Transaction API (JTA) to support CORBA interop.
* <P>
* The subset consists of RMI exception types which are mapped to CORBA system
* exceptions by the 'Java Language to IDL Mapping Specification'.
*/
module java.transaction {
requires public java.rmi;
exports javax.transaction;

@ -23,6 +23,9 @@
* questions.
*/
/**
* Defines an API for XML cryptography.
*/
module java.xml.crypto {
requires public java.xml;
requires java.logging;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 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
@ -30,7 +30,6 @@ import sun.security.util.Length;
/**
* The handle for an RSA or DSA key using the Microsoft Crypto API.
*
* @see DSAPrivateKey
* @see RSAPrivateKey
* @see RSAPublicKey
*
@ -41,9 +40,35 @@ abstract class Key implements java.security.Key, Length
{
private static final long serialVersionUID = -1088859394025049194L;
// Native handle
protected long hCryptProv = 0;
protected long hCryptKey = 0;
static class NativeHandles {
long hCryptProv = 0;
long hCryptKey = 0;
public NativeHandles(long hCryptProv, long hCryptKey) {
this.hCryptProv = hCryptProv;
this.hCryptKey = hCryptKey;
}
/**
* Finalization method
*/
protected void finalize() throws Throwable
{
try {
synchronized(this)
{
cleanUp(hCryptProv, hCryptKey);
hCryptProv = 0;
hCryptKey = 0;
}
} finally {
super.finalize();
}
}
}
protected NativeHandles handles;
// Key length
protected int keyLength = 0;
@ -51,31 +76,12 @@ abstract class Key implements java.security.Key, Length
/**
* Construct a Key object.
*/
protected Key(long hCryptProv, long hCryptKey, int keyLength)
protected Key(NativeHandles handles, int keyLength)
{
this.hCryptProv = hCryptProv;
this.hCryptKey = hCryptKey;
this.handles = handles;
this.keyLength = keyLength;
}
/**
* Finalization method
*/
protected void finalize() throws Throwable
{
try {
synchronized(this)
{
cleanUp(hCryptProv, hCryptKey);
hCryptProv = 0;
hCryptKey = 0;
}
} finally {
super.finalize();
}
}
/**
* Native method to cleanup the key handle.
*/
@ -96,7 +102,7 @@ abstract class Key implements java.security.Key, Length
*/
public long getHCryptKey()
{
return hCryptKey;
return handles.hCryptKey;
}
/**
@ -104,12 +110,12 @@ abstract class Key implements java.security.Key, Length
*/
public long getHCryptProvider()
{
return hCryptProv;
return handles.hCryptProv;
}
/**
* Returns the standard algorithm name for this key. For
* example, "DSA" would indicate that this key is a DSA key.
* example, "RSA" would indicate that this key is a RSA key.
* See Appendix A in the <a href=
* "../../../guide/security/CryptoSpec.html#AppA">
* Java Cryptography Architecture API Specification &amp; Reference </a>

@ -168,7 +168,7 @@ abstract class KeyStore extends KeyStoreSpi {
}
certChain = chain;
}
};
}
/*
* An X.509 certificate factory.
@ -798,7 +798,8 @@ abstract class KeyStore extends KeyStoreSpi {
}
storeWithUniqueAlias(alias, new KeyEntry(alias,
new RSAPrivateKey(hCryptProv, hCryptKey, keyLength),
new RSAPrivateKey(new Key.NativeHandles(hCryptProv,
hCryptKey), keyLength),
certChain));
}
catch (Throwable e)
@ -854,7 +855,6 @@ abstract class KeyStore extends KeyStoreSpi {
* Load keys and/or certificates from keystore into Collection.
*
* @param name Name of keystore.
* @param entries Collection of key/certificate.
*/
private native void loadKeysOrCertificateChains(String name)
throws KeyStoreException;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 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
@ -41,8 +41,9 @@ class RSAKeyPair {
*/
RSAKeyPair(long hCryptProv, long hCryptKey, int keyLength)
{
privateKey = new RSAPrivateKey(hCryptProv, hCryptKey, keyLength);
publicKey = new RSAPublicKey(hCryptProv, hCryptKey, keyLength);
Key.NativeHandles handles = new Key.NativeHandles(hCryptProv, hCryptKey);
privateKey = new RSAPrivateKey(handles, keyLength);
publicKey = new RSAPublicKey(handles, keyLength);
}
public RSAPrivateKey getPrivate() {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 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
@ -42,7 +42,15 @@ class RSAPrivateKey extends Key implements PrivateKey
*/
RSAPrivateKey(long hCryptProv, long hCryptKey, int keyLength)
{
super(hCryptProv, hCryptKey, keyLength);
super(new NativeHandles(hCryptProv, hCryptKey), keyLength);
}
/**
* Construct an RSAPrivateKey object.
*/
RSAPrivateKey(NativeHandles handles, int keyLength)
{
super(handles, keyLength);
}
/**
@ -63,8 +71,8 @@ class RSAPrivateKey extends Key implements PrivateKey
public String toString()
{
return "RSAPrivateKey [size=" + keyLength + " bits, type=" +
getKeyType(hCryptKey) + ", container=" +
getContainerName(hCryptProv) + "]";
getKeyType(handles.hCryptKey) + ", container=" +
getContainerName(handles.hCryptProv) + "]";
}
// This class is not serializable

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -51,7 +51,15 @@ class RSAPublicKey extends Key implements java.security.interfaces.RSAPublicKey
*/
RSAPublicKey(long hCryptProv, long hCryptKey, int keyLength)
{
super(hCryptProv, hCryptKey, keyLength);
super(new NativeHandles(hCryptProv, hCryptKey), keyLength);
}
/**
* Construct an RSAPublicKey object.
*/
RSAPublicKey(NativeHandles handles, int keyLength)
{
super(handles, keyLength);
}
/**
@ -77,8 +85,8 @@ class RSAPublicKey extends Key implements java.security.interfaces.RSAPublicKey
StringBuffer sb = new StringBuffer();
sb.append("RSAPublicKey [size=").append(keyLength)
.append(" bits, type=").append(getKeyType(hCryptKey))
.append(", container=").append(getContainerName(hCryptProv))
.append(" bits, type=").append(getKeyType(handles.hCryptKey))
.append(", container=").append(getContainerName(handles.hCryptProv))
.append("]\n modulus: ").append(getModulus())
.append("\n public exponent: ").append(getPublicExponent());
@ -93,7 +101,7 @@ class RSAPublicKey extends Key implements java.security.interfaces.RSAPublicKey
if (exponent == null) {
try {
publicKeyBlob = getPublicKeyBlob(hCryptKey);
publicKeyBlob = getPublicKeyBlob(handles.hCryptKey);
exponent = new BigInteger(1, getExponent(publicKeyBlob));
} catch (KeyException e) {
@ -112,7 +120,7 @@ class RSAPublicKey extends Key implements java.security.interfaces.RSAPublicKey
if (modulus == null) {
try {
publicKeyBlob = getPublicKeyBlob(hCryptKey);
publicKeyBlob = getPublicKeyBlob(handles.hCryptKey);
modulus = new BigInteger(1, getModulus(publicKeyBlob));
} catch (KeyException e) {

@ -55,7 +55,7 @@ public final class GenerateJLIClassesPlugin implements Plugin {
private static final String DESCRIPTION = PluginsResourceBundle.getDescription(NAME);
private static final String DMH = "java/lang/invoke/DirectMethodHandle$Holder";
private static final String DIRECT_METHOD_HANDLE = "java/lang/invoke/DirectMethodHandle$Holder";
private static final String DMH_INVOKE_VIRTUAL = "invokeVirtual";
private static final String DMH_INVOKE_STATIC = "invokeStatic";
private static final String DMH_INVOKE_SPECIAL = "invokeSpecial";
@ -63,6 +63,8 @@ public final class GenerateJLIClassesPlugin implements Plugin {
private static final String DMH_INVOKE_INTERFACE = "invokeInterface";
private static final String DMH_INVOKE_STATIC_INIT = "invokeStaticInit";
private static final String DELEGATING_METHOD_HANDLE = "java/lang/invoke/DelegatingMethodHandle$Holder";
private static final JavaLangInvokeAccess JLIA
= SharedSecrets.getJavaLangInvokeAccess();
@ -222,7 +224,15 @@ public final class GenerateJLIClassesPlugin implements Plugin {
@Override
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
// Copy all but DMH_ENTRY to out
in.transformAndCopy(entry -> entry.path().equals(DMH_ENTRY) ? null : entry, out);
in.transformAndCopy(entry -> {
// filter out placeholder entries
if (entry.path().equals(DIRECT_METHOD_HANDLE_ENTRY) ||
entry.path().equals(DELEGATING_METHOD_HANDLE_ENTRY)) {
return null;
} else {
return entry;
}
}, out);
speciesTypes.forEach(types -> generateBMHClass(types, out));
generateDMHClass(out);
return out.build();
@ -264,15 +274,24 @@ public final class GenerateJLIClassesPlugin implements Plugin {
}
}
try {
byte[] bytes =
JLIA.generateDMHClassBytes(DMH, methodTypes, dmhTypes);
ResourcePoolEntry ndata = ResourcePoolEntry.create(DMH_ENTRY, bytes);
byte[] bytes = JLIA.generateDirectMethodHandleHolderClassBytes(
DIRECT_METHOD_HANDLE, methodTypes, dmhTypes);
ResourcePoolEntry ndata = ResourcePoolEntry
.create(DIRECT_METHOD_HANDLE_ENTRY, bytes);
out.add(ndata);
bytes = JLIA.generateDelegatingMethodHandleHolderClassBytes(
DELEGATING_METHOD_HANDLE, methodTypes);
ndata = ResourcePoolEntry.create(DELEGATING_METHOD_HANDLE_ENTRY, bytes);
out.add(ndata);
} catch (Exception ex) {
throw new PluginException(ex);
}
}
private static final String DMH_ENTRY = "/java.base/" + DMH + ".class";
private static final String DIRECT_METHOD_HANDLE_ENTRY =
"/java.base/" + DIRECT_METHOD_HANDLE + ".class";
private static final String DELEGATING_METHOD_HANDLE_ENTRY =
"/java.base/" + DELEGATING_METHOD_HANDLE + ".class";
// Convert LL -> LL, L3 -> LLL
private static String expandSignature(String signature) {
@ -310,15 +329,19 @@ public final class GenerateJLIClassesPlugin implements Plugin {
assert(parts.length == 2);
assert(parts[1].length() == 1);
String parameters = expandSignature(parts[0]);
Class<?> rtype = primitiveType(parts[1].charAt(0));
Class<?>[] ptypes = new Class<?>[parameters.length()];
for (int i = 0; i < ptypes.length; i++) {
ptypes[i] = primitiveType(parameters.charAt(i));
Class<?> rtype = simpleType(parts[1].charAt(0));
if (parameters.isEmpty()) {
return MethodType.methodType(rtype);
} else {
Class<?>[] ptypes = new Class<?>[parameters.length()];
for (int i = 0; i < ptypes.length; i++) {
ptypes[i] = simpleType(parameters.charAt(i));
}
return MethodType.methodType(rtype, ptypes);
}
return MethodType.methodType(rtype, ptypes);
}
private static Class<?> primitiveType(char c) {
private static Class<?> simpleType(char c) {
switch (c) {
case 'F':
return float.class;

@ -1,5 +1,5 @@
#
# Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1995, 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
@ -185,6 +185,9 @@ BUNDLE_UP_AND_EXIT = \
( \
jtregExitCode=$$? && \
_summary="$(SUMMARY_TXT)"; \
if [ $${jtregExitCode} = 1 ] ; then \
jtregExitCode=0; \
fi; \
$(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \
$(ECHO) "$${jtregExitCode}" > $(EXITCODE); \
if [ -r "$${_summary}" ] ; then \

@ -211,6 +211,8 @@ sun/rmi/rmic/newrmic/equivalence/run.sh 8145980 generic-
java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-all
sun/rmi/runtime/Log/6409194/NoConsoleOutput.java 8164124 windows-all
############################################################################
# jdk_security

@ -205,8 +205,12 @@ public class VerifyStackTrace {
.replaceAll("java.base@(\\d+\\.){0,3}(\\d+)/", "java.base/")
.replaceAll("/[0-9]+\\.run", "/xxxxxxxx.run")
.replaceAll("/[0-9]+\\.invoke", "/xxxxxxxx.invoke")
// DMHs may or may not be pre-generated, making frames differ
.replaceAll("DirectMethodHandle\\$Holder", "LambdaForm\\$DMH")
.replaceAll("DMH\\.invoke", "DMH/xxxxxxxx.invoke")
// invoke frames may or may not have basic method type
// information encoded for diagnostic purposes
.replaceAll("xx\\.invoke([A-Za-z]*)_[A-Z]+_[A-Z]", "xx.invoke$1")
.replaceAll("\\$[0-9]+", "\\$??");
} else {
return produced;

@ -0,0 +1,90 @@
/*
* 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 8163896
* @summary Finalizing one key of a KeyPair invalidates the other key
*/
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.ProviderException;
import java.security.Security;
import java.util.function.Consumer;
import java.util.ArrayList;
import java.util.List;
public class FinalizeHalf {
static int failures = 0;
public static void main(String[] args) throws Throwable {
List<Consumer<Key>> methods = new ArrayList<>();
methods.add((Key k) -> k.getEncoded());
methods.add((Key k) -> k.toString());
for (String algo : new String[] {"DiffieHellman", "DSA", "RSA"}) {
for (Provider provider : Security.getProviders()) {
for (boolean priv : new boolean[] {true, false}) {
for (Consumer<Key> method : methods) {
test(algo, provider, priv, method);
}
}
}
}
if (failures > 0) {
throw new RuntimeException(failures + " test(s) failed.");
}
}
static void test(String algo, Provider provider, boolean priv,
Consumer<Key> method) throws Exception {
KeyPairGenerator generator;
try {
generator = KeyPairGenerator.getInstance(algo, provider);
} catch (NoSuchAlgorithmException nsae) {
return;
}
System.out.println("Checking " + provider.getName() + ", " + algo);
KeyPair pair = generator.generateKeyPair();
Key key = priv ? pair.getPrivate() : pair.getPublic();
pair = null;
for (int i = 0; i < 32; ++i) {
System.gc();
}
try {
method.accept(key);
} catch (ProviderException pe) {
failures++;
}
}
}

@ -0,0 +1,90 @@
/*
* 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.
*/
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.security.auth.kerberos.KeyTab;
import javax.xml.crypto.KeySelectorException;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import com.sun.security.auth.callback.TextCallbackHandler;
import com.sun.security.jgss.AuthorizationDataEntry;
/*
* @test
* @bug 8159964
* @summary Classes from deprivileged modules should get loaded through
* Platform Classloader.
* @run main DeprivilegedModuleLoaderTest
*/
public class DeprivilegedModuleLoaderTest {
public static void main(String[] args) {
boolean pass = true;
List<Class<?>> classes = getDeprivilegedClasses();
for (Class<?> cls : classes) {
try {
pass &= testPlatformClassLoader(cls);
} catch (Exception exc) {
exc.printStackTrace(System.out);
pass = false;
}
}
if (!pass) {
throw new RuntimeException("Atleast one test failed.");
}
}
private static List<Class<?>> getDeprivilegedClasses() {
List<Class<?>> classes = new ArrayList<Class<?>>();
// Test from java.xml.crypto/javax/xml/crypto/dsig package
classes.add(XMLSignatureFactory.class);
// Test from java.xml.crypto/javax/xml/crypto package
classes.add(KeySelectorException.class);
// Test From java.security.jgss/javax/security/auth/kerberos package
classes.add(KeyTab.class);
// Test from jdk.security.jgss/com/sun/security/jgss package
classes.add(AuthorizationDataEntry.class);
// Test from jdk.security.auth/com/sun/security/auth/callback package
classes.add(TextCallbackHandler.class);
return classes;
}
private static boolean testPlatformClassLoader(Class<?> cls) {
ClassLoader loader = cls.getClassLoader();
if (loader == null) {
throw new RuntimeException(String.format(
"Loaded through Bootstrap Classloader: '%s'", cls));
} else if (!loader.toString().contains("PlatformClassLoader")) {
throw new RuntimeException(String.format(
"Not loaded through Platform ClassLoader: '%s'", cls));
}
System.out.println(String.format(
"Pass: '%s' get loaded through PlatformClassLoader", cls));
return true;
}
}

@ -64,6 +64,8 @@ public class SimpleOCSPServer {
private static final SimpleDateFormat utcDateFmt =
new SimpleDateFormat("MMM dd yyyy, HH:mm:ss z");
static final int FREE_PORT = 0;
// CertStatus values
public static enum CertStatus {
CERT_STATUS_GOOD,
@ -88,7 +90,8 @@ public class SimpleOCSPServer {
private volatile boolean started = false;
private volatile boolean serverReady = false;
private volatile boolean receivedShutdown = false;
private long delayMsec = 0;
private volatile boolean acceptConnections = true;
private volatile long delayMsec = 0;
// Fields used in the generation of responses
private long nextUpdateInterval = -1;
@ -116,7 +119,7 @@ public class SimpleOCSPServer {
*/
public SimpleOCSPServer(KeyStore ks, String password, String issuerAlias,
String signerAlias) throws GeneralSecurityException, IOException {
this(null, 0, ks, password, issuerAlias, signerAlias);
this(null, FREE_PORT, ks, password, issuerAlias, signerAlias);
}
/**
@ -230,6 +233,15 @@ public class SimpleOCSPServer {
while (!receivedShutdown) {
try {
Socket newConnection = servSocket.accept();
if (!acceptConnections) {
try {
log("Reject connection");
newConnection.close();
} catch (IOException e) {
// ignore
}
continue;
}
threadPool.submit(new OcspHandler(newConnection));
} catch (SocketTimeoutException timeout) {
// Nothing to do here. If receivedShutdown
@ -256,6 +268,23 @@ public class SimpleOCSPServer {
});
}
/**
* Make the OCSP server reject incoming connections.
*/
public synchronized void rejectConnections() {
log("Reject OCSP connections");
acceptConnections = false;
}
/**
* Make the OCSP server accept incoming connections.
*/
public synchronized void acceptConnections() {
log("Accept OCSP connections");
acceptConnections = true;
}
/**
* Stop the OCSP server.
*/
@ -499,13 +528,11 @@ public class SimpleOCSPServer {
* on the incoming request.
*/
public void setDelay(long delayMillis) {
if (!started) {
delayMsec = delayMillis > 0 ? delayMillis : 0;
if (delayMsec > 0) {
log("OCSP latency set to " + delayMsec + " milliseconds.");
} else {
log("OCSP latency disabled");
}
delayMsec = delayMillis > 0 ? delayMillis : 0;
if (delayMsec > 0) {
log("OCSP latency set to " + delayMsec + " milliseconds.");
} else {
log("OCSP latency disabled");
}
}

@ -119,20 +119,22 @@ public class SSLSocketWithStapling {
System.setProperty("javax.net.debug", "ssl");
}
// Create the PKI we will use for the test and start the OCSP servers
createPKI();
try {
// Create the PKI we will use for the test and start the OCSP servers
createPKI();
testAllDefault();
testPKIXParametersRevEnabled();
testRevokedCertificate();
testHardFailFallback();
testSoftFailFallback();
testLatencyNoStaple(false);
testLatencyNoStaple(true);
// shut down the OCSP responders before finishing the test
intOcsp.stop();
rootOcsp.stop();
testAllDefault();
testPKIXParametersRevEnabled();
testRevokedCertificate();
testHardFailFallback();
testSoftFailFallback();
testLatencyNoStaple(false);
testLatencyNoStaple(true);
} finally {
// shut down the OCSP responders before finishing the test
intOcsp.stop();
rootOcsp.stop();
}
}
/**
@ -281,11 +283,9 @@ public class SSLSocketWithStapling {
ServerParameters servParams = new ServerParameters();
serverReady = false;
// Stop the OCSP responders and give a 1 second delay before
// running the test.
intOcsp.stop();
rootOcsp.stop();
Thread.sleep(1000);
// make OCSP responders reject connections
intOcsp.rejectConnections();
rootOcsp.rejectConnections();
System.out.println("=======================================");
System.out.println("Stapling enbled in client and server,");
@ -315,9 +315,9 @@ public class SSLSocketWithStapling {
System.out.println(" PASS");
System.out.println("=======================================\n");
// Start the OCSP responders up again
intOcsp.start();
rootOcsp.start();
// Make OCSP responders accept connections
intOcsp.acceptConnections();
rootOcsp.acceptConnections();
// Wait 5 seconds for server ready
for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) {
@ -338,11 +338,9 @@ public class SSLSocketWithStapling {
ServerParameters servParams = new ServerParameters();
serverReady = false;
// Stop the OCSP responders and give a 1 second delay before
// running the test.
intOcsp.stop();
rootOcsp.stop();
Thread.sleep(1000);
// make OCSP responders reject connections
intOcsp.rejectConnections();
rootOcsp.rejectConnections();
System.out.println("=======================================");
System.out.println("Stapling enbled in client and server,");
@ -372,9 +370,9 @@ public class SSLSocketWithStapling {
System.out.println(" PASS");
System.out.println("=======================================\n");
// Start the OCSP responders up again
intOcsp.start();
rootOcsp.start();
// Make OCSP responders accept connections
intOcsp.acceptConnections();
rootOcsp.acceptConnections();
// Wait 5 seconds for server ready
for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) {
@ -401,15 +399,10 @@ public class SSLSocketWithStapling {
ServerParameters servParams = new ServerParameters();
serverReady = false;
// Stop the OCSP responders and give a 1 second delay before
// running the test.
intOcsp.stop();
rootOcsp.stop();
Thread.sleep(1000);
// Give a 1 second delay before running the test.
intOcsp.setDelay(3000);
rootOcsp.setDelay(3000);
rootOcsp.start();
intOcsp.start();
Thread.sleep(1000);
// Wait 5 seconds for server ready
for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) {
@ -458,13 +451,9 @@ public class SSLSocketWithStapling {
System.out.println("========================================\n");
// Remove the OCSP responder latency
intOcsp.stop();
rootOcsp.stop();
Thread.sleep(1000);
intOcsp.setDelay(0);
rootOcsp.setDelay(0);
rootOcsp.start();
intOcsp.start();
Thread.sleep(1000);
// Wait 5 seconds for server ready
for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || !rootOcsp.isServerReady())); i++) {
@ -676,6 +665,7 @@ public class SSLSocketWithStapling {
* Release the client, if not active already...
*/
System.err.println("Server died...");
e.printStackTrace(System.err);
serverReady = true;
serverException = e;
}

@ -26,6 +26,7 @@
* @bug 8022120
* @summary check that the init and marshalParams methods throw
* NullPointerException when the parent parameter is null
* @run main/othervm/java.security.policy==test.policy NullParent
*/
import javax.xml.crypto.dsig.CanonicalizationMethod;

@ -0,0 +1,3 @@
grant {
};

@ -27,7 +27,7 @@
* @summary Test that KeyInfo.marshal works correctly
* @modules java.xml.crypto/org.jcp.xml.dsig.internal.dom
* @compile -XDignore.symbol.file Marshal.java
* @run main Marshal
* @run main/othervm/java.security.policy==test.policy Marshal
* @author Sean Mullan
*/

@ -0,0 +1,3 @@
grant {
permission java.lang.RuntimePermission "accessClassInPackage.org.jcp.xml.dsig.internal.dom";
};

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -103,16 +103,60 @@ public class ClassnameCharTest {
//--------------------- Infrastructure ---------------------------
static volatile int passed = 0, failed = 0;
static boolean pass() {passed++; return true;}
static boolean fail() {failed++; server.stop(0); Thread.dumpStack(); return false;}
static boolean fail(String msg) {System.out.println(msg); return fail();}
static void unexpected(Throwable t) {failed++; server.stop(0); t.printStackTrace();}
static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
static boolean pass() {
passed++;
return true;
}
static boolean fail() {
failed++;
if (server != null) {
server.stop(0);
}
Thread.dumpStack();
return false;
}
static boolean fail(String msg) {
System.out.println(msg);
return fail();
}
static void unexpected(Throwable t) {
failed++;
if (server != null) {
server.stop(0);
}
t.printStackTrace();
}
static boolean check(boolean cond) {
if (cond) {
pass();
} else {
fail();
}
return cond;
}
static boolean equal(Object x, Object y) {
if (x == null ? y == null : x.equals(y)) return pass();
else return fail(x + " not equal to " + y);}
if (x == null ? y == null : x.equals(y)) {
return pass();
} else {
return fail(x + " not equal to " + y);
}
}
public static void main(String[] args) throws Throwable {
try {realMain(args);} catch (Throwable t) {unexpected(t);}
try {
realMain(args);
} catch (Throwable t) {
unexpected(t);
}
System.out.println("\nPassed = " + passed + " failed = " + failed);
if (failed > 0) throw new AssertionError("Some tests failed");}
if (failed > 0) {
throw new AssertionError("Some tests failed");
}
}
}

@ -0,0 +1,86 @@
/*
* 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.
*/
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Matches the krb5 debug output:
* >>> KDCCommunication: kdc=host UDP:11555, timeout=100,Attempt =1, #bytes=138
*
* Example:
* CommMatcher cm = new CommMatcher();
* cm.addPort(12345).addPort(23456);
* for (String line : debugOutput) {
* if (cm.match(line)) {
* println("KDC: %c, %s, Timeout: %d\n",
* cm.kdc(), cm.protocol(), cm.timeout());
* }
* }
*/
public class CommMatcher {
static final Pattern re = Pattern.compile(
">>> KDCCommunication: kdc=\\S+ (TCP|UDP):(\\d+), " +
"timeout=(\\d+),Attempt\\s*=(\\d+)");
List<Integer> kdcPorts = new ArrayList<>();
Matcher matcher;
/**
* Add KDC ports one by one. The 1st KDC will be 'a' in {@link #kdc()},
* 2nd is 'b', etc, etc.
*/
public CommMatcher addPort(int port) {
if (port > 0) {
kdcPorts.add(port);
} else {
kdcPorts.clear();
}
return this;
}
public boolean match(String line) {
matcher = re.matcher(line);
return matcher.find();
}
public String protocol() {
return matcher.group(1);
}
public char kdc() {
int port = Integer.parseInt(matcher.group(2));
return (char)(kdcPorts.indexOf(port) + 'a');
}
public int timeout() {
return BadKdc.toSymbolicSec(Integer.parseInt(matcher.group(3)));
}
public int attempt() {
return Integer.parseInt(matcher.group(4));
}
}

@ -30,6 +30,7 @@
* @summary support max_retries in krb5.conf
*/
import javax.security.auth.login.LoginException;
import java.io.*;
import java.net.DatagramSocket;
import java.security.Security;
@ -37,46 +38,86 @@ import java.security.Security;
public class MaxRetries {
static int idlePort = -1;
static CommMatcher cm = new CommMatcher();
public static void main(String[] args)
throws Exception {
System.setProperty("sun.security.krb5.debug", "true");
new OneKDC(null).writeJAASConf();
OneKDC kdc = new OneKDC(null).writeJAASConf();
// An idle UDP socket to prevent PortUnreachableException
DatagramSocket ds = new DatagramSocket();
idlePort = ds.getLocalPort();
cm.addPort(idlePort);
cm.addPort(kdc.getPort());
System.setProperty("java.security.krb5.conf", "alternative-krb5.conf");
// For tryLast
Security.setProperty("krb5.kdc.bad.policy", "trylast");
// We always make the real timeout to be 1 second
BadKdc.setRatio(0.25f);
rewriteMaxRetries(4);
test1(4000, 6); // 1 1 1 1 2 2
test1(4000, 2); // 2 2
// Explanation: In this case, max_retries=4 and timeout=4s.
// For AS-REQ without preauth, we will see 4 4s timeout on kdc#1
// ("a4" repeat 4 times), and one 4s timeout on kdc#2 ("b4"). For
// AS-REQ with preauth, one 4s timeout on kdc#2 (second "b4").
// we tolerate 4 real timeout on kdc#2, so make it "(b4){2,6}".
test1("a4a4a4a4b4b4", "a4a4a4a4(b4){2,6}");
test1("b4b4", "(b4){2,6}");
BadKdc.setRatio(1f);
rewriteMaxRetries(1);
test1(1000, 3); // 1 2 2
test1(1000, 2); // 2 2
// Explanation: Since max_retries=1 only, we could fail in 1st or 2nd
// AS-REQ to kdc#2.
String actual = test1("a1b1b1", "(a1b1b1|a1b1x|a1b1b1x)");
if (actual.endsWith("x")) {
// If 1st attempt fails, all bads are back available
test1("a1b1b1", "(a1b1b1|a1b1x|a1b1b1x)");
} else {
test1("b1b1", "(b1b1|b1x|b1b1x)");
}
BadKdc.setRatio(0.2f);
rewriteMaxRetries(-1);
test1(5000, 4); // 1 1 2 2
test1(5000, 2); // 2 2
test1("a5a5a5b5b5", "a5a5a5(b5){2,4}");
test1("b5b5", "(b5){2,4}");
// For tryLess
Security.setProperty("krb5.kdc.bad.policy", "tryless:1," + BadKdc.toReal(5000));
BadKdc.setRatio(0.25f);
Security.setProperty("krb5.kdc.bad.policy",
"tryless:1,1000");
rewriteMaxRetries(4);
test1(4000, 7); // 1 1 1 1 2 1 2
test1(4000, 4); // 1 2 1 2
test1("a4a4a4a4b4a4b4", "a4a4a4a4(b4){1,3}a4(b4){1,3}");
test1("a4b4a4b4", "a4(b4){1,3}a4(b4){1,3}");
BadKdc.setRatio(1f);
rewriteMaxRetries(1);
test1(1000, 4); // 1 2 1 2
test1(1000, 4); // 1 2 1 2
actual = test1("a1b1a1b1", "(a1b1|a1b1x|a1b1a1b1|a1b1a1b1x)");
if (actual.endsWith("x")) {
test1("a1b1a1b1", "(a1b1|a1b1x|a1b1a1b1|a1b1a1b1x)");
} else {
test1("a1b1a1b1", "(a1b1|a1b1x|a1b1a1b1|a1b1a1b1x)");
}
BadKdc.setRatio(.2f);
rewriteMaxRetries(-1);
test1(5000, 5); // 1 1 2 1 2
test1(5000, 4); // 1 2 1 2
test1("a5a5a5b5a5b5", "a5a5a5(b5){1,2}a5(b5){1,2}");
test1("a5b5a5b5", "a5(b5){1,2}a5(b5){1,2}");
BadKdc.setRatio(1f);
rewriteMaxRetries(2);
if (BadKdc.toReal(2000) > 1000) {
// Explanation: if timeout is longer than 1s in tryLess,
// we will see "a1" at 2nd kdc#1 access
test1("a2a2b2a1b2", "a2a2(b2){1,2}a1(b2){1,2}");
} else {
test1("a2a2b2a2b2", "a2a2(b2){1,2}a2(b2){1,2}");
}
BadKdc.setRatio(1f);
rewriteUdpPrefLimit(-1, -1); // default, no limit
test2("UDP");
@ -95,32 +136,52 @@ public class MaxRetries {
/**
* One round of test for max_retries and timeout.
* @param timeout the expected timeout
* @param count the expected total try
*
* @param exact the expected exact match, where no timeout
* happens for real KDCs
* @param relaxed the expected relaxed match, where some timeout
* could happen for real KDCs
* @return the actual result
*/
private static void test1(int timeout, int count) throws Exception {
String timeoutTag = "timeout=" + BadKdc.toReal(timeout);
private static String test1(String exact, String relaxed) throws Exception {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
PrintStream oldout = System.out;
System.setOut(new PrintStream(bo));
Context c = Context.fromJAAS("client");
boolean failed = false;
long start = System.nanoTime();
try {
Context c = Context.fromJAAS("client");
} catch (LoginException e) {
failed = true;
}
System.setOut(oldout);
String[] lines = new String(bo.toByteArray()).split("\n");
System.out.println("----------------- TEST (" + timeout + "," +
count + ") -----------------");
System.out.println("----------------- TEST (" + exact
+ ") -----------------");
// Result, a series of timeout + kdc#
StringBuilder sb = new StringBuilder();
for (String line: lines) {
if (line.startsWith(">>> KDCCommunication")) {
if (cm.match(line)) {
System.out.println(line);
if (line.indexOf(timeoutTag) < 0) {
throw new Exception("Wrong timeout value" + timeoutTag);
}
count--;
sb.append(cm.kdc()).append(cm.timeout());
}
}
if (count != 0) {
throw new Exception("Retry count is " + count + " less");
if (failed) {
sb.append("x");
}
System.out.println("Time: " + (System.nanoTime() - start) / 1000000000d);
String actual = sb.toString();
System.out.println("Actual: " + actual);
if (actual.equals(exact)) {
System.out.println("Exact match: " + exact);
} else if (actual.matches(relaxed)) {
System.out.println("!!!! Tolerant match: " + relaxed);
} else {
throw new Exception("Match neither " + exact + " nor " + relaxed);
}
return actual;
}
/**
@ -138,11 +199,11 @@ public class MaxRetries {
String[] lines = new String(bo.toByteArray()).split("\n");
System.out.println("----------------- TEST -----------------");
for (String line: lines) {
if (line.startsWith(">>> KDCCommunication")) {
if (cm.match(line)) {
System.out.println(line);
count--;
if (line.indexOf(proto) < 0) {
throw new Exception("Wrong timeout value");
if (!cm.protocol().equals(proto)) {
throw new Exception("Wrong protocol value");
}
}
}
@ -165,6 +226,7 @@ public class MaxRetries {
}
if (s.startsWith("[realms]")) {
// Reconfig global setting
fw.write("kdc_timeout = 5000\n");
if (global != -1) {
fw.write("udp_preference_limit = " + global + "\n");
}
@ -183,7 +245,8 @@ public class MaxRetries {
/**
* Set max_retries and timeout value for realm. The global value is always
* 2 and 5000.
* 3 and 5000.
*
* @param value max_retries and timeout/1000 for a realm, -1 means none.
*/
private static void rewriteMaxRetries(int value) throws Exception {
@ -196,7 +259,7 @@ public class MaxRetries {
}
if (s.startsWith("[realms]")) {
// Reconfig global setting
fw.write("max_retries = 2\n");
fw.write("max_retries = 3\n");
fw.write("kdc_timeout = " + BadKdc.toReal(5000) + "\n");
} else if (s.trim().startsWith("kdc = ")) {
if (value != -1) {

@ -49,23 +49,31 @@ public class StartDateTest {
new File("jks").delete();
run("-keystore jks -storetype jks -storepass changeit -keypass changeit -alias me " +
"-keyalg rsa -genkeypair -dname CN=Haha -startdate +1y");
cal.setTime(getIssueDate());
run("one", "+1y");
cal.setTime(getIssueDate("one"));
System.out.println(cal);
if (cal.get(Calendar.YEAR) != year + 1) {
throw new Exception("Function check #1 fails");
}
run("-keystore jks -storetype jks -storepass changeit -keypass changeit -alias me " +
"-selfcert -startdate +1m");
cal.setTime(getIssueDate());
run("two", "+1m");
cal.setTime(getIssueDate("two"));
System.out.println(cal);
if (cal.get(Calendar.MONTH) != (month + 1) % 12) {
throw new Exception("Function check #2 fails");
}
new File("jks").delete();
run("three", "2009/10/11 12:34:56");
cal.setTime(getIssueDate("three"));
System.out.println(cal);
if (cal.get(Calendar.YEAR) != 2009 ||
cal.get(Calendar.MONTH) != Calendar.OCTOBER ||
cal.get(Calendar.DAY_OF_MONTH) != 11 ||
cal.get(Calendar.HOUR_OF_DAY) != 12 ||
cal.get(Calendar.MINUTE) != 34 ||
cal.get(Calendar.SECOND) != 56) {
throw new Exception("Function check #3 fails");
}
// Part 2: Test format
Method m = sun.security.tools.keytool.Main.class.getDeclaredMethod(
@ -129,16 +137,23 @@ public class StartDateTest {
}
}
static void run(String s) throws Exception {
sun.security.tools.keytool.Main.main((s+" -debug").split(" "));
// The keytool command line template, alias and startdate TBD
static String[] cmd = ("-alias tbd -startdate tbd -keystore jks " +
"-storetype jks -storepass changeit -keypass changeit " +
"-keyalg rsa -genkeypair -dname CN=Haha -debug").split(" ");
static void run(String alias, String startDate) throws Exception {
cmd[1] = alias;
cmd[3] = startDate;
sun.security.tools.keytool.Main.main(cmd);
}
static Date getIssueDate() throws Exception {
static Date getIssueDate(String alias) throws Exception {
KeyStore ks = KeyStore.getInstance("jks");
try (FileInputStream fis = new FileInputStream("jks")) {
ks.load(fis, "changeit".toCharArray());
}
X509Certificate cert = (X509Certificate)ks.getCertificate("me");
X509Certificate cert = (X509Certificate)ks.getCertificate(alias);
return cert.getNotBefore();
}
}

@ -40,6 +40,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.Optional;
import jdk.testlibrary.JDKToolLauncher;
import jdk.testlibrary.Utils;
import jdk.testlibrary.OutputAnalyzer;
@ -111,7 +112,8 @@ public class BasicLauncherTest {
* @param vmArgs - vm and java arguments to launch test app
* @return exit code of tool
*/
public static void launch(String expectedMessage, List<String> toolArgs)
public static void launch(String expectedMessage,
Optional<String> unexpectedMessage, List<String> toolArgs)
throws IOException {
System.out.println("Starting LingeredApp");
@ -131,6 +133,7 @@ public class BasicLauncherTest {
processBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);;
output.shouldContain(expectedMessage);
unexpectedMessage.ifPresent(output::shouldNotContain);
output.shouldHaveExitValue(0);
} catch (Exception ex) {
@ -140,13 +143,16 @@ public class BasicLauncherTest {
}
}
public static void launch(String expectedMessage, String... toolArgs)
public static void launch(String expectedMessage,
String unexpectedMessage, String... toolArgs)
throws IOException {
launch(expectedMessage, Arrays.asList(toolArgs));
launch(expectedMessage, Optional.ofNullable(unexpectedMessage),
Arrays.asList(toolArgs));
}
public static void launchNotOSX(String expectedMessage, String... toolArgs)
public static void launchNotOSX(String expectedMessage,
String unexpectedMessage, String... toolArgs)
throws IOException {
if (Platform.isOSX()) {
@ -154,6 +160,8 @@ public class BasicLauncherTest {
System.out.println("This test is not expected to work on OS X. Skipping");
return;
}
launch(expectedMessage, unexpectedMessage, toolArgs);
}
public static void testHeapDump() throws IOException {
@ -164,7 +172,7 @@ public class BasicLauncherTest {
}
dump.deleteOnExit();
launch("heap written to", "jmap",
launch("heap written to", null, "jmap",
"--binaryheap", "--dumpfile=" + dump.getAbsolutePath());
assertTrue(dump.exists() && dump.isFile(),
@ -182,11 +190,12 @@ public class BasicLauncherTest {
launchCLHSDB();
launch("compiler detected", "jmap", "--clstats");
launchNotOSX("No deadlocks found", "jstack");
launch("compiler detected", "jmap");
launch("Java System Properties", "jinfo");
launch("java.threads", "jsnap");
launch("compiler detected", null, "jmap", "--clstats");
launchNotOSX("No deadlocks found", null, "jstack");
launch("compiler detected", null, "jmap");
launch("Java System Properties",
"System Properties info not available", "jinfo");
launch("java.threads", null, "jsnap");
testHeapDump();