Merge
This commit is contained in:
commit
591154e8ac
jdk
make/copy
src
java.base/share/classes
com/sun/crypto/provider
java
io
BufferedReader.javaByteArrayOutputStream.javaCharArrayWriter.javaFileSystem.javaObjectInputStream.javaObjectOutputStream.javaObjectStreamClass.javaOutputStreamWriter.javaPrintStream.javaPrintWriter.javaSequenceInputStream.javaStringBufferInputStream.javaStringReader.javaStringWriter.javaWriter.java
lang/invoke
BoundMethodHandle.javaDelegatingMethodHandle.javaDirectMethodHandle.javaGenerateJLIClassesHelper.javaInvokerBytecodeGenerator.javaLambdaForm.javaMethodHandleImpl.java
security
text
javax/net/ssl
SSLEngine.javaSSLParameters.javaSSLServerSocket.javaSSLServerSocketFactory.javaSSLSocket.javaSSLSocketFactory.java
jdk/internal/misc
module-info.javasun/security/tools/keytool
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
KeyPairGenerator
Security/ClassLoader
testlibrary
javax
net/ssl/Stapling
xml/crypto/dsig
sun
misc/URLClassPath
security
tools/jhsdb
@ -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 & 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;
|
||||
|
90
jdk/test/java/security/KeyPairGenerator/FinalizeHalf.java
Normal file
90
jdk/test/java/security/KeyPairGenerator/FinalizeHalf.java
Normal file
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
86
jdk/test/sun/security/krb5/auto/CommMatcher.java
Normal file
86
jdk/test/sun/security/krb5/auto/CommMatcher.java
Normal file
@ -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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user