--- a/.hgtags Wed Oct 19 08:05:48 2016 -0700
+++ b/.hgtags Thu Oct 27 08:52:00 2016 -0700
@@ -383,3 +383,4 @@
d273dfe9a126d3bffe92072547fef2cd1361b0eb jdk-9+138
65477538bec32963dc41153d89c4417eb46c45fc jdk-9+139
0875007901f7d364a08220b052f0c81003e9c8c5 jdk-9+140
+9aadd2163b568d76f8969ad2fb404a63733da359 jdk-9+141
--- a/.hgtags-top-repo Wed Oct 19 08:05:48 2016 -0700
+++ b/.hgtags-top-repo Thu Oct 27 08:52:00 2016 -0700
@@ -383,3 +383,4 @@
67c4388142bdf58aec8fefa4475faaa8a5d7380c jdk-9+138
7dcf453eacae79ee86a6bcc75fd0b546fc99b48a jdk-9+139
a5815c6098a241d3a1df64d22b84b3524e4a77df jdk-9+140
+f64afae7f1a5608e438585bbf0bc23785e69cba0 jdk-9+141
--- a/common/autoconf/flags.m4 Wed Oct 19 08:05:48 2016 -0700
+++ b/common/autoconf/flags.m4 Thu Oct 27 08:52:00 2016 -0700
@@ -759,6 +759,10 @@
# on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
$2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
;;
+ s390 )
+ $2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer -mbackchain -march=z10"
+ $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
+ ;;
* )
$2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
$2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing"
@@ -895,7 +899,7 @@
elif test "x$OPENJDK_$1_OS" = xsolaris; then
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -DSOLARIS"
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -template=no%extdef -features=no%split_init \
- -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ -D_Crun_inline_placement -library=%none -KPIC -mt -features=no%except"
elif test "x$OPENJDK_$1_OS" = xmacosx; then
$2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_ALLBSD_SOURCE"
@@ -940,6 +944,10 @@
# Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -mcpu=power7 -mtune=power8"
fi
+ elif test "x$OPENJDK_$1_CPU" = xs390x; then
+ if test "x$OPENJDK_$1_OS" = xlinux; then
+ $2JVM_CFLAGS="[$]$2JVM_CFLAGS -mbackchain -march=z10"
+ fi
fi
if test "x$OPENJDK_$1_CPU_ENDIAN" = xlittle; then
--- a/common/autoconf/generated-configure.sh Wed Oct 19 08:05:48 2016 -0700
+++ b/common/autoconf/generated-configure.sh Thu Oct 27 08:52:00 2016 -0700
@@ -5093,7 +5093,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1476275292
+DATE_WHEN_GENERATED=1477490418
###############################################################################
#
@@ -49840,6 +49840,10 @@
# on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
;;
+ s390 )
+ COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer -mbackchain -march=z10"
+ CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
+ ;;
* )
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
CFLAGS_JDK="${CFLAGS_JDK} -fno-strict-aliasing"
@@ -50077,7 +50081,7 @@
elif test "x$OPENJDK_TARGET_OS" = xsolaris; then
JVM_CFLAGS="$JVM_CFLAGS -DSOLARIS"
JVM_CFLAGS="$JVM_CFLAGS -template=no%extdef -features=no%split_init \
- -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ -D_Crun_inline_placement -library=%none -KPIC -mt -features=no%except"
elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
JVM_CFLAGS="$JVM_CFLAGS -D_ALLBSD_SOURCE"
@@ -50122,6 +50126,10 @@
# Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
JVM_CFLAGS="$JVM_CFLAGS -mcpu=power7 -mtune=power8"
fi
+ elif test "x$OPENJDK_TARGET_CPU" = xs390x; then
+ if test "x$OPENJDK_TARGET_OS" = xlinux; then
+ JVM_CFLAGS="$JVM_CFLAGS -mbackchain -march=z10"
+ fi
fi
if test "x$OPENJDK_TARGET_CPU_ENDIAN" = xlittle; then
@@ -50655,6 +50663,10 @@
# on ppc we don't prevent gcc to omit frame pointer but do prevent strict aliasing
OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
;;
+ s390 )
+ OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer -mbackchain -march=z10"
+ OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
+ ;;
* )
OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -fno-omit-frame-pointer"
OPENJDK_BUILD_CFLAGS_JDK="${OPENJDK_BUILD_CFLAGS_JDK} -fno-strict-aliasing"
@@ -50892,7 +50904,7 @@
elif test "x$OPENJDK_BUILD_OS" = xsolaris; then
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DSOLARIS"
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -template=no%extdef -features=no%split_init \
- -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ -D_Crun_inline_placement -library=%none -KPIC -mt -features=no%except"
elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_ALLBSD_SOURCE"
@@ -50937,6 +50949,10 @@
# Use Power8, this is the first CPU to support PPC64 LE with ELFv2 ABI.
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mcpu=power7 -mtune=power8"
fi
+ elif test "x$OPENJDK_BUILD_CPU" = xs390x; then
+ if test "x$OPENJDK_BUILD_OS" = xlinux; then
+ OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -mbackchain -march=z10"
+ fi
fi
if test "x$OPENJDK_BUILD_CPU_ENDIAN" = xlittle; then
--- a/common/autoconf/spec.gmk.in Wed Oct 19 08:05:48 2016 -0700
+++ b/common/autoconf/spec.gmk.in Thu Oct 27 08:52:00 2016 -0700
@@ -265,6 +265,10 @@
BUNDLES_OUTPUTDIR=$(BUILD_OUTPUT)/bundles
TESTMAKE_OUTPUTDIR=$(BUILD_OUTPUT)/test-make
MAKESUPPORT_OUTPUTDIR=$(BUILD_OUTPUT)/make-support
+
+# By default, output javadoc directly into image
+JAVADOC_OUTPUTDIR = $(DOCS_IMAGE_DIR)
+
# This does not get overridden in a bootcycle build
CONFIGURESUPPORT_OUTPUTDIR:=@CONFIGURESUPPORT_OUTPUTDIR@
BUILDJDK_OUTPUTDIR=$(BUILD_OUTPUT)/buildjdk
@@ -788,7 +792,7 @@
# Docs image
DOCS_IMAGE_SUBDIR := docs
-DOCS_IMAGE_DIR := $(IMAGES_OUTPUTDIR)/$(DOCS_IMAGE_SUBDIR)
+DOCS_IMAGE_DIR = $(IMAGES_OUTPUTDIR)/$(DOCS_IMAGE_SUBDIR)
# Macosx bundles directory definitions
JDK_MACOSX_BUNDLE_SUBDIR=jdk-bundle
--- a/corba/.hgtags Wed Oct 19 08:05:48 2016 -0700
+++ b/corba/.hgtags Thu Oct 27 08:52:00 2016 -0700
@@ -383,3 +383,4 @@
27bb44be32076861a0951bcefb07a1d92509a4b6 jdk-9+138
8c9da7fc5b07c606afd571c7012441b77dda83b2 jdk-9+139
9f3fc931bc230f44f2a58d75f7f6360af98bb113 jdk-9+140
+b32f998da32b488ec7c4e9dbb3c750841b48e74d jdk-9+141
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java Wed Oct 19 08:05:48 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java Thu Oct 27 08:52:00 2016 -0700
@@ -31,22 +31,17 @@
package com.sun.corba.se.impl.io;
-import java.io.InputStream;
import java.io.IOException;
import java.io.StreamCorruptedException;
import java.io.ObjectInputValidation;
import java.io.NotActiveException;
import java.io.InvalidObjectException;
import java.io.InvalidClassException;
-import java.io.DataInputStream;
import java.io.OptionalDataException;
-import java.io.WriteAbortedException;
import java.io.Externalizable;
import java.io.EOFException;
import java.lang.reflect.*;
import java.util.Vector;
-import java.util.Stack;
-import java.util.Hashtable;
import java.util.Enumeration;
import sun.corba.Bridge ;
@@ -54,7 +49,6 @@
import java.security.AccessController ;
import java.security.PrivilegedAction ;
-import com.sun.corba.se.impl.io.ObjectStreamClass;
import com.sun.corba.se.impl.util.Utility;
import org.omg.CORBA.portable.ValueInputStream;
@@ -71,14 +65,12 @@
import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription;
import com.sun.org.omg.SendingContext.CodeBase;
-import javax.rmi.PortableRemoteObject;
import javax.rmi.CORBA.Util;
import javax.rmi.CORBA.ValueHandler;
import java.security.*;
import java.util.*;
-import com.sun.corba.se.impl.orbutil.ObjectUtility ;
import com.sun.corba.se.impl.logging.OMGSystemException ;
import com.sun.corba.se.impl.logging.UtilSystemException ;
@@ -182,75 +174,6 @@
private byte streamFormatVersion;
- // Since java.io.OptionalDataException's constructors are
- // package private, but we need to throw it in some special
- // cases, we try to do it by reflection.
- private static final Constructor OPT_DATA_EXCEPTION_CTOR;
-
- private Object[] readObjectArgList = { this } ;
-
- static {
- OPT_DATA_EXCEPTION_CTOR = getOptDataExceptionCtor();
- }
-
- // Grab the OptionalDataException boolean ctor and make
- // it accessible. Note that any exceptions
- // will be wrapped in ExceptionInInitializerErrors.
- private static Constructor getOptDataExceptionCtor() {
-
- try {
-
- Constructor result =
-
- (Constructor) AccessController.doPrivileged(
- new PrivilegedExceptionAction() {
- public java.lang.Object run()
- throws NoSuchMethodException,
- SecurityException {
-
- Constructor boolCtor
- = OptionalDataException.class.getDeclaredConstructor(
- new Class[] {
- Boolean.TYPE });
-
- boolCtor.setAccessible(true);
-
- return boolCtor;
- }});
-
- if (result == null)
- // XXX I18N, logging needed.
- throw new Error("Unable to find OptionalDataException constructor");
-
- return result;
-
- } catch (Exception ex) {
- // XXX I18N, logging needed.
- throw new ExceptionInInitializerError(ex);
- }
- }
-
- // Create a new OptionalDataException with the EOF marker
- // set to true. See handleOptionalDataMarshalException.
- private OptionalDataException createOptionalDataException() {
- try {
- OptionalDataException result
- = (OptionalDataException)
- OPT_DATA_EXCEPTION_CTOR.newInstance(new Object[] {
- Boolean.TRUE });
-
- if (result == null)
- // XXX I18N, logging needed.
- throw new Error("Created null OptionalDataException");
-
- return result;
-
- } catch (Exception ex) {
- // XXX I18N, logging needed.
- throw new Error("Couldn't create OptionalDataException", ex);
- }
- }
-
// Return the stream format version currently being used
// to deserialize an object
protected byte getStreamFormatVersion() {
@@ -395,7 +318,6 @@
int offset)
/* throws OptionalDataException, ClassNotFoundException, IOException */
{
-
/* Save the current state and get ready to read an object. */
Object prevObject = currentObject;
ObjectStreamClass prevClassDesc = currentClassDesc;
@@ -947,7 +869,7 @@
if (!objectRead)
result = new EOFException("No more optional data");
else
- result = createOptionalDataException();
+ result = bridge.newOptionalDataExceptionForSerialization(true);
result.initCause(marshalException);
@@ -1230,8 +1152,7 @@
readObjectState.beginUnmarshalCustomValue(this,
calledDefaultWriteObject,
- (currentClassDesc.readObjectMethod
- != null));
+ currentClassDesc.hasReadObject());
} else {
if (currentClassDesc.hasReadObject())
setState(IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED);
@@ -1556,8 +1477,7 @@
readObjectState.beginUnmarshalCustomValue(this,
calledDefaultWriteObject,
- (currentClassDesc.readObjectMethod
- != null));
+ currentClassDesc.hasReadObject());
}
boolean usedReadObject = false;
@@ -1714,13 +1634,8 @@
throws InvalidClassException, StreamCorruptedException,
ClassNotFoundException, IOException
{
- if (osc.readObjectMethod == null) {
- return false;
- }
-
try {
- osc.readObjectMethod.invoke( obj, readObjectArgList ) ;
- return true;
+ return osc.invokeReadObject( obj, this ) ;
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof ClassNotFoundException)
@@ -1734,8 +1649,6 @@
else
// XXX I18N, logging needed.
throw new Error("internal error");
- } catch (IllegalAccessException e) {
- return false;
}
}
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java Wed Oct 19 08:05:48 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java Thu Oct 27 08:52:00 2016 -0700
@@ -31,33 +31,23 @@
package com.sun.corba.se.impl.io;
-import org.omg.CORBA.INTERNAL;
import org.omg.CORBA.portable.OutputStream;
import java.security.AccessController ;
import java.security.PrivilegedAction ;
import java.io.IOException;
-import java.io.DataOutputStream;
-import java.io.Serializable;
import java.io.InvalidClassException;
-import java.io.StreamCorruptedException;
import java.io.Externalizable;
-import java.io.ObjectStreamException;
import java.io.NotSerializableException;
import java.io.NotActiveException;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Field;
-
-import java.util.Stack;
import javax.rmi.CORBA.Util;
-import javax.rmi.CORBA.ValueHandlerMultiFormat;
import sun.corba.Bridge ;
-import com.sun.corba.se.impl.io.ObjectStreamClass;
import com.sun.corba.se.impl.util.Utility;
import com.sun.corba.se.impl.util.RepositoryId;
@@ -621,7 +611,7 @@
writeObjectState.enterWriteObject(this);
// writeObject(obj, c, this);
- osc.writeObjectMethod.invoke( obj, writeObjectArgList ) ;
+ osc.invokeWriteObject( obj, this ) ;
writeObjectState.exitWriteObject(this);
@@ -636,8 +626,6 @@
else
// XXX I18N, Logging needed.
throw new Error("invokeObjectWriter internal error",e);
- } catch (IllegalAccessException e) {
- // cannot happen
}
}
@@ -761,59 +749,52 @@
*/
private void outputClassFields(Object o, Class cl,
ObjectStreamField[] fields)
- throws IOException, InvalidClassException {
+ throws IOException {
for (int i = 0; i < fields.length; i++) {
if (fields[i].getField() == null)
- // XXX I18N, Logging needed.
throw new InvalidClassException(cl.getName(),
"Nonexistent field " + fields[i].getName());
-
- try {
- switch (fields[i].getTypeCode()) {
- case 'B':
- byte byteValue = fields[i].getField().getByte( o ) ;
- orbStream.write_octet(byteValue);
- break;
- case 'C':
- char charValue = fields[i].getField().getChar( o ) ;
- orbStream.write_wchar(charValue);
- break;
- case 'F':
- float floatValue = fields[i].getField().getFloat( o ) ;
- orbStream.write_float(floatValue);
- break;
- case 'D' :
- double doubleValue = fields[i].getField().getDouble( o ) ;
- orbStream.write_double(doubleValue);
- break;
- case 'I':
- int intValue = fields[i].getField().getInt( o ) ;
- orbStream.write_long(intValue);
- break;
- case 'J':
- long longValue = fields[i].getField().getLong( o ) ;
- orbStream.write_longlong(longValue);
- break;
- case 'S':
- short shortValue = fields[i].getField().getShort( o ) ;
- orbStream.write_short(shortValue);
- break;
- case 'Z':
- boolean booleanValue = fields[i].getField().getBoolean( o ) ;
- orbStream.write_boolean(booleanValue);
- break;
- case '[':
- case 'L':
- Object objectValue = fields[i].getField().get( o ) ;
- writeObjectField(fields[i], objectValue);
- break;
- default:
- // XXX I18N, Logging needed.
- throw new InvalidClassException(cl.getName());
- }
- } catch (IllegalAccessException exc) {
- throw wrapper.illegalFieldAccess( exc, fields[i].getName() ) ;
+ switch (fields[i].getTypeCode()) {
+ case 'B':
+ byte byteValue = bridge.getByte(o, fields[i].getFieldID()) ;
+ orbStream.write_octet(byteValue);
+ break;
+ case 'C':
+ char charValue = bridge.getChar(o, fields[i].getFieldID()) ;
+ orbStream.write_wchar(charValue);
+ break;
+ case 'F':
+ float floatValue = bridge.getFloat(o, fields[i].getFieldID()) ;
+ orbStream.write_float(floatValue);
+ break;
+ case 'D' :
+ double doubleValue = bridge.getDouble(o, fields[i].getFieldID()) ;
+ orbStream.write_double(doubleValue);
+ break;
+ case 'I':
+ int intValue = bridge.getInt(o, fields[i].getFieldID()) ;
+ orbStream.write_long(intValue);
+ break;
+ case 'J':
+ long longValue = bridge.getLong(o, fields[i].getFieldID()) ;
+ orbStream.write_longlong(longValue);
+ break;
+ case 'S':
+ short shortValue = bridge.getShort(o, fields[i].getFieldID()) ;
+ orbStream.write_short(shortValue);
+ break;
+ case 'Z':
+ boolean booleanValue = bridge.getBoolean(o, fields[i].getFieldID()) ;
+ orbStream.write_boolean(booleanValue);
+ break;
+ case '[':
+ case 'L':
+ Object objectValue = bridge.getObject(o, fields[i].getFieldID()) ;
+ writeObjectField(fields[i], objectValue);
+ break;
+ default:
+ throw new InvalidClassException(cl.getName());
}
}
}
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java Wed Oct 19 08:05:48 2016 -0700
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java Thu Oct 27 08:52:00 2016 -0700
@@ -31,16 +31,16 @@
package com.sun.corba.se.impl.io;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.invoke.MethodHandle;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.DigestOutputStream;
import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
import java.security.PrivilegedAction;
import java.lang.reflect.Modifier;
-import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
@@ -80,9 +80,6 @@
public static final long kDefaultUID = -1;
- private static Object noArgsList[] = {};
- private static Class<?> noTypesList[] = {};
-
/** true if represents enum type */
private boolean isEnum;
@@ -311,12 +308,37 @@
return null;
}
+ public final boolean invokeWriteObject(Object obj, ObjectOutputStream ois) throws InvocationTargetException {
+ if (!hasWriteObject()) {
+ return false;
+ }
+ try {
+ writeObjectMethod.invoke(obj, ois);
+ } catch (Throwable t) {
+ throw new InvocationTargetException(t, "writeObject");
+ }
+ return true;
+ }
+
+ public final boolean invokeReadObject(Object obj, ObjectInputStream ois) throws InvocationTargetException {
+ if (hasReadObject()) {
+ try {
+ readObjectMethod.invoke(obj, ois);
+ return true;
+ } catch (Throwable t) {
+ throw new InvocationTargetException(t, "readObject");
+ }
+ } else {
+ return false;
+ }
+ }
+
public Serializable writeReplace(Serializable value) {
if (writeReplaceObjectMethod != null) {
try {
- return (Serializable) writeReplaceObjectMethod.invoke(value,noArgsList);
- } catch(Throwable t) {
- throw new RuntimeException(t);
+ return (Serializable) writeReplaceObjectMethod.invoke(value);
+ } catch (Throwable t) {
+ throw new InternalError("unexpected error", t);
}
}
else return value;
@@ -325,9 +347,9 @@
public Object readResolve(Object value) {
if (readResolveObjectMethod != null) {
try {
- return readResolveObjectMethod.invoke(value,noArgsList);
- } catch(Throwable t) {
- throw new RuntimeException(t);
+ return readResolveObjectMethod.invoke(value);
+ } catch (Throwable t) {
+ throw new InternalError("unexpected error", t);
}
}
else return value;
@@ -382,31 +404,34 @@
*/
}
- private static final class PersistentFieldsValue
+ static final class PersistentFieldsValue
extends ClassValue<ObjectStreamField[]> {
PersistentFieldsValue() { }
protected ObjectStreamField[] computeValue(Class<?> type) {
try {
+ bridge.ensureClassInitialized(type);
Field pf = type.getDeclaredField("serialPersistentFields");
int mods = pf.getModifiers();
if (Modifier.isPrivate(mods) && Modifier.isStatic(mods) &&
Modifier.isFinal(mods)) {
- pf.setAccessible(true);
+ long offset = bridge.staticFieldOffset(pf);
java.io.ObjectStreamField[] fields =
- (java.io.ObjectStreamField[])pf.get(type);
+ (java.io.ObjectStreamField[])bridge.getObject(type, offset);
return translateFields(fields);
}
- } catch (NoSuchFieldException | IllegalAccessException |
+ } catch (NoSuchFieldException |
IllegalArgumentException | ClassCastException e) {
}
return null;
}
- private static ObjectStreamField[] translateFields(
- java.io.ObjectStreamField[] fields) {
+ private static ObjectStreamField[] translateFields(java.io.ObjectStreamField[] fields) {
+ if (fields == null) {
+ return null;
+ }
ObjectStreamField[] translation =
- new ObjectStreamField[fields.length];
+ new ObjectStreamField[fields.length];
for (int i = 0; i < fields.length; i++) {
translation[i] = new ObjectStreamField(fields[i].getName(),
fields[i].getType());
@@ -450,13 +475,11 @@
* If it is declared, use the declared serialPersistentFields.
* Otherwise, extract the fields from the class itself.
*/
- fields = persistentFieldsValue.get(cl);
+ fields = persistentFieldsValue.get(cl);
if (fields == null) {
- /* Get all of the declared fields for this
- * Class. setAccessible on all fields so they
- * can be accessed later. Create a temporary
- * ObjectStreamField array to hold each
+ /* Get all of the declared fields for this Class.
+ * Create a temporary ObjectStreamField array to hold each
* non-static, non-transient field. Then copy the
* temporary array into an array of the correct
* size once the number of fields is known.
@@ -471,7 +494,6 @@
int modifiers = fld.getModifiers();
if (!Modifier.isStatic(modifiers) &&
!Modifier.isTransient(modifiers)) {
- fld.setAccessible(true) ;
tempFields[numFields++] = new ObjectStreamField(fld);
}
}
@@ -487,7 +509,6 @@
try {
Field reflField = cl.getDeclaredField(fields[j].getName());
if (fields[j].getType() == reflField.getType()) {
- reflField.setAccessible(true);
fields[j].setField(reflField);
}
} catch (NoSuchFieldException e) {
@@ -527,8 +548,8 @@
int mods = f.getModifiers();
// SerialBug 5: static final SUID should be read
if (Modifier.isStatic(mods) && Modifier.isFinal(mods) ) {
- f.setAccessible(true);
- suid = f.getLong(cl);
+ long offset = bridge.staticFieldOffset(f);
+ suid = bridge.getLong(cl, offset);
// SerialBug 2: should be computed after writeObject
// actualSuid = computeStructuralUID(cl);
} else {
@@ -540,16 +561,12 @@
suid = _computeSerialVersionUID(cl);
// SerialBug 2: should be computed after writeObject
// actualSuid = computeStructuralUID(cl);
- } catch (IllegalAccessException ex) {
- suid = _computeSerialVersionUID(cl);
}
}
- writeReplaceObjectMethod = ObjectStreamClass.getInheritableMethod(cl,
- "writeReplace", noTypesList, Object.class);
+ writeReplaceObjectMethod = bridge.writeReplaceForSerialization(cl);
- readResolveObjectMethod = ObjectStreamClass.getInheritableMethod(cl,
- "readResolve", noTypesList, Object.class);
+ readResolveObjectMethod = bridge.readResolveForSerialization(cl);
if (externalizable)
cons = getExternalizableConstructor(cl) ;
@@ -557,14 +574,8 @@
cons = getSerializableConstructor(cl) ;
if (serializable && !forProxyClass) {
- /* Look for the writeObject method
- * Set the accessible flag on it here. ObjectOutputStream
- * will call it as necessary.
- */
- writeObjectMethod = getPrivateMethod( cl, "writeObject",
- new Class<?>[] { java.io.ObjectOutputStream.class }, Void.TYPE ) ;
- readObjectMethod = getPrivateMethod( cl, "readObject",
- new Class<?>[] { java.io.ObjectInputStream.class }, Void.TYPE ) ;
+ writeObjectMethod = bridge.writeObjectForSerialization(cl) ;
+ readObjectMethod = bridge.readObjectForSerialization(cl);
}
return null;
}
@@ -585,27 +596,6 @@
}
}
- /**
- * Returns non-static private method with given signature defined by given
- * class, or null if none found. Access checks are disabled on the
- * returned method (if any).
- */
- private static Method getPrivateMethod(Class<?> cl, String name,
- Class<?>[] argTypes,
- Class<?> returnType)
- {
- try {
- Method meth = cl.getDeclaredMethod(name, argTypes);
- meth.setAccessible(true);
- int mods = meth.getModifiers();
- return ((meth.getReturnType() == returnType) &&
- ((mods & Modifier.STATIC) == 0) &&
- ((mods & Modifier.PRIVATE) != 0)) ? meth : null;
- } catch (NoSuchMethodException ex) {
- return null;
- }
- }
-
// Specific to RMI-IIOP
/**
* Java to IDL ptc-02-01-12 1.5.1
@@ -849,6 +839,22 @@
}
/**
+ * Returns true if represented class is serializable or externalizable and
+ * defines a conformant writeReplace method. Otherwise, returns false.
+ */
+ boolean hasWriteReplaceMethod() {
+ return (writeReplaceObjectMethod != null);
+ }
+
+ /**
+ * Returns true if represented class is serializable or externalizable and
+ * defines a conformant readResolve method. Otherwise, returns false.
+ */
+ boolean hasReadResolveMethod() {
+ return (readResolveObjectMethod != null);
+ }
+
+ /**
* Returns when or not this class should be custom
* marshaled (use chunking). This should happen if
* it is Externalizable OR if it or
@@ -904,7 +910,7 @@
{
if (cons != null) {
try {
- return cons.newInstance(new Object[0]);
+ return cons.newInstance();
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
InternalError ie = new InternalError();
@@ -912,7 +918,7 @@
throw ie ;
}
} else {
- throw new UnsupportedOperationException();
+ throw new UnsupportedOperationException("no constructor for " + ofClass);
}
}
@@ -921,15 +927,8 @@
* Access checks are disabled on the returned constructor (if any), since
* the defining class may still be non-public.
*/
- private static Constructor getExternalizableConstructor(Class<?> cl) {
- try {
- Constructor cons = cl.getDeclaredConstructor(new Class<?>[0]);
- cons.setAccessible(true);
- return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ?
- cons : null;
- } catch (NoSuchMethodException ex) {
- return null;
- }
+ private static Constructor<?> getExternalizableConstructor(Class<?> cl) {
+ return bridge.newConstructorForExternalization(cl);
}
/**
@@ -937,28 +936,8 @@
* superclass, or null if none found. Access checks are disabled on the
* returned constructor (if any).
*/
- private static Constructor getSerializableConstructor(Class<?> cl) {
- Class<?> initCl = cl;
- while (Serializable.class.isAssignableFrom(initCl)) {
- if ((initCl = initCl.getSuperclass()) == null) {
- return null;
- }
- }
- try {
- Constructor cons = initCl.getDeclaredConstructor(new Class<?>[0]);
- int mods = cons.getModifiers();
- if ((mods & Modifier.PRIVATE) != 0 ||
- ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
- !packageEquals(cl, initCl)))
- {
- return null;
- }
- cons = bridge.newConstructorForSerialization(cl, cons);
- cons.setAccessible(true);
- return cons;
- } catch (NoSuchMethodException ex) {
- return null;
- }
+ private static Constructor<?> getSerializableConstructor(Class<?> cl) {
+ return bridge.newConstructorForSerialization(cl);
}
/*
@@ -1522,11 +1501,11 @@
* @since JDK 1.2
*/
private boolean hasExternalizableBlockData;
- Method writeObjectMethod;
- Method readObjectMethod;
- private transient Method writeReplaceObjectMethod;
- private transient Method readResolveObjectMethod;
- private Constructor cons ;
+ private transient MethodHandle writeObjectMethod;
+ private transient MethodHandle readObjectMethod;
+ private transient MethodHandle writeReplaceObjectMethod;
+ private transient MethodHandle readResolveObjectMethod;
+ private transient Constructor<?> cons;
/**
* Beginning in Java to IDL ptc/02-01-12, RMI-IIOP has a
@@ -1543,44 +1522,12 @@
*/
private ObjectStreamClass localClassDesc;
- /* Find out if the class has a static class initializer <clinit> */
- private static Method hasStaticInitializerMethod = null;
/**
* Returns true if the given class defines a static initializer method,
* false otherwise.
*/
private static boolean hasStaticInitializer(Class<?> cl) {
- if (hasStaticInitializerMethod == null) {
- Class<?> classWithThisMethod = null;
-
- try {
- if (classWithThisMethod == null)
- classWithThisMethod = java.io.ObjectStreamClass.class;
-
- hasStaticInitializerMethod =
- classWithThisMethod.getDeclaredMethod("hasStaticInitializer",
- new Class<?>[] { Class.class });
- } catch (NoSuchMethodException ex) {
- }
-
- if (hasStaticInitializerMethod == null) {
- // XXX I18N, logging needed
- throw new InternalError("Can't find hasStaticInitializer method on "
- + classWithThisMethod.getName());
- }
- hasStaticInitializerMethod.setAccessible(true);
- }
-
- try {
- Boolean retval = (Boolean)
- hasStaticInitializerMethod.invoke(null, new Object[] { cl });
- return retval.booleanValue();
- } catch (Exception ex) {
- // XXX I18N, logging needed
- InternalError ie = new InternalError( "Error invoking hasStaticInitializer" ) ;
- ie.initCause( ex ) ;
- throw ie ;
- }
+ return bridge.hasStaticInitializerForSerialization(cl);
}
@@ -1754,7 +1701,6 @@
if ((meth == null) || (meth.getReturnType() != returnType)) {
return null;
}
- meth.setAccessible(true);
int mods = meth.getModifiers();
if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) {
return null;
--- a/corba/src/java.corba/share/classes/module-info.java Wed Oct 19 08:05:48 2016 -0700
+++ b/corba/src/java.corba/share/classes/module-info.java Thu Oct 27 08:52:00 2016 -0700
@@ -32,6 +32,7 @@
requires java.logging;
requires java.naming;
requires java.transaction;
+ requires jdk.unsupported;
exports javax.activity;
exports javax.rmi;
--- a/corba/src/java.corba/share/classes/sun/corba/Bridge.java Wed Oct 19 08:05:48 2016 -0700
+++ b/corba/src/java.corba/share/classes/sun/corba/Bridge.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -25,25 +25,24 @@
package sun.corba ;
+import java.io.OptionalDataException;
+import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field ;
-import java.lang.reflect.Method ;
import java.lang.reflect.Constructor ;
-import java.lang.reflect.InvocationTargetException ;
-
-import java.io.ObjectInputStream ;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
-import jdk.internal.misc.Unsafe ;
-import jdk.internal.reflect.ReflectionFactory;
+import sun.misc.Unsafe;
+import sun.reflect.ReflectionFactory;
/** This class provides the methods for fundamental JVM operations
* needed in the ORB that are not part of the public Java API. This includes:
* <ul>
* <li>throwException, which can throw undeclared checked exceptions.
- * This is needed to handle throwing arbitrary exceptions across a standardized OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
+ * This is needed to handle throwing arbitrary exceptions across a standardized
+ * OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
* <li>putXXX/getXXX methods that allow unchecked access to fields of objects.
* This is used for setting uninitialzed non-static final fields (which is
* impossible with reflection) and for speed.</li>
@@ -71,88 +70,28 @@
*/
public final class Bridge
{
- private static final Class[] NO_ARGS = new Class[] {};
private static final Permission getBridgePermission =
- new BridgePermission( "getBridge" ) ;
+ new BridgePermission("getBridge");
private static Bridge bridge = null ;
- // latestUserDefinedLoader() is a private static method
- // in ObjectInputStream in JDK 1.3 through 1.5.
- // We use reflection in a doPrivileged block to get a
- // Method reference and make it accessible.
- private final Method latestUserDefinedLoaderMethod ;
- private final Unsafe unsafe ;
- private final ReflectionFactory reflectionFactory ;
+ /** Access to Unsafe to read/write fields. */
+ private static final Unsafe unsafe = AccessController.doPrivileged(
+ (PrivilegedAction<Unsafe>)() -> {
+ try {
+ Field field = Unsafe.class.getDeclaredField("theUnsafe");
+ field.setAccessible(true);
+ return (Unsafe)field.get(null);
- private Method getLatestUserDefinedLoaderMethod()
- {
- return (Method) AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- Method result = null;
-
- try {
- Class io = ObjectInputStream.class;
- result = io.getDeclaredMethod(
- "latestUserDefinedLoader", NO_ARGS);
- result.setAccessible(true);
- } catch (NoSuchMethodException nsme) {
- Error err = new Error( "java.io.ObjectInputStream" +
- " latestUserDefinedLoader " + nsme );
- err.initCause(nsme) ;
- throw err ;
- }
-
- return result;
+ } catch (NoSuchFieldException |IllegalAccessException ex) {
+ throw new InternalError("Unsafe.theUnsafe field not available", ex);
}
}
- );
- }
-
- private Unsafe getUnsafe() {
- Field fld = (Field)AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- Field fld = null ;
+ ) ;
- try {
- Class unsafeClass = jdk.internal.misc.Unsafe.class ;
- fld = unsafeClass.getDeclaredField( "theUnsafe" ) ;
- fld.setAccessible( true ) ;
- return fld ;
- } catch (NoSuchFieldException exc) {
- Error err = new Error( "Could not access Unsafe" ) ;
- err.initCause( exc ) ;
- throw err ;
- }
- }
- }
- ) ;
-
- Unsafe unsafe = null;
+ private final ReflectionFactory reflectionFactory ;
- try {
- unsafe = (Unsafe)(fld.get( null )) ;
- } catch (Throwable t) {
- Error err = new Error( "Could not access Unsafe" ) ;
- err.initCause( t ) ;
- throw err ;
- }
-
- return unsafe ;
- }
-
-
- private Bridge()
- {
- latestUserDefinedLoaderMethod = getLatestUserDefinedLoaderMethod();
- unsafe = getUnsafe() ;
- reflectionFactory = (ReflectionFactory)AccessController.doPrivileged(
- new ReflectionFactory.GetReflectionFactoryAction());
+ private Bridge() {
+ reflectionFactory = ReflectionFactory.getReflectionFactory();
}
/** Fetch the Bridge singleton. This requires the following
@@ -182,23 +121,8 @@
/** Obtain the latest user defined ClassLoader from the call stack.
* This is required by the RMI-IIOP specification.
*/
- public final ClassLoader getLatestUserDefinedLoader()
- {
- try {
- // Invoke the ObjectInputStream.latestUserDefinedLoader method
- return (ClassLoader)latestUserDefinedLoaderMethod.invoke(null,
- (Object[])NO_ARGS);
- } catch (InvocationTargetException ite) {
- Error err = new Error(
- "sun.corba.Bridge.latestUserDefinedLoader: " + ite ) ;
- err.initCause( ite ) ;
- throw err ;
- } catch (IllegalAccessException iae) {
- Error err = new Error(
- "sun.corba.Bridge.latestUserDefinedLoader: " + iae ) ;
- err.initCause( iae ) ;
- throw err ;
- }
+ public final ClassLoader getLatestUserDefinedLoader() {
+ return jdk.internal.misc.VM.latestUserDefinedLoader();
}
/**
@@ -345,6 +269,23 @@
return unsafe.objectFieldOffset( f ) ;
}
+ /**
+ * Returns the offset of a static field.
+ */
+ public final long staticFieldOffset(Field f)
+ {
+ return unsafe.staticFieldOffset( f ) ;
+ }
+
+ /**
+ * Ensure that the class has been initalized.
+ * @param cl the class to ensure is initialized
+ */
+ public final void ensureClassInitialized(Class<?> cl) {
+ unsafe.ensureClassInitialized(cl);
+ }
+
+
/** Throw the exception.
* The exception may be an undeclared checked exception.
*/
@@ -353,16 +294,55 @@
unsafe.throwException( ee ) ;
}
- /** Obtain a constructor for Class cl using constructor cons which
- * may be the constructor defined in a superclass of cl. This is
- * used to create a constructor for Serializable classes that
- * constructs an instance of the Serializable class using the
+ /**
+ * Obtain a constructor for Class cl.
+ * This is used to create a constructor for Serializable classes that
+ * construct an instance of the Serializable class using the
* no args constructor of the first non-Serializable superclass
* of the Serializable class.
*/
- public final Constructor newConstructorForSerialization( Class cl,
- Constructor cons )
- {
- return reflectionFactory.newConstructorForSerialization( cl, cons ) ;
+ public final Constructor<?> newConstructorForSerialization( Class<?> cl ) {
+ return reflectionFactory.newConstructorForSerialization( cl ) ;
+ }
+
+ public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
+ return reflectionFactory.newConstructorForExternalization( cl ) ;
+ }
+
+ /**
+ * Returns true if the given class defines a static initializer method,
+ * false otherwise.
+ */
+ public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
+ return reflectionFactory.hasStaticInitializerForSerialization(cl);
+ }
+
+ public final MethodHandle writeObjectForSerialization(Class<?> cl) {
+ return reflectionFactory.writeObjectForSerialization(cl);
+ }
+
+ public final MethodHandle readObjectForSerialization(Class<?> cl) {
+ return reflectionFactory.readObjectForSerialization(cl);
}
+
+ public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
+ return reflectionFactory.readObjectNoDataForSerialization(cl);
+ }
+
+ public final MethodHandle readResolveForSerialization(Class<?> cl) {
+ return reflectionFactory.readResolveForSerialization(cl);
+ }
+
+ public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
+ return reflectionFactory.writeReplaceForSerialization(cl);
+ }
+
+ /**
+ * Return a new OptionalDataException instance.
+ * @return a new OptionalDataException instance
+ */
+ public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
+ return reflectionFactory.newOptionalDataExceptionForSerialization(bool);
+ }
+
}
--- a/corba/src/java.corba/share/classes/sun/corba/SharedSecrets.java Wed Oct 19 08:05:48 2016 -0700
+++ b/corba/src/java.corba/share/classes/sun/corba/SharedSecrets.java Thu Oct 27 08:52:00 2016 -0700
@@ -25,13 +25,13 @@
package sun.corba;
-import com.sun.corba.se.impl.io.ValueUtility;
-import jdk.internal.misc.Unsafe;
-
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import com.sun.corba.se.impl.io.ValueUtility;
+import sun.misc.Unsafe;
+
/** A repository of "shared secrets", which are a mechanism for
calling implementation-private methods in another package without
using reflection. A package-private class implements a public
@@ -43,22 +43,22 @@
// SharedSecrets cloned in corba repo to avoid build issues
public class SharedSecrets {
- private static final Unsafe unsafe = getUnsafe();
- private static JavaCorbaAccess javaCorbaAccess;
- private static Unsafe getUnsafe() {
- PrivilegedAction<Unsafe> pa = () -> {
- Class<?> unsafeClass = jdk.internal.misc.Unsafe.class ;
- try {
- Field f = unsafeClass.getDeclaredField("theUnsafe");
- f.setAccessible(true);
- return (Unsafe) f.get(null);
- } catch (Exception e) {
- throw new Error(e);
- }
- };
- return AccessController.doPrivileged(pa);
- }
+ /** Access to Unsafe to read/write fields. */
+ private static final Unsafe unsafe = AccessController.doPrivileged(
+ (PrivilegedAction<Unsafe>)() -> {
+ try {
+ Field field = Unsafe.class.getDeclaredField("theUnsafe");
+ field.setAccessible(true);
+ return (Unsafe)field.get(null);
+
+ } catch (NoSuchFieldException |IllegalAccessException ex) {
+ throw new InternalError("Unsafe.theUnsafe field not available", ex);
+ }
+ }
+ );
+
+ private static JavaCorbaAccess javaCorbaAccess;
public static JavaCorbaAccess getJavaCorbaAccess() {
if (javaCorbaAccess == null) {
--- a/hotspot/.hgtags Wed Oct 19 08:05:48 2016 -0700
+++ b/hotspot/.hgtags Thu Oct 27 08:52:00 2016 -0700
@@ -543,3 +543,4 @@
fc0956308c7a586267c5dd35dff74f773aa9c3eb jdk-9+138
08492e67bf3226784dab3bf9ae967382ddbc1af5 jdk-9+139
fec31089c2ef5a12dd64f401b0bf2e00f56ee0d0 jdk-9+140
+160a00bc6ed0af1fdf8418fc65e6bddbbc0c536d jdk-9+141
--- a/hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -1894,6 +1894,22 @@
__ beq(combined_check, slow);
}
+ if (flags & LIR_OpArrayCopy::type_check) {
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) {
+ __ load_klass(tmp, dst);
+ __ lwz(tmp2, in_bytes(Klass::layout_helper_offset()), tmp);
+ __ cmpwi(CCR0, tmp2, Klass::_lh_neutral_value);
+ __ bge(CCR0, slow);
+ }
+
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) {
+ __ load_klass(tmp, src);
+ __ lwz(tmp2, in_bytes(Klass::layout_helper_offset()), tmp);
+ __ cmpwi(CCR0, tmp2, Klass::_lh_neutral_value);
+ __ bge(CCR0, slow);
+ }
+ }
+
// Higher 32bits must be null.
__ extsw(length, length);
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -2034,6 +2034,27 @@
__ delayed()->nop();
}
+ // If the compiler was not able to prove that exact type of the source or the destination
+ // of the arraycopy is an array type, check at runtime if the source or the destination is
+ // an instance type.
+ if (flags & LIR_OpArrayCopy::type_check) {
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) {
+ __ load_klass(dst, tmp);
+ __ lduw(tmp, in_bytes(Klass::layout_helper_offset()), tmp2);
+ __ cmp(tmp2, Klass::_lh_neutral_value);
+ __ br(Assembler::greaterEqual, false, Assembler::pn, *stub->entry());
+ __ delayed()->nop();
+ }
+
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) {
+ __ load_klass(src, tmp);
+ __ lduw(tmp, in_bytes(Klass::layout_helper_offset()), tmp2);
+ __ cmp(tmp2, Klass::_lh_neutral_value);
+ __ br(Assembler::greaterEqual, false, Assembler::pn, *stub->entry());
+ __ delayed()->nop();
+ }
+ }
+
if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
// test src_pos register
__ cmp_zero_and_br(Assembler::less, src_pos, *stub->entry());
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -3146,6 +3146,23 @@
__ jcc(Assembler::zero, *stub->entry());
}
+ // If the compiler was not able to prove that exact type of the source or the destination
+ // of the arraycopy is an array type, check at runtime if the source or the destination is
+ // an instance type.
+ if (flags & LIR_OpArrayCopy::type_check) {
+ if (!(flags & LIR_OpArrayCopy::dst_objarray)) {
+ __ load_klass(tmp, dst);
+ __ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value);
+ __ jcc(Assembler::greaterEqual, *stub->entry());
+ }
+
+ if (!(flags & LIR_OpArrayCopy::src_objarray)) {
+ __ load_klass(tmp, src);
+ __ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value);
+ __ jcc(Assembler::greaterEqual, *stub->entry());
+ }
+ }
+
// check if negative
if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
__ testl(src_pos, src_pos);
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -5859,6 +5859,11 @@
assert(cp != NULL, "invariant");
assert(_loader_data != NULL, "invariant");
+ if (_class_name == vmSymbols::java_lang_Object()) {
+ check_property(_local_interfaces == Universe::the_empty_klass_array(),
+ "java.lang.Object cannot implement an interface in class file %s",
+ CHECK);
+ }
// We check super class after class file is parsed and format is checked
if (_super_class_index > 0 && NULL ==_super_klass) {
Symbol* const super_class_name = cp->klass_name_at(_super_class_index);
--- a/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp Wed Oct 19 08:05:48 2016 -0700
+++ b/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -203,6 +203,7 @@
inline bool verify(address start, address end) const;
inline void print_on(outputStream* st, int current_offset) const;
+ inline void print_truncated(outputStream* st, int current_offset) const;
// Create as_xxx and is_xxx methods for the subtypes
#define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
@@ -263,6 +264,10 @@
void print_on(outputStream* st, int current_offset = -1) const {
st->print("same_frame(@%d)", offset_delta() + current_offset);
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ print_on(st, current_offset);
+ }
};
class same_frame_extended : public stack_map_frame {
@@ -309,6 +314,10 @@
void print_on(outputStream* st, int current_offset = -1) const {
st->print("same_frame_extended(@%d)", offset_delta() + current_offset);
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ print_on(st, current_offset);
+ }
};
class same_locals_1_stack_item_frame : public stack_map_frame {
@@ -381,6 +390,11 @@
types()->print_on(st);
st->print(")");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("same_locals_1_stack_item_frame(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
class same_locals_1_stack_item_extended : public stack_map_frame {
@@ -446,6 +460,11 @@
types()->print_on(st);
st->print(")");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("same_locals_1_stack_item_extended(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
class chop_frame : public stack_map_frame {
@@ -511,6 +530,10 @@
void print_on(outputStream* st, int current_offset = -1) const {
st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops());
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ print_on(st, current_offset);
+ }
};
class append_frame : public stack_map_frame {
@@ -619,6 +642,11 @@
}
st->print(")");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("append_frame(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
class full_frame : public stack_map_frame {
@@ -784,6 +812,11 @@
}
st->print("})");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("full_frame(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
#define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
@@ -841,6 +874,10 @@
FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs));
}
+void stack_map_frame::print_truncated(outputStream* st, int offs = -1) const {
+ FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_truncated, (st, offs));
+}
+
#undef VIRTUAL_DISPATCH
#undef VOID_VIRTUAL_DISPATCH
--- a/hotspot/src/share/vm/classfile/verifier.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -541,8 +541,19 @@
stack_map_frame* sm_frame = sm_table->entries();
streamIndentor si2(ss);
int current_offset = -1;
+ // Subtract two from StackMapAttribute length because the length includes
+ // two bytes for number of table entries.
+ size_t sm_table_space = method->stackmap_data()->length() - 2;
for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
ss->indent();
+ size_t sm_frame_size = sm_frame->size();
+ // If the size of the next stackmap exceeds the length of the entire
+ // stackmap table then print a truncated message and return.
+ if (sm_frame_size > sm_table_space) {
+ sm_frame->print_truncated(ss, current_offset);
+ return;
+ }
+ sm_table_space -= sm_frame_size;
sm_frame->print_on(ss, current_offset);
ss->cr();
current_offset += sm_frame->offset_delta();
--- a/hotspot/src/share/vm/prims/jvm.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -2524,7 +2524,6 @@
switch (cp->tag_at(cp_index).value()) {
case JVM_CONSTANT_InterfaceMethodref:
case JVM_CONSTANT_Methodref:
- case JVM_CONSTANT_NameAndType: // for invokedynamic
return cp->uncached_name_ref_at(cp_index)->as_utf8();
default:
fatal("JVM_GetCPMethodNameUTF: illegal constant");
@@ -2542,7 +2541,6 @@
switch (cp->tag_at(cp_index).value()) {
case JVM_CONSTANT_InterfaceMethodref:
case JVM_CONSTANT_Methodref:
- case JVM_CONSTANT_NameAndType: // for invokedynamic
return cp->uncached_signature_ref_at(cp_index)->as_utf8();
default:
fatal("JVM_GetCPMethodSignatureUTF: illegal constant");
--- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -794,9 +794,10 @@
} else if (new_len == 0) {
value = old_value;
} else {
- char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1, mtArguments);
+ size_t length = old_len + 1 + new_len + 1;
+ char* buf = NEW_C_HEAP_ARRAY(char, length, mtArguments);
// each new setting adds another LINE to the switch:
- sprintf(buf, "%s\n%s", old_value, new_value);
+ jio_snprintf(buf, length, "%s\n%s", old_value, new_value);
value = buf;
free_this_too = buf;
}
@@ -1014,15 +1015,17 @@
if (args == NULL || count == 0) {
return NULL;
}
- size_t length = strlen(args[0]) + 1; // add 1 for the null terminator
- for (int i = 1; i < count; i++) {
- length += strlen(args[i]) + 1; // add 1 for a space
+ size_t length = 0;
+ for (int i = 0; i < count; i++) {
+ length += strlen(args[i]) + 1; // add 1 for a space or NULL terminating character
}
char* s = NEW_RESOURCE_ARRAY(char, length);
- strcpy(s, args[0]);
- for (int j = 1; j < count; j++) {
- strcat(s, " ");
- strcat(s, args[j]);
+ char* dst = s;
+ for (int j = 0; j < count; j++) {
+ size_t offset = strlen(args[j]) + 1; // add 1 for a space or NULL terminating character
+ jio_snprintf(dst, length, "%s ", args[j]); // jio_snprintf will replace the last space character with NULL character
+ dst += offset;
+ length -= offset;
}
return (const char*) s;
}
@@ -1106,9 +1109,8 @@
// Only make the obsolete check for valid arguments.
if (arg_len <= BUFLEN) {
// Construct a string which consists only of the argument name without '+', '-', or '='.
- char stripped_argname[BUFLEN+1];
- strncpy(stripped_argname, argname, arg_len);
- stripped_argname[arg_len] = '\0'; // strncpy may not null terminate.
+ char stripped_argname[BUFLEN+1]; // +1 for '\0'
+ jio_snprintf(stripped_argname, arg_len+1, "%s", argname); // +1 for '\0'
if (is_obsolete_flag(stripped_argname, &since)) {
char version[256];
since.to_string(version, sizeof(version));
@@ -1260,8 +1262,7 @@
size_t key_len = eq - prop;
char* tmp_key = AllocateHeap(key_len + 1, mtArguments);
- strncpy(tmp_key, prop, key_len);
- tmp_key[key_len] = '\0';
+ jio_snprintf(tmp_key, key_len + 1, "%s", prop);
key = tmp_key;
value = &prop[key_len + 1];
@@ -2256,7 +2257,7 @@
// Feed the cache size setting into the JDK
char buffer[1024];
- sprintf(buffer, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);
+ jio_snprintf(buffer, 1024, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);
if (!add_property(buffer)) {
return JNI_ENOMEM;
}
@@ -2777,8 +2778,8 @@
if (tail != NULL) {
const char* pos = strchr(tail, ':');
size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
- char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
- name[len] = '\0';
+ char* name = NEW_C_HEAP_ARRAY(char, len + 1, mtArguments);
+ jio_snprintf(name, len + 1, "%s", tail);
char *options = NULL;
if(pos != NULL) {
@@ -2854,7 +2855,9 @@
return JNI_ERR;
#else
if (tail != NULL) {
- char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtArguments), tail);
+ size_t length = strlen(tail) + 1;
+ char *options = NEW_C_HEAP_ARRAY(char, length, mtArguments);
+ jio_snprintf(options, length, "%s", tail);
add_init_agent("instrument", options, false);
// java agents need module java.instrument
if (!create_numbered_property("jdk.module.addmods", "java.instrument", addmods_count++)) {
@@ -3512,7 +3515,7 @@
// check if the default lib/endorsed directory exists; if so, error
char path[JVM_MAXPATHLEN];
const char* fileSep = os::file_separator();
- sprintf(path, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep);
+ jio_snprintf(path, JVM_MAXPATHLEN, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep);
if (CheckEndorsedAndExtDirs) {
int nonEmptyDirs = 0;
@@ -3534,7 +3537,7 @@
return JNI_ERR;
}
- sprintf(path, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
+ jio_snprintf(path, JVM_MAXPATHLEN, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
dir = os::opendir(path);
if (dir != NULL) {
jio_fprintf(defaultStream::output_stream(),
@@ -3899,6 +3902,13 @@
void Arguments::set_shared_spaces_flags() {
if (DumpSharedSpaces) {
+ if (FailOverToOldVerifier) {
+ // Don't fall back to the old verifier on verification failure. If a
+ // class fails verification with the split verifier, it might fail the
+ // CDS runtime verifier constraint check. In that case, we don't want
+ // to share the class. We only archive classes that pass the split verifier.
+ FLAG_SET_DEFAULT(FailOverToOldVerifier, false);
+ }
if (RequireSharedSpaces) {
warning("Cannot dump shared archive while using shared archive");
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -2881,8 +2881,6 @@
char *s = sig->as_C_string();
int len = (int)strlen(s);
s++; len--; // Skip opening paren
- char *t = s+len;
- while (*(--t) != ')'); // Find close paren
BasicType *sig_bt = NEW_RESOURCE_ARRAY(BasicType, 256);
VMRegPair *regs = NEW_RESOURCE_ARRAY(VMRegPair, 256);
@@ -2891,7 +2889,7 @@
sig_bt[cnt++] = T_OBJECT; // Receiver is argument 0; not in signature
}
- while (s < t) {
+ while (*s != ')') { // Find closing right paren
switch (*s++) { // Switch on signature character
case 'B': sig_bt[cnt++] = T_BYTE; break;
case 'C': sig_bt[cnt++] = T_CHAR; break;
--- a/hotspot/src/share/vm/runtime/signature.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/hotspot/src/share/vm/runtime/signature.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -224,7 +224,49 @@
_index = 0;
expect('(');
Symbol* sig = _signature;
- while (sig->byte_at(_index) != ')') _index++;
+ // Need to skip over each type in the signature's argument list until a
+ // closing ')' is found., then get the return type. We cannot just scan
+ // for the first ')' because ')' is a legal character in a type name.
+ while (sig->byte_at(_index) != ')') {
+ switch(sig->byte_at(_index)) {
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'I':
+ case 'J':
+ case 'S':
+ case 'Z':
+ case 'V':
+ {
+ _index++;
+ }
+ break;
+ case 'L':
+ {
+ while (sig->byte_at(_index++) != ';') ;
+ }
+ break;
+ case '[':
+ {
+ int begin = ++_index;
+ skip_optional_size();
+ while (sig->byte_at(_index) == '[') {
+ _index++;
+ skip_optional_size();
+ }
+ if (sig->byte_at(_index) == 'L') {
+ while (sig->byte_at(_index++) != ';') ;
+ } else {
+ _index++;
+ }
+ }
+ break;
+ default:
+ ShouldNotReachHere();
+ break;
+ }
+ }
expect(')');
// Parse return type
_parameter_index = -1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/c1/TestArrayCopyToFromObject.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,64 @@
+/*
+ * 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 8160591
+ * @summary C1-generated code for System.arraycopy() does not throw an ArrayStoreException if 'dst' is no a "proper" array (i.e., it is java.lang.Object)
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xcomp -XX:-UseCompressedClassPointers -XX:CompileOnly=TestArrayCopyToFromObject.test TestArrayCopyToFromObject
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xcomp -XX:+UseCompressedClassPointers -XX:CompileOnly=TestArrayCopyToFromObject.test TestArrayCopyToFromObject
+ */
+public class TestArrayCopyToFromObject {
+
+ public void test(Object aArray[]) {
+ Object a = new Object();
+
+ try {
+ System.arraycopy(aArray, 0, a, 0, 1);
+ throw new RuntimeException ("FAILED: Expected ArrayStoreException " +
+ "(due to destination not being an array) " +
+ "was not thrown");
+ } catch (ArrayStoreException e) {
+ System.out.println("PASSED: Expected ArrayStoreException was thrown");
+ }
+
+ try {
+ System.arraycopy(a, 0, aArray, 0, 1);
+ throw new RuntimeException ("FAILED: Expected ArrayStoreException " +
+ "(due to source not being an array) " +
+ "was not thrown");
+ } catch (ArrayStoreException e) {
+ System.out.println("PASSED: Expected ArrayStoreException was thrown");
+ }
+
+ }
+
+ public static void main(String args[]) {
+ System.out.println("TestArrayCopyToFromObject");
+ Object aArray[] = new Object[10];
+ for (int i = 0; i < 10; i++) {
+ aArray[i] = new Object();
+ }
+ new TestArrayCopyToFromObject().test(aArray);
+ }
+}
--- a/jaxp/.hgtags Wed Oct 19 08:05:48 2016 -0700
+++ b/jaxp/.hgtags Thu Oct 27 08:52:00 2016 -0700
@@ -383,3 +383,4 @@
69c3b12ba75b2e321dee731ac545e7fbff608451 jdk-9+138
8991d71c5316bde259e6a417c1199b008ca3cdf0 jdk-9+139
8d100cb9b04819b5bd09f33c7fd5b8628d1a456f jdk-9+140
+037c095ba0c345edbeaaab52fda913a76c3930c0 jdk-9+141
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Stylesheet.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Stylesheet.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -31,6 +31,7 @@
import com.sun.org.apache.bcel.internal.generic.GETSTATIC;
import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
+import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
import com.sun.org.apache.bcel.internal.generic.ISTORE;
import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
@@ -1252,6 +1253,10 @@
classGen.getConstantPool());
transf.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException");
+ // call resetPrefixIndex at the beginning of transform
+ final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "resetPrefixIndex", "()V");
+ il.append(new INVOKESTATIC(check));
+
// Define and initialize current with the root node
final LocalVariableGen current =
transf.addLocalVariable("current",
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -31,6 +31,7 @@
import java.text.NumberFormat;
import java.util.Locale;
import java.util.ResourceBundle;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.transform.dom.DOMSource;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
@@ -1533,16 +1534,25 @@
}
/**
- * This function is used in the execution of xsl:element
+ * These functions are used in the execution of xsl:element to generate
+ * and reset namespace prefix index local to current transformation process
*/
- private static int prefixIndex = 0;
-
public static String generatePrefix() {
- synchronized (BasisLibrary.class) {
- return ("ns" + prefixIndex++);
- }
+ return ("ns" + threadLocalPrefixIndex.get().getAndIncrement());
+ }
+
+ public static void resetPrefixIndex() {
+ threadLocalPrefixIndex.get().set(0);
}
+ private static final ThreadLocal<AtomicInteger> threadLocalPrefixIndex =
+ new ThreadLocal<AtomicInteger>() {
+ @Override
+ protected AtomicInteger initialValue() {
+ return new AtomicInteger();
+ }
+ };
+
public static final String RUN_TIME_INTERNAL_ERR =
"RUN_TIME_INTERNAL_ERR";
public static final String RUN_TIME_COPY_ERR =
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/NamespacePrefixTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,193 @@
+/*
+ * 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.
+ */
+
+package transform;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertTrue;
+import static jaxp.library.JAXPTestUtilities.runWithAllPerm;
+
+/*
+ * @test
+ * @bug 8167179
+ * @library /javax/xml/jaxp/libs
+ * @run testng/othervm -DrunSecMngr=true transform.NamespacePrefixTest
+ * @run testng/othervm transform.NamespacePrefixTest
+ * @summary This class tests the generation of namespace prefixes
+ */
+public class NamespacePrefixTest {
+
+ @Test
+ public void testReuseTemplates() throws Exception {
+ final TransformerFactory tf = TransformerFactory.newInstance();
+ final Source xslsrc = new StreamSource(new StringReader(XSL));
+ final Templates tmpl = tf.newTemplates(xslsrc);
+ for (int i = 0; i < TRANSF_COUNT; i++) {
+ checkResult(doTransformation(tmpl.newTransformer()));
+ }
+ }
+
+ @Test
+ public void testReuseTransformer() throws Exception {
+ final TransformerFactory tf = TransformerFactory.newInstance();
+ final Source xslsrc = new StreamSource(new StringReader(XSL));
+ final Transformer t = tf.newTransformer(xslsrc);
+ for (int i = 0; i < TRANSF_COUNT; i++) {
+ checkResult(doTransformation(t));
+ }
+ }
+
+ @Test
+ public void testConcurrentTransformations() throws Exception {
+ final TransformerFactory tf = TransformerFactory.newInstance();
+ final Source xslsrc = new StreamSource(new StringReader(XSL));
+ final Templates tmpl = tf.newTemplates(xslsrc);
+ concurrentTestPassed.set(true);
+
+ // Execute multiple TestWorker tasks
+ for (int id = 0; id < THREADS_COUNT; id++) {
+ EXECUTOR.execute(new TransformerThread(tmpl.newTransformer(), id));
+ }
+ // Initiate shutdown of previously submitted task
+ runWithAllPerm(EXECUTOR::shutdown);
+ // Wait for termination of submitted tasks
+ if (!EXECUTOR.awaitTermination(THREADS_COUNT, TimeUnit.SECONDS)) {
+ // If not all tasks terminates during the time out force them to shutdown
+ runWithAllPerm(EXECUTOR::shutdownNow);
+ }
+ // Check if all transformation threads generated the correct namespace prefix
+ assertTrue(concurrentTestPassed.get());
+ }
+
+ // Do one transformation with the provided transformer
+ private static String doTransformation(Transformer t) throws Exception {
+ StringWriter resWriter = new StringWriter();
+ Source xmlSrc = new StreamSource(new StringReader(XML));
+ t.transform(xmlSrc, new StreamResult(resWriter));
+ return resWriter.toString();
+ }
+
+ // Check if the transformation result string contains the
+ // element with the exact namespace prefix generated.
+ private static void checkResult(String result) {
+ // Check prefix of 'Element2' element, it should always be the same
+ assertTrue(result.contains(EXPECTED_CONTENT));
+ }
+
+ // Check if the transformation result string contains the element with
+ // the exact namespace prefix generated by current thread.
+ // If the expected prefix is not found and there was no failures observed by
+ // other test threads then mark concurrent test as failed.
+ private static void checkThreadResult(String result, int id) {
+ boolean res = result.contains(EXPECTED_CONTENT);
+ System.out.printf("%d: transformation result: %s%n", id, res ? "Pass" : "Fail");
+ if (!res) {
+ System.out.printf("%d result:%s%n", id, result);
+ }
+ concurrentTestPassed.compareAndSet(true, res);
+ }
+
+ // TransformerThread task that does the transformation similar
+ // to testReuseTransformer test method
+ private class TransformerThread implements Runnable {
+
+ private final Transformer transformer;
+ private final int id;
+
+ TransformerThread(Transformer transformer, int id) {
+ this.transformer = transformer;
+ this.id = id;
+ }
+
+ @Override
+ public void run() {
+ try {
+ System.out.printf("%d: waiting for barrier%n", id);
+ //Synchronize startup of all tasks
+ BARRIER.await();
+ System.out.printf("%d: starting transformation%n", id);
+ checkThreadResult(doTransformation(transformer), id);
+ } catch (Exception ex) {
+ throw new RuntimeException("TransformerThread " + id + " failed", ex);
+ }
+ }
+ }
+
+ // Number of subsequent transformations
+ private static final int TRANSF_COUNT = 10;
+
+ // Number of transformer threads running concurently
+ private static final int THREADS_COUNT = 10;
+
+ // Variable for storing the concurrent transformation test result. It is
+ // updated by transformer threads
+ private static final AtomicBoolean concurrentTestPassed = new AtomicBoolean(true);
+
+ // Cyclic barrier for threads startup synchronization
+ private static final CyclicBarrier BARRIER = new CyclicBarrier(THREADS_COUNT);
+
+ // Thread pool
+ private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool();
+
+ // XSL that transforms XML and produces unique namespace prefixes for each element
+ private final static String XSL = "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n"
+ + " <xsl:template match=\"node()|@*\" priority=\"1\">\n"
+ + " <xsl:copy>\n"
+ + " <xsl:apply-templates select=\"node()|@*\"/>\n"
+ + " </xsl:copy>\n"
+ + " </xsl:template>\n"
+ + " <xsl:template match=\"*\" priority=\"2\">\n"
+ + " <xsl:element name=\"{name()}\" namespace=\"{namespace-uri()}\">\n"
+ + " <xsl:apply-templates select=\"node()|@*\"/>\n"
+ + " </xsl:element>\n"
+ + " </xsl:template>\n"
+ + "</xsl:stylesheet>";
+
+ // Simple XML content with root and two child elements
+ private final static String XML = "<TestRoot xmlns=\"test.xmlns\">\n"
+ + " <Element1 xmlns=\"test.xmlns\">\n"
+ + " </Element1>\n"
+ + " <Element2 xmlns=\"test.xmlns\">\n"
+ + " </Element2>\n"
+ + "</TestRoot>";
+
+ // With thread local namespace prefix index each transformation result should
+ // be the same and contain the same prefix for Element2
+ private final static String EXPECTED_CONTENT = "</ns2:Element2>";
+
+}
--- a/jaxws/.hgtags Wed Oct 19 08:05:48 2016 -0700
+++ b/jaxws/.hgtags Thu Oct 27 08:52:00 2016 -0700
@@ -386,3 +386,4 @@
7d3a8f52b124db26ba8425c2931b748dd9d2791b jdk-9+138
7a7aadf3c4500cc273c889aa1172d4fe3844bb6b jdk-9+139
9004617323fe99cbe4fad48f373cb2ed4fc50aa6 jdk-9+140
+b2c18f755228d1d19a86cd7d5fa1abb6b1495dfb jdk-9+141
--- a/jdk/.hgtags Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/.hgtags Thu Oct 27 08:52:00 2016 -0700
@@ -383,3 +383,4 @@
665096863382bf23ce891307cf2a7511e77c1c88 jdk-9+138
5518ac2f2ead5e594bd983f2047178136aafdfd0 jdk-9+139
e93b7ea559759f036c9f69fd2ddaf47bb4e98385 jdk-9+140
+8d752af5f61d41f226adf2cda72a20faa9ad620a jdk-9+141
--- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -1413,27 +1413,7 @@
* returned constructor (if any).
*/
private static Constructor<?> getSerializableConstructor(Class<?> cl) {
- Class<?> initCl = cl;
- while (Serializable.class.isAssignableFrom(initCl)) {
- if ((initCl = initCl.getSuperclass()) == null) {
- return null;
- }
- }
- try {
- Constructor<?> cons = initCl.getDeclaredConstructor((Class<?>[]) null);
- int mods = cons.getModifiers();
- if ((mods & Modifier.PRIVATE) != 0 ||
- ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
- !packageEquals(cl, initCl)))
- {
- return null;
- }
- cons = reflFactory.newConstructorForSerialization(cl, cons);
- cons.setAccessible(true);
- return cons;
- } catch (NoSuchMethodException ex) {
- return null;
- }
+ return reflFactory.newConstructorForSerialization(cl);
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Thu Oct 27 08:52:00 2016 -0700
@@ -557,7 +557,7 @@
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
int modifiers = tmpConstructor.getModifiers();
- Reflection.ensureMemberAccess(caller, this, null, modifiers);
+ Reflection.ensureMemberAccess(caller, this, this, modifiers);
newInstanceCallerCache = caller;
}
// Run constructor
--- a/jdk/src/java.base/share/classes/java/lang/Deprecated.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Deprecated.java Thu Oct 27 08:52:00 2016 -0700
@@ -79,7 +79,7 @@
/**
* Returns the version in which the annotated element became deprecated.
* The version string is in the same format and namespace as the value of
- * the {@code @since} javadoc tag. The default value is the empty
+ * the {@code @since} javadoc tag. The default value is the empty
* string.
*
* @return the version string
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java Thu Oct 27 08:52:00 2016 -0700
@@ -504,11 +504,12 @@
}
/**
- * Creates a new Thread that inherits the given AccessControlContext.
+ * Creates a new Thread that inherits the given AccessControlContext
+ * but thread-local variables are not inherited.
* This is not a public constructor.
*/
Thread(Runnable target, AccessControlContext acc) {
- init(null, target, "Thread-" + nextThreadNum(), 0, acc, true);
+ init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Thu Oct 27 08:52:00 2016 -0700
@@ -44,6 +44,8 @@
import jdk.internal.jimage.ImageLocation;
import jdk.internal.jimage.ImageReader;
import jdk.internal.jimage.ImageReaderFactory;
+import jdk.internal.misc.JavaNetUriAccess;
+import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleHashes.HashSupplier;
import jdk.internal.module.SystemModules;
@@ -71,6 +73,8 @@
// ImageReader used to access all modules in the image
private static final ImageReader imageReader;
+ private static final JavaNetUriAccess jnua = SharedSecrets.getJavaNetUriAccess();
+
// the set of modules in the run-time image
private static final Set<ModuleReference> modules;
@@ -166,7 +170,8 @@
HashSupplier hash)
{
String mn = md.name();
- URI uri = URI.create("jrt:/" + mn);
+
+ URI uri = jnua.create("jrt", "/".concat(mn));
Supplier<ModuleReader> readerSupplier = new Supplier<>() {
@Override
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Thu Oct 27 08:52:00 2016 -0700
@@ -312,22 +312,22 @@
// (See also Class.newInstance(), which uses a similar method.)
//
// A more complicated security check cache is needed for Method and Field
- // The cache can be either null (empty cache), a 2-array of {caller,target},
- // or a caller (with target implicitly equal to this.clazz).
- // In the 2-array case, the target is always different from the clazz.
+ // The cache can be either null (empty cache), a 2-array of {caller,targetClass},
+ // or a caller (with targetClass implicitly equal to memberClass).
+ // In the 2-array case, the targetClass is always different from the memberClass.
volatile Object securityCheckCache;
- void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers)
+ final void checkAccess(Class<?> caller, Class<?> memberClass,
+ Class<?> targetClass, int modifiers)
throws IllegalAccessException
{
- if (caller == clazz) { // quick check
+ if (caller == memberClass) { // quick check
return; // ACCESS IS OK
}
Object cache = securityCheckCache; // read volatile
- Class<?> targetClass = clazz;
- if (obj != null
+ if (targetClass != null // instance member or constructor
&& Modifier.isProtected(modifiers)
- && ((targetClass = obj.getClass()) != clazz)) {
+ && targetClass != memberClass) {
// Must match a 2-list of { caller, targetClass }.
if (cache instanceof Class[]) {
Class<?>[] cache2 = (Class<?>[]) cache;
@@ -339,25 +339,27 @@
// subsumes range check for [0].)
}
} else if (cache == caller) {
- // Non-protected case (or obj.class == this.clazz).
+ // Non-protected case (or targetClass == memberClass or static member).
return; // ACCESS IS OK
}
// If no return, fall through to the slow path.
- slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
+ slowCheckMemberAccess(caller, memberClass, targetClass, modifiers);
}
// Keep all this slow stuff out of line:
- void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers,
- Class<?> targetClass)
+ void slowCheckMemberAccess(Class<?> caller, Class<?> memberClass,
+ Class<?> targetClass, int modifiers)
throws IllegalAccessException
{
- Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
+ Reflection.ensureMemberAccess(caller, memberClass, targetClass, modifiers);
// Success: Update the cache.
- Object cache = ((targetClass == clazz)
- ? caller
- : new Class<?>[] { caller, targetClass });
+ Object cache = (targetClass != null
+ && Modifier.isProtected(modifiers)
+ && targetClass != memberClass)
+ ? new Class<?>[] { caller, targetClass }
+ : caller;
// Note: The two cache elements are not volatile,
// but they are effectively final. The Java memory model
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Thu Oct 27 08:52:00 2016 -0700
@@ -443,7 +443,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, null, modifiers);
+ checkAccess(caller, clazz, clazz, modifiers);
}
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Thu Oct 27 08:52:00 2016 -0700
@@ -403,7 +403,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).get(obj);
}
@@ -437,7 +437,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getBoolean(obj);
}
@@ -471,7 +471,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getByte(obj);
}
@@ -507,7 +507,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getChar(obj);
}
@@ -543,7 +543,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getShort(obj);
}
@@ -579,7 +579,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getInt(obj);
}
@@ -615,7 +615,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getLong(obj);
}
@@ -651,7 +651,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getFloat(obj);
}
@@ -687,7 +687,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getDouble(obj);
}
@@ -765,7 +765,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).set(obj, value);
}
@@ -801,7 +801,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setBoolean(obj, z);
}
@@ -837,7 +837,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setByte(obj, b);
}
@@ -873,7 +873,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setChar(obj, c);
}
@@ -909,7 +909,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setShort(obj, s);
}
@@ -945,7 +945,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setInt(obj, i);
}
@@ -981,7 +981,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setLong(obj, l);
}
@@ -1017,7 +1017,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setFloat(obj, f);
}
@@ -1053,11 +1053,20 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setDouble(obj, d);
}
+ // check access to field
+ private void checkAccess(Class<?> caller, Object obj)
+ throws IllegalAccessException
+ {
+ checkAccess(caller, clazz,
+ Modifier.isStatic(modifiers) ? null : obj.getClass(),
+ modifiers);
+ }
+
// security check is done before calling this method
private FieldAccessor getFieldAccessor(Object obj)
throws IllegalAccessException
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Thu Oct 27 08:52:00 2016 -0700
@@ -526,7 +526,9 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, clazz,
+ Modifier.isStatic(modifiers) ? null : obj.getClass(),
+ modifiers);
}
MethodAccessor ma = methodAccessor; // read volatile
if (ma == null) {
--- a/jdk/src/java.base/share/classes/java/net/InetAddress.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java Thu Oct 27 08:52:00 2016 -0700
@@ -321,6 +321,13 @@
public String getOriginalHostName(InetAddress ia) {
return ia.holder.getOriginalHostName();
}
+
+ public InetAddress getByName(String hostName,
+ InetAddress hostAddress)
+ throws UnknownHostException
+ {
+ return InetAddress.getByName(hostName, hostAddress);
+ }
}
);
init();
--- a/jdk/src/java.base/share/classes/java/net/URI.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/net/URI.java Thu Oct 27 08:52:00 2016 -0700
@@ -37,6 +37,9 @@
import java.nio.charset.CodingErrorAction;
import java.nio.charset.CharacterCodingException;
import java.text.Normalizer;
+import jdk.internal.loader.URLClassPath;
+import jdk.internal.misc.JavaNetUriAccess;
+import jdk.internal.misc.SharedSecrets;
import sun.nio.cs.ThreadLocalCoders;
import java.lang.Character; // for javadoc
@@ -820,6 +823,25 @@
}
/**
+ * Constructs a simple URI consisting of only a scheme and a pre-validated
+ * path. Provides a fast-path for some internal cases.
+ */
+ URI(String scheme, String path) {
+ assert validSchemeAndPath(scheme, path);
+ this.scheme = scheme;
+ this.path = path;
+ }
+
+ private static boolean validSchemeAndPath(String scheme, String path) {
+ try {
+ URI u = new URI(scheme + ":" + path);
+ return scheme.equals(u.scheme) && path.equals(u.path);
+ } catch (URISyntaxException e) {
+ return false;
+ }
+ }
+
+ /**
* Creates a URI by parsing the given string.
*
* <p> This convenience factory method works as if by invoking the {@link
@@ -3571,5 +3593,13 @@
}
}
-
+ static {
+ SharedSecrets.setJavaNetUriAccess(
+ new JavaNetUriAccess() {
+ public URI create(String scheme, String path) {
+ return new URI(scheme, path);
+ }
+ }
+ );
+ }
}
--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, 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
@@ -51,7 +51,7 @@
import jdk.internal.loader.Resource;
import jdk.internal.loader.URLClassPath;
-import jdk.internal.misc.JavaNetAccess;
+import jdk.internal.misc.JavaNetURLClassLoaderAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.perf.PerfCounter;
import sun.net.www.ParseUtil;
@@ -767,10 +767,11 @@
}
static {
- SharedSecrets.setJavaNetAccess(
- new JavaNetAccess() {
- public URLClassPath getURLClassPath(URLClassLoader u) {
- return u.ucp;
+ SharedSecrets.setJavaNetURLClassLoaderAccess(
+ new JavaNetURLClassLoaderAccess() {
+ @Override
+ public AccessControlContext getAccessControlContext(URLClassLoader u) {
+ return u.acc;
}
}
);
--- a/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Thu Oct 27 08:52:00 2016 -0700
@@ -89,6 +89,11 @@
AccessController.getContext(), context);
}
+ @Override
+ public ProtectionDomain[] getProtectDomains(AccessControlContext context) {
+ return context.getContext();
+ }
+
private static AccessControlContext getCombinedACC(
AccessControlContext context, AccessControlContext stack) {
AccessControlContext acc =
--- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahDate.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahDate.java Thu Oct 27 08:52:00 2016 -0700
@@ -368,7 +368,7 @@
if (field instanceof ChronoField) {
switch ((ChronoField) field) {
case DAY_OF_WEEK: return getDayOfWeek();
- case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((getDayOfWeek() - 1) % 7) + 1;
+ case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((dayOfMonth - 1) % 7) + 1;
case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
case DAY_OF_MONTH: return this.dayOfMonth;
case DAY_OF_YEAR: return this.getDayOfYear();
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -349,25 +349,40 @@
if (field == MONTH_OF_YEAR) {
for (TextStyle textStyle : TextStyle.values()) {
- Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
- "gregory", Calendar.MONTH, textStyle.toCalendarStyle(), locale);
Map<Long, String> map = new HashMap<>();
- if (displayNames != null) {
- for (Entry<String, Integer> entry : displayNames.entrySet()) {
- map.put((long) (entry.getValue() + 1), entry.getKey());
- }
-
- } else {
- // Narrow names may have duplicated names, such as "J" for January, Jun, July.
- // Get names one by one in that case.
+ // Narrow names may have duplicated names, such as "J" for January, June, July.
+ // Get names one by one in that case.
+ if ((textStyle.equals(TextStyle.NARROW) ||
+ textStyle.equals(TextStyle.NARROW_STANDALONE))) {
for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
String name;
name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
- "gregory", Calendar.MONTH, month, textStyle.toCalendarStyle(), locale);
+ "gregory", Calendar.MONTH,
+ month, textStyle.toCalendarStyle(), locale);
if (name == null) {
break;
}
- map.put((long) (month + 1), name);
+ map.put((month + 1L), name);
+ }
+ } else {
+ Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+ "gregory", Calendar.MONTH, textStyle.toCalendarStyle(), locale);
+ if (displayNames != null) {
+ for (Entry<String, Integer> entry : displayNames.entrySet()) {
+ map.put((long)(entry.getValue() + 1), entry.getKey());
+ }
+ } else {
+ // Although probability is very less, but if other styles have duplicate names.
+ // Get names one by one in that case.
+ for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
+ String name;
+ name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
+ "gregory", Calendar.MONTH, month, textStyle.toCalendarStyle(), locale);
+ if (name == null) {
+ break;
+ }
+ map.put((month + 1L), name);
+ }
}
}
if (!map.isEmpty()) {
@@ -379,26 +394,41 @@
if (field == DAY_OF_WEEK) {
for (TextStyle textStyle : TextStyle.values()) {
- Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
- "gregory", Calendar.DAY_OF_WEEK, textStyle.toCalendarStyle(), locale);
Map<Long, String> map = new HashMap<>();
- if (displayNames != null) {
- for (Entry<String, Integer> entry : displayNames.entrySet()) {
- map.put((long)toWeekDay(entry.getValue()), entry.getKey());
- }
-
- } else {
- // Narrow names may have duplicated names, such as "S" for Sunday and Saturday.
- // Get names one by one in that case.
+ // Narrow names may have duplicated names, such as "S" for Sunday and Saturday.
+ // Get names one by one in that case.
+ if ((textStyle.equals(TextStyle.NARROW) ||
+ textStyle.equals(TextStyle.NARROW_STANDALONE))) {
for (int wday = Calendar.SUNDAY; wday <= Calendar.SATURDAY; wday++) {
String name;
name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
- "gregory", Calendar.DAY_OF_WEEK, wday, textStyle.toCalendarStyle(), locale);
+ "gregory", Calendar.DAY_OF_WEEK,
+ wday, textStyle.toCalendarStyle(), locale);
if (name == null) {
break;
}
map.put((long)toWeekDay(wday), name);
}
+ } else {
+ Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+ "gregory", Calendar.DAY_OF_WEEK, textStyle.toCalendarStyle(), locale);
+ if (displayNames != null) {
+ for (Entry<String, Integer> entry : displayNames.entrySet()) {
+ map.put((long)toWeekDay(entry.getValue()), entry.getKey());
+ }
+ } else {
+ // Although probability is very less, but if other styles have duplicate names.
+ // Get names one by one in that case.
+ for (int wday = Calendar.SUNDAY; wday <= Calendar.SATURDAY; wday++) {
+ String name;
+ name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
+ "gregory", Calendar.DAY_OF_WEEK, wday, textStyle.toCalendarStyle(), locale);
+ if (name == null) {
+ break;
+ }
+ map.put((long)toWeekDay(wday), name);
+ }
+ }
}
if (!map.isEmpty()) {
styleMap.put(textStyle, map);
--- a/jdk/src/java.base/share/classes/java/util/Optional.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/Optional.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, 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
@@ -236,7 +236,7 @@
* present, otherwise an empty {@code Optional}
* @throws NullPointerException if the mapping function is {@code null}
*/
- public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
+ public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
@@ -264,12 +264,14 @@
* @throws NullPointerException if the mapping function is {@code null} or
* returns a {@code null} result
*/
- public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
+ public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
- return Objects.requireNonNull(mapper.apply(value));
+ @SuppressWarnings("unchecked")
+ Optional<U> r = (Optional<U>) mapper.apply(value);
+ return Objects.requireNonNull(r);
}
}
@@ -286,12 +288,14 @@
* produces a {@code null} result
* @since 9
*/
- public Optional<T> or(Supplier<Optional<T>> supplier) {
+ public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
Objects.requireNonNull(supplier);
if (isPresent()) {
return this;
} else {
- return Objects.requireNonNull(supplier.get());
+ @SuppressWarnings("unchecked")
+ Optional<T> r = (Optional<T>) supplier.get();
+ return Objects.requireNonNull(r);
}
}
--- a/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java Thu Oct 27 08:52:00 2016 -0700
@@ -63,7 +63,7 @@
* files containing the resource data. <code>ResourceBundle.getBundle</code>
* will automatically look for the appropriate properties file and create a
* <code>PropertyResourceBundle</code> that refers to it. See
- * {@link ResourceBundle#getBundle(java.lang.String, java.util.Locale, java.lang.ClassLoader) ResourceBundle.getBundle}
+ * {@link ResourceBundle#getBundle(String, Locale, ClassLoader) ResourceBundle.getBundle}
* for a complete description of the search and instantiation strategy.
*
* <p>
@@ -105,19 +105,14 @@
* </pre>
* </blockquote>
*
- * <p>
- * The implementation of a {@code PropertyResourceBundle} subclass must be
- * thread-safe if it's simultaneously used by multiple threads. The default
- * implementations of the non-abstract methods in this class are thread-safe.
- *
- * <p>
- * <strong>Note:</strong> PropertyResourceBundle can be constructed either
- * from an InputStream or a Reader, which represents a property file.
- * Constructing a PropertyResourceBundle instance from an InputStream requires
- * that the input stream be encoded in UTF-8. By default, if a
+ * @apiNote
+ * {@code PropertyResourceBundle} can be constructed either
+ * from an {@code InputStream} or a {@code Reader}, which represents a property file.
+ * Constructing a {@code PropertyResourceBundle} instance from an {@code InputStream}
+ * requires that the input stream be encoded in {@code UTF-8}. By default, if a
* {@link java.nio.charset.MalformedInputException} or an
* {@link java.nio.charset.UnmappableCharacterException} occurs on reading the
- * input stream, then the PropertyResourceBundle instance resets to the state
+ * input stream, then the {@code PropertyResourceBundle} instance resets to the state
* before the exception, re-reads the input stream in {@code ISO-8859-1}, and
* continues reading. If the system property
* {@code java.util.PropertyResourceBundle.encoding} is set to either
@@ -126,8 +121,15 @@
* If "ISO-8859-1" is specified, characters that cannot be represented in
* ISO-8859-1 encoding must be represented by Unicode Escapes as defined in section
* 3.3 of <cite>The Java™ Language Specification</cite>
- * whereas the other constructor which takes a Reader does not have that limitation.
+ * whereas the other constructor which takes a {@code Reader} does not have that limitation.
* Other encoding values are ignored for this system property.
+ * The system property is read and evaluated when initializing this class.
+ * Changing or removing the property has no effect after the initialization.
+ *
+ * @implSpec
+ * The implementation of a {@code PropertyResourceBundle} subclass must be
+ * thread-safe if it's simultaneously used by multiple threads. The default
+ * implementations of the non-abstract methods in this class are thread-safe.
*
* @see ResourceBundle
* @see ListResourceBundle
@@ -144,16 +146,18 @@
/**
* Creates a property resource bundle from an {@link java.io.InputStream
- * InputStream}. This constructor reads the property file in UTF-8 by default.
- * If a {@link java.nio.charset.MalformedInputException} or an
- * {@link java.nio.charset.UnmappableCharacterException} occurs on reading the
- * input stream, then the PropertyResourceBundle instance resets to the state
- * before the exception, re-reads the input stream in {@code ISO-8859-1} and
- * continues reading. If the system property
- * {@code java.util.PropertyResourceBundle.encoding} is set to either
- * "ISO-8859-1" or "UTF-8", the input stream is solely read in that encoding,
- * and throws the exception if it encounters an invalid sequence. Other
- * encoding values are ignored for this system property.
+ * InputStream}. This constructor reads the property file in UTF-8 by default.
+ * If a {@link java.nio.charset.MalformedInputException} or an
+ * {@link java.nio.charset.UnmappableCharacterException} occurs on reading the
+ * input stream, then the PropertyResourceBundle instance resets to the state
+ * before the exception, re-reads the input stream in {@code ISO-8859-1} and
+ * continues reading. If the system property
+ * {@code java.util.PropertyResourceBundle.encoding} is set to either
+ * "ISO-8859-1" or "UTF-8", the input stream is solely read in that encoding,
+ * and throws the exception if it encounters an invalid sequence. Other
+ * encoding values are ignored for this system property.
+ * The system property is read and evaluated when initializing this class.
+ * Changing or removing the property has no effect after the initialization.
*
* @param stream an InputStream that represents a property file
* to read from.
--- a/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Thu Oct 27 08:52:00 2016 -0700
@@ -71,7 +71,9 @@
NATIVE_LIBS("native"),
NATIVE_CMDS("bin"),
CLASSES("classes"),
- CONFIG("conf");
+ CONFIG("conf"),
+ HEADER_FILES("include"),
+ MAN_PAGES("man");
private final String jmodDir;
private Section(String jmodDir) {
@@ -151,6 +153,10 @@
return Section.CLASSES;
case "conf":
return Section.CONFIG;
+ case "include":
+ return Section.HEADER_FILES;
+ case "man":
+ return Section.MAN_PAGES;
default:
throw new IllegalArgumentException("invalid section: " + s);
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetAccess.java Wed Oct 19 08:05:48 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.internal.misc;
-
-import java.net.URLClassLoader;
-import jdk.internal.loader.URLClassPath;
-
-public interface JavaNetAccess {
- /**
- * return the URLClassPath belonging to the given loader
- */
- URLClassPath getURLClassPath (URLClassLoader u);
-}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetInetAddressAccess.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetInetAddressAccess.java Thu Oct 27 08:52:00 2016 -0700
@@ -26,6 +26,7 @@
package jdk.internal.misc;
import java.net.InetAddress;
+import java.net.UnknownHostException;
public interface JavaNetInetAddressAccess {
/**
@@ -33,4 +34,13 @@
* the given InetAddress object.
*/
String getOriginalHostName(InetAddress ia);
+
+ /**
+ * Get the InetAddress of the provided host. If an InetAddress is provided
+ * then it will be the default address returned for all calls to either
+ * form of getByName. This is required to maintain consistency when
+ * caching addresses and hostnames.
+ */
+ InetAddress getByName(String hostName, InetAddress hostAddress)
+ throws UnknownHostException;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetURLClassLoaderAccess.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.misc;
+
+import java.net.URLClassLoader;
+import java.security.AccessControlContext;
+
+public interface JavaNetURLClassLoaderAccess {
+ AccessControlContext getAccessControlContext(URLClassLoader u);;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetUriAccess.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.misc;
+
+import java.net.URI;
+
+public interface JavaNetUriAccess {
+ /**
+ * Create a URI of pre-validated scheme and path.
+ */
+ URI create(String scheme, String path);
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaSecurityAccess.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaSecurityAccess.java Thu Oct 27 08:52:00 2016 -0700
@@ -27,6 +27,7 @@
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
public interface JavaSecurityAccess {
@@ -37,4 +38,5 @@
<T> T doIntersectionPrivilege(PrivilegedAction<T> action,
AccessControlContext context);
+ ProtectionDomain[] getProtectDomains(AccessControlContext context);
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Thu Oct 27 08:52:00 2016 -0700
@@ -53,10 +53,11 @@
private static JavaLangInvokeAccess javaLangInvokeAccess;
private static JavaLangRefAccess javaLangRefAccess;
private static JavaIOAccess javaIOAccess;
- private static JavaNetAccess javaNetAccess;
private static JavaNetInetAddressAccess javaNetInetAddressAccess;
private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
private static JavaNetSocketAccess javaNetSocketAccess;
+ private static JavaNetUriAccess javaNetUriAccess;
+ private static JavaNetURLClassLoaderAccess javaNetURLClassLoaderAccess;
private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
@@ -134,14 +135,24 @@
return javaLangRefAccess;
}
- public static void setJavaNetAccess(JavaNetAccess jna) {
- javaNetAccess = jna;
+ public static void setJavaNetUriAccess(JavaNetUriAccess jnua) {
+ javaNetUriAccess = jnua;
}
- public static JavaNetAccess getJavaNetAccess() {
- if (javaNetAccess == null)
+ public static JavaNetUriAccess getJavaNetUriAccess() {
+ if (javaNetUriAccess == null)
+ unsafe.ensureClassInitialized(java.net.URI.class);
+ return javaNetUriAccess;
+ }
+
+ public static void setJavaNetURLClassLoaderAccess(JavaNetURLClassLoaderAccess jnua) {
+ javaNetURLClassLoaderAccess = jnua;
+ }
+
+ public static JavaNetURLClassLoaderAccess getJavaNetURLClassLoaderAccess() {
+ if (javaNetURLClassLoaderAccess == null)
unsafe.ensureClassInitialized(java.net.URLClassLoader.class);
- return javaNetAccess;
+ return javaNetURLClassLoaderAccess;
}
public static void setJavaNetInetAddressAccess(JavaNetInetAddressAccess jna) {
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Thu Oct 27 08:52:00 2016 -0700
@@ -84,9 +84,22 @@
public static native int getClassAccessFlags(Class<?> c);
+ /**
+ * Ensures that access to a member is granted and throws
+ * IllegalAccessException if not.
+ *
+ * @param currentClass the class performing the access
+ * @param memberClass the declaring class of the member being accessed
+ * @param targetClass the class of target object if accessing instance
+ * field or method;
+ * or the declaring class if accessing constructor;
+ * or null if accessing static field or method
+ * @param modifiers the member's access modifiers
+ * @throws IllegalAccessException if access to member is denied
+ */
public static void ensureMemberAccess(Class<?> currentClass,
Class<?> memberClass,
- Object target,
+ Class<?> targetClass,
int modifiers)
throws IllegalAccessException
{
@@ -94,18 +107,15 @@
throw new InternalError();
}
- if (!verifyMemberAccess(currentClass, memberClass, target, modifiers)) {
- throwIllegalAccessException(currentClass, memberClass, target, modifiers);
+ if (!verifyMemberAccess(currentClass, memberClass, targetClass, modifiers)) {
+ throwIllegalAccessException(currentClass, memberClass, targetClass, modifiers);
}
}
- public static boolean verifyMemberAccess(Class<?> currentClass,
- // Declaring class of field
- // or method
- Class<?> memberClass,
- // May be NULL in case of statics
- Object target,
- int modifiers)
+ private static boolean verifyMemberAccess(Class<?> currentClass,
+ Class<?> memberClass,
+ Class<?> targetClass,
+ int modifiers)
{
// Verify that currentClass can access a field, method, or
// constructor of memberClass, where that member's access bits are
@@ -162,18 +172,18 @@
return false;
}
- if (Modifier.isProtected(modifiers)) {
- // Additional test for protected members: JLS 6.6.2
- Class<?> targetClass = (target == null ? memberClass : target.getClass());
- if (targetClass != currentClass) {
- if (!gotIsSameClassPackage) {
- isSameClassPackage = isSameClassPackage(currentClass, memberClass);
- gotIsSameClassPackage = true;
- }
- if (!isSameClassPackage) {
- if (!isSubclassOf(targetClass, currentClass)) {
- return false;
- }
+ // Additional test for protected instance members
+ // and protected constructors: JLS 6.6.2
+ if (targetClass != null && Modifier.isProtected(modifiers) &&
+ targetClass != currentClass)
+ {
+ if (!gotIsSameClassPackage) {
+ isSameClassPackage = isSameClassPackage(currentClass, memberClass);
+ gotIsSameClassPackage = true;
+ }
+ if (!isSameClassPackage) {
+ if (!isSubclassOf(targetClass, currentClass)) {
+ return false;
}
}
}
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -25,14 +25,25 @@
package jdk.internal.reflect;
+import java.io.Externalizable;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.OptionalDataException;
+import java.io.Serializable;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.lang.reflect.Executable;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.security.Permission;
import java.security.PrivilegedAction;
+import java.util.Objects;
import java.util.Properties;
+
import sun.reflect.misc.ReflectUtil;
import sun.security.action.GetPropertyAction;
@@ -57,6 +68,9 @@
// Provides access to package-private mechanisms in java.lang.reflect
private static volatile LangReflectAccess langReflectAccess;
+ /* Method for static class initializer <clinit>, or null */
+ private static volatile Method hasStaticInitializerMethod;
+
//
// "Inflation" mechanism. Loading bytecodes to implement
// Method.invoke() and Constructor.newInstance() currently costs
@@ -337,16 +351,41 @@
//
//
- public Constructor<?> newConstructorForSerialization
- (Class<?> classToInstantiate, Constructor<?> constructorToCall)
- {
- // Fast path
- if (constructorToCall.getDeclaringClass() == classToInstantiate) {
- return constructorToCall;
+ public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
+ if (!Externalizable.class.isAssignableFrom(cl)) {
+ return null;
+ }
+ try {
+ Constructor<?> cons = cl.getConstructor();
+ cons.setAccessible(true);
+ return cons;
+ } catch (NoSuchMethodException ex) {
+ return null;
+ }
+ }
+
+ public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
+ Class<?> initCl = cl;
+ while (Serializable.class.isAssignableFrom(initCl)) {
+ if ((initCl = initCl.getSuperclass()) == null) {
+ return null;
+ }
+ }
+ Constructor<?> constructorToCall;
+ try {
+ constructorToCall = initCl.getDeclaredConstructor();
+ int mods = constructorToCall.getModifiers();
+ if ((mods & Modifier.PRIVATE) != 0 ||
+ ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
+ !packageEquals(cl, initCl))) {
+ return null;
+ }
+ } catch (NoSuchMethodException ex) {
+ return null;
}
ConstructorAccessor acc = new MethodAccessorGenerator().
- generateSerializationConstructor(classToInstantiate,
+ generateSerializationConstructor(cl,
constructorToCall.getParameterTypes(),
constructorToCall.getExceptionTypes(),
constructorToCall.getModifiers(),
@@ -364,9 +403,151 @@
langReflectAccess().
getConstructorParameterAnnotations(constructorToCall));
setConstructorAccessor(c, acc);
+ c.setAccessible(true);
return c;
}
+ public final MethodHandle readObjectForSerialization(Class<?> cl) {
+ return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class);
+ }
+
+ public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
+ return findReadWriteObjectForSerialization(cl, "readObjectNoData", ObjectInputStream.class);
+ }
+
+ public final MethodHandle writeObjectForSerialization(Class<?> cl) {
+ return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class);
+ }
+
+ private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl,
+ String methodName,
+ Class<?> streamClass) {
+ if (!Serializable.class.isAssignableFrom(cl)) {
+ return null;
+ }
+
+ try {
+ Method meth = cl.getDeclaredMethod(methodName, streamClass);
+ int mods = meth.getModifiers();
+ if (meth.getReturnType() != Void.TYPE ||
+ Modifier.isStatic(mods) ||
+ !Modifier.isPrivate(mods)) {
+ return null;
+ }
+ meth.setAccessible(true);
+ return MethodHandles.lookup().unreflect(meth);
+ } catch (NoSuchMethodException ex) {
+ return null;
+ } catch (IllegalAccessException ex1) {
+ throw new InternalError("Error", ex1);
+ }
+ }
+
+ /**
+ * Returns a MethodHandle for {@code writeReplace} on the serializable class
+ * or null if no match found.
+ * @param cl a serializable class
+ * @returnss the {@code writeReplace} MethodHandle or {@code null} if not found
+ */
+ public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
+ return getReplaceResolveForSerialization(cl, "writeReplace");
+ }
+
+ /**
+ * Returns a MethodHandle for {@code readResolve} on the serializable class
+ * or null if no match found.
+ * @param cl a serializable class
+ * @returns the {@code writeReplace} MethodHandle or {@code null} if not found
+ */
+ public final MethodHandle readResolveForSerialization(Class<?> cl) {
+ return getReplaceResolveForSerialization(cl, "readResolve");
+ }
+
+ /**
+ * Lookup readResolve or writeReplace on a class with specified
+ * signature constraints.
+ * @param cl a serializable class
+ * @param methodName the method name to find
+ * @returns a MethodHandle for the method or {@code null} if not found or
+ * has the wrong signature.
+ */
+ private MethodHandle getReplaceResolveForSerialization(Class<?> cl,
+ String methodName) {
+ if (!Serializable.class.isAssignableFrom(cl)) {
+ return null;
+ }
+
+ Class<?> defCl = cl;
+ while (defCl != null) {
+ try {
+ Method m = defCl.getDeclaredMethod(methodName);
+ if (m.getReturnType() != Object.class) {
+ return null;
+ }
+ int mods = m.getModifiers();
+ if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) {
+ return null;
+ } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) {
+ // fall through
+ } else if (Modifier.isPrivate(mods) && (cl != defCl)) {
+ return null;
+ } else if (!packageEquals(cl, defCl)) {
+ return null;
+ }
+ try {
+ // Normal return
+ m.setAccessible(true);
+ return MethodHandles.lookup().unreflect(m);
+ } catch (IllegalAccessException ex0) {
+ // setAccessible should prevent IAE
+ throw new InternalError("Error", ex0);
+ }
+ } catch (NoSuchMethodException ex) {
+ defCl = defCl.getSuperclass();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if the given class defines a static initializer method,
+ * false otherwise.
+ */
+ public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
+ Method m = hasStaticInitializerMethod;
+ if (m == null) {
+ try {
+ m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer",
+ new Class<?>[]{Class.class});
+ m.setAccessible(true);
+ hasStaticInitializerMethod = m;
+ } catch (NoSuchMethodException ex) {
+ throw new InternalError("No such method hasStaticInitializer on "
+ + ObjectStreamClass.class, ex);
+ }
+ }
+ try {
+ return (Boolean) m.invoke(null, cl);
+ } catch (InvocationTargetException | IllegalAccessException ex) {
+ throw new InternalError("Exception invoking hasStaticInitializer", ex);
+ }
+ }
+
+ /**
+ * Return the accessible constructor for OptionalDataException signaling eof.
+ * @returns the eof constructor for OptionalDataException
+ */
+ public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() {
+ try {
+ Constructor<OptionalDataException> boolCtor =
+ OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE);
+ boolCtor.setAccessible(true);
+ return boolCtor;
+ } catch (NoSuchMethodException ex) {
+ throw new InternalError("Constructor not found", ex);
+ }
+ }
+
//--------------------------------------------------------------------------
//
// Internals only below this point
@@ -426,4 +607,17 @@
}
return langReflectAccess;
}
+
+ /**
+ * Returns true if classes are defined in the classloader and same package, false
+ * otherwise.
+ * @param cl1 a class
+ * @param cl2 another class
+ * @returns true if the two classes are in the same classloader and package
+ */
+ private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
+ return cl1.getClassLoader() == cl2.getClassLoader() &&
+ Objects.equals(cl1.getPackage(), cl2.getPackage());
+ }
+
}
--- a/jdk/src/java.base/share/classes/module-info.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/module-info.java Thu Oct 27 08:52:00 2016 -0700
@@ -171,8 +171,10 @@
jdk.jartool,
jdk.jdeps,
jdk.jlink,
+ jdk.jshell,
jdk.net,
jdk.scripting.nashorn,
+ jdk.scripting.nashorn.shell,
jdk.unsupported,
jdk.vm.ci;
exports jdk.internal.perf to
@@ -238,8 +240,7 @@
java.xml.ws;
exports sun.security.action to
java.desktop,
- java.security.jgss,
- jdk.crypto.pkcs11;
+ java.security.jgss;
exports sun.security.internal.interfaces to
jdk.crypto.pkcs11;
exports sun.security.internal.spec to
@@ -265,6 +266,8 @@
jdk.crypto.pkcs11;
exports sun.security.ssl to
java.security.jgss;
+ exports sun.security.timestamp to
+ jdk.jartool;
exports sun.security.tools to
jdk.jartool;
exports sun.security.util to
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java Thu Oct 27 08:52:00 2016 -0700
@@ -25,8 +25,11 @@
package sun.net.www.protocol.http;
+import java.util.Collections;
import java.util.Iterator;
import java.util.HashMap;
+import java.util.Set;
+
import sun.net.www.*;
import sun.security.action.GetPropertyAction;
@@ -67,8 +70,8 @@
* -Dhttp.auth.preference="scheme"
*
* which in this case, specifies that "scheme" should be used as the auth scheme when offered
- * disregarding the default prioritisation. If scheme is not offered then the default priority
- * is used.
+ * disregarding the default prioritisation. If scheme is not offered, or explicitly
+ * disabled, by {@code disabledSchemes}, then the default priority is used.
*
* Attention: when http.auth.preference is set as SPNEGO or Kerberos, it's actually "Negotiate
* with SPNEGO" or "Negotiate with Kerberos", which means the user will prefer the Negotiate
@@ -113,17 +116,32 @@
String hdrname; // Name of the header to look for
/**
- * parse a set of authentication headers and choose the preferred scheme
- * that we support for a given host
+ * Parses a set of authentication headers and chooses the preferred scheme
+ * that is supported for a given host.
*/
public AuthenticationHeader (String hdrname, MessageHeader response,
HttpCallerInfo hci, boolean dontUseNegotiate) {
+ this(hdrname, response, hci, dontUseNegotiate, Collections.emptySet());
+ }
+
+ /**
+ * Parses a set of authentication headers and chooses the preferred scheme
+ * that is supported for a given host.
+ *
+ * <p> The {@code disabledSchemes} parameter is a, possibly empty, set of
+ * authentication schemes that are disabled.
+ */
+ public AuthenticationHeader(String hdrname,
+ MessageHeader response,
+ HttpCallerInfo hci,
+ boolean dontUseNegotiate,
+ Set<String> disabledSchemes) {
this.hci = hci;
this.dontUseNegotiate = dontUseNegotiate;
- rsp = response;
+ this.rsp = response;
this.hdrname = hdrname;
- schemes = new HashMap<>();
- parse();
+ this.schemes = new HashMap<>();
+ parse(disabledSchemes);
}
public HttpCallerInfo getHttpCallerInfo() {
@@ -143,10 +161,11 @@
* then the last one will be used. The
* preferred scheme that we support will be used.
*/
- private void parse () {
+ private void parse(Set<String> disabledSchemes) {
Iterator<String> iter = rsp.multiValueIterator(hdrname);
while (iter.hasNext()) {
String raw = iter.next();
+ // HeaderParser lower cases everything, so can be used case-insensitively
HeaderParser hp = new HeaderParser(raw);
Iterator<String> keys = hp.keys();
int i, lastSchemeIndex;
@@ -156,7 +175,8 @@
if (lastSchemeIndex != -1) {
HeaderParser hpn = hp.subsequence (lastSchemeIndex, i);
String scheme = hpn.findKey(0);
- schemes.put (scheme, new SchemeMapValue (hpn, raw));
+ if (!disabledSchemes.contains(scheme))
+ schemes.put(scheme, new SchemeMapValue (hpn, raw));
}
lastSchemeIndex = i;
}
@@ -164,7 +184,8 @@
if (i > lastSchemeIndex) {
HeaderParser hpn = hp.subsequence (lastSchemeIndex, i);
String scheme = hpn.findKey(0);
- schemes.put(scheme, new SchemeMapValue (hpn, raw));
+ if (!disabledSchemes.contains(scheme))
+ schemes.put(scheme, new SchemeMapValue (hpn, raw));
}
}
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Thu Oct 27 08:52:00 2016 -0700
@@ -25,6 +25,7 @@
package sun.net.www.protocol.http;
+import java.security.PrivilegedAction;
import java.util.Arrays;
import java.net.URL;
import java.net.URLConnection;
@@ -109,6 +110,14 @@
static final boolean validateProxy;
static final boolean validateServer;
+ /** A, possibly empty, set of authentication schemes that are disabled
+ * when proxying plain HTTP ( not HTTPS ). */
+ static final Set<String> disabledProxyingSchemes;
+
+ /** A, possibly empty, set of authentication schemes that are disabled
+ * when setting up a tunnel for HTTPS ( HTTP CONNECT ). */
+ static final Set<String> disabledTunnelingSchemes;
+
private StreamingOutputStream strOutputStream;
private static final String RETRY_MSG1 =
"cannot retry due to proxy authentication, in streaming mode";
@@ -206,6 +215,22 @@
"Via"
};
+ private static String getNetProperty(String name) {
+ PrivilegedAction<String> pa = () -> NetProperties.get(name);
+ return AccessController.doPrivileged(pa);
+ }
+
+ private static Set<String> schemesListToSet(String list) {
+ if (list == null || list.isEmpty())
+ return Collections.emptySet();
+
+ Set<String> s = new HashSet<>();
+ String[] parts = list.split("\\s*,\\s*");
+ for (String part : parts)
+ s.add(part.toLowerCase(Locale.ROOT));
+ return s;
+ }
+
static {
Properties props = GetPropertyAction.privilegedGetProperties();
maxRedirects = GetIntegerAction.privilegedGetProperty(
@@ -218,6 +243,14 @@
agent = agent + " Java/"+version;
}
userAgent = agent;
+
+ // A set of net properties to control the use of authentication schemes
+ // when proxing/tunneling.
+ String p = getNetProperty("jdk.http.auth.tunneling.disabledSchemes");
+ disabledTunnelingSchemes = schemesListToSet(p);
+ p = getNetProperty("jdk.http.auth.proxying.disabledSchemes");
+ disabledProxyingSchemes = schemesListToSet(p);
+
validateProxy = Boolean.parseBoolean(
props.getProperty("http.auth.digest.validateProxy"));
validateServer = Boolean.parseBoolean(
@@ -1575,10 +1608,13 @@
// altered in similar ways.
AuthenticationHeader authhdr = new AuthenticationHeader (
- "Proxy-Authenticate", responses,
- new HttpCallerInfo(url, http.getProxyHostUsed(),
- http.getProxyPortUsed()),
- dontUseNegotiate
+ "Proxy-Authenticate",
+ responses,
+ new HttpCallerInfo(url,
+ http.getProxyHostUsed(),
+ http.getProxyPortUsed()),
+ dontUseNegotiate,
+ disabledProxyingSchemes
);
if (!doingNTLMp2ndStage) {
@@ -2024,11 +2060,14 @@
}
}
- AuthenticationHeader authhdr = new AuthenticationHeader (
- "Proxy-Authenticate", responses,
- new HttpCallerInfo(url, http.getProxyHostUsed(),
- http.getProxyPortUsed()),
- dontUseNegotiate
+ AuthenticationHeader authhdr = new AuthenticationHeader(
+ "Proxy-Authenticate",
+ responses,
+ new HttpCallerInfo(url,
+ http.getProxyHostUsed(),
+ http.getProxyPortUsed()),
+ dontUseNegotiate,
+ disabledTunnelingSchemes
);
if (!doingNTLMp2ndStage) {
proxyAuthentication =
--- a/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Thu Oct 27 08:52:00 2016 -0700
@@ -44,9 +44,21 @@
return Class.forName(name);
}
- /*
- * Reflection.ensureMemberAccess is overly-restrictive
- * due to a bug. We awkwardly work around it for now.
+ /**
+ * Ensures that access to a method or field is granted and throws
+ * IllegalAccessException if not. This method is not suitable for checking
+ * access to constructors.
+ *
+ * @param currentClass the class performing the access
+ * @param memberClass the declaring class of the member being accessed
+ * @param target the target object if accessing instance field or method;
+ * or null if accessing static field or method or if target
+ * object access rights will be checked later
+ * @param modifiers the member's access modifiers
+ * @throws IllegalAccessException if access to member is denied
+ * @implNote Delegates directly to
+ * {@link Reflection#ensureMemberAccess(Class, Class, Class, int)}
+ * which should be used instead.
*/
public static void ensureMemberAccess(Class<?> currentClass,
Class<?> memberClass,
@@ -54,62 +66,10 @@
int modifiers)
throws IllegalAccessException
{
- if (target == null && Modifier.isProtected(modifiers)) {
- int mods = modifiers;
- mods = mods & (~Modifier.PROTECTED);
- mods = mods | Modifier.PUBLIC;
-
- /*
- * See if we fail because of class modifiers
- */
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- mods);
- try {
- /*
- * We're still here so class access was ok.
- * Now try with default field access.
- */
- mods = mods & (~Modifier.PUBLIC);
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- mods);
- /*
- * We're still here so access is ok without
- * checking for protected.
- */
- return;
- } catch (IllegalAccessException e) {
- /*
- * Access failed but we're 'protected' so
- * if the test below succeeds then we're ok.
- */
- if (isSubclassOf(currentClass, memberClass)) {
- return;
- } else {
- throw e;
- }
- }
- } else {
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- modifiers);
- }
- }
-
- private static boolean isSubclassOf(Class<?> queryClass,
- Class<?> ofClass)
- {
- while (queryClass != null) {
- if (queryClass == ofClass) {
- return true;
- }
- queryClass = queryClass.getSuperclass();
- }
- return false;
+ Reflection.ensureMemberAccess(currentClass,
+ memberClass,
+ target == null ? null : target.getClass(),
+ modifiers);
}
/**
--- a/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -28,20 +28,38 @@
import java.io.OutputStream;
import java.io.IOException;
import java.math.BigInteger;
+import java.security.CryptoPrimitive;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.Timestamp;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
-import java.security.*;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
import sun.security.timestamp.TimestampToken;
-import sun.security.util.*;
+import sun.security.util.Debug;
+import sun.security.util.DerEncoder;
+import sun.security.util.DerInputStream;
+import sun.security.util.DerOutputStream;
+import sun.security.util.DerValue;
+import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.util.HexDumpEncoder;
+import sun.security.util.KeyUtil;
+import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name;
import sun.security.x509.KeyUsageExtension;
-import sun.security.util.HexDumpEncoder;
/**
* A SignerInfo, as defined in PKCS#7's signedData type.
@@ -50,6 +68,17 @@
*/
public class SignerInfo implements DerEncoder {
+ // Digest and Signature restrictions
+ private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
+
+ private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
+
+ private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
+ new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
+
BigInteger version;
X500Name issuerName;
BigInteger certificateSerialNumber;
@@ -318,6 +347,13 @@
if (messageDigest == null) // fail if there is no message digest
return null;
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET,
+ digestAlgname, null)) {
+ throw new SignatureException("Digest check failed. " +
+ "Disabled algorithm used: " + digestAlgname);
+ }
+
MessageDigest md = MessageDigest.getInstance(digestAlgname);
byte[] computedMessageDigest = md.digest(data);
@@ -349,12 +385,26 @@
String algname = AlgorithmId.makeSigAlg(
digestAlgname, encryptionAlgname);
- Signature sig = Signature.getInstance(algname);
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, algname, null)) {
+ throw new SignatureException("Signature check failed. " +
+ "Disabled algorithm used: " + algname);
+ }
+
X509Certificate cert = getCertificate(block);
-
+ PublicKey key = cert.getPublicKey();
if (cert == null) {
return null;
}
+
+ // check if the public key is restricted
+ if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
+ throw new SignatureException("Public key check failed. " +
+ "Disabled key used: " +
+ KeyUtil.getKeySize(key) + " bit " +
+ key.getAlgorithm());
+ }
+
if (cert.hasUnsupportedCriticalExtension()) {
throw new SignatureException("Certificate has unsupported "
+ "critical extension(s)");
@@ -391,11 +441,9 @@
}
}
- PublicKey key = cert.getPublicKey();
+ Signature sig = Signature.getInstance(algname);
sig.initVerify(key);
-
sig.update(dataSigned);
-
if (sig.verify(encryptedDigest)) {
return this;
}
@@ -450,6 +498,23 @@
return unauthenticatedAttributes;
}
+ /**
+ * Returns the timestamp PKCS7 data unverified.
+ * @return a PKCS7 object
+ */
+ public PKCS7 getTsToken() throws IOException {
+ if (unauthenticatedAttributes == null) {
+ return null;
+ }
+ PKCS9Attribute tsTokenAttr =
+ unauthenticatedAttributes.getAttribute(
+ PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
+ if (tsTokenAttr == null) {
+ return null;
+ }
+ return new PKCS7((byte[])tsTokenAttr.getValue());
+ }
+
/*
* Extracts a timestamp from a PKCS7 SignerInfo.
*
@@ -477,19 +542,12 @@
if (timestamp != null || !hasTimestamp)
return timestamp;
- if (unauthenticatedAttributes == null) {
- hasTimestamp = false;
- return null;
- }
- PKCS9Attribute tsTokenAttr =
- unauthenticatedAttributes.getAttribute(
- PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
- if (tsTokenAttr == null) {
+ PKCS7 tsToken = getTsToken();
+ if (tsToken == null) {
hasTimestamp = false;
return null;
}
- PKCS7 tsToken = new PKCS7((byte[])tsTokenAttr.getValue());
// Extract the content (an encoded timestamp token info)
byte[] encTsTokenInfo = tsToken.getContentInfo().getData();
// Extract the signer (the Timestamping Authority)
@@ -515,9 +573,16 @@
*/
private void verifyTimestamp(TimestampToken token)
throws NoSuchAlgorithmException, SignatureException {
+ String digestAlgname = token.getHashAlgorithm().getName();
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, digestAlgname,
+ null)) {
+ throw new SignatureException("Timestamp token digest check failed. " +
+ "Disabled algorithm used: " + digestAlgname);
+ }
MessageDigest md =
- MessageDigest.getInstance(token.getHashAlgorithm().getName());
+ MessageDigest.getInstance(digestAlgname);
if (!Arrays.equals(token.getHashedMessage(),
md.digest(encryptedDigest))) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Thu Oct 27 08:52:00 2016 -0700
@@ -185,20 +185,22 @@
AlgorithmConstraints constraints,
Date pkixdate) {
- if (anchor == null) {
- throw new IllegalArgumentException(
- "The trust anchor cannot be null");
- }
-
- if (anchor.getTrustedCert() != null) {
- this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
- // Check for anchor certificate restrictions
- trustedMatch = checkFingerprint(anchor.getTrustedCert());
- if (trustedMatch && debug != null) {
- debug.println("trustedMatch = true");
+ if (anchor != null) {
+ if (anchor.getTrustedCert() != null) {
+ this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
+ // Check for anchor certificate restrictions
+ trustedMatch = checkFingerprint(anchor.getTrustedCert());
+ if (trustedMatch && debug != null) {
+ debug.println("trustedMatch = true");
+ }
+ } else {
+ this.trustedPubKey = anchor.getCAPublicKey();
}
} else {
- this.trustedPubKey = anchor.getCAPublicKey();
+ this.trustedPubKey = null;
+ if (debug != null) {
+ debug.println("TrustAnchor is null, trustedMatch is false.");
+ }
}
this.prevPubKey = trustedPubKey;
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -816,18 +816,22 @@
/**
* Verifies whether the input certificate completes the path.
- * Checks the cert against each trust anchor that was specified, in order,
- * and returns true as soon as it finds a valid anchor.
- * Returns true if the cert matches a trust anchor specified as a
- * certificate or if the cert verifies with a trust anchor that
- * was specified as a trusted {pubkey, caname} pair. Returns false if none
- * of the trust anchors are valid for this cert.
+ * First checks the cert against each trust anchor that was specified,
+ * in order, and returns true if the cert matches the trust anchor
+ * specified as a certificate or has the same key and subject of an anchor
+ * specified as a trusted {pubkey, caname} pair.
+ * If no match has been found, does a second check of the cert against
+ * anchors specified as a trusted {pubkey, caname} pair to see if the cert
+ * was issued by that anchor.
+ * Returns false if none of the trust anchors are valid for this cert.
*
* @param cert the certificate to test
* @return a boolean value indicating whether the cert completes the path.
*/
@Override
boolean isPathCompleted(X509Certificate cert) {
+ List<TrustAnchor> otherAnchors = new ArrayList<>();
+ // first, check if cert is already trusted
for (TrustAnchor anchor : trustAnchors) {
if (anchor.getTrustedCert() != null) {
if (cert.equals(anchor.getTrustedCert())) {
@@ -849,7 +853,12 @@
}
// else, it is a self-issued certificate of the anchor
}
-
+ otherAnchors.add(anchor);
+ }
+ // next, check if cert is issued by anchor specified by key/name
+ for (TrustAnchor anchor : otherAnchors) {
+ X500Principal principal = anchor.getCA();
+ PublicKey publicKey = anchor.getCAPublicKey();
// Check subject/issuer name chaining
if (principal == null ||
!principal.equals(cert.getIssuerX500Principal())) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java Thu Oct 27 08:52:00 2016 -0700
@@ -35,6 +35,7 @@
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.CRLReason;
import java.security.cert.Extension;
+import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collections;
@@ -164,6 +165,15 @@
Date date, List<Extension> extensions)
throws IOException, CertPathValidatorException
{
+ return check(cert, responderURI, null, issuerCert, responderCert, date, extensions);
+ }
+
+ public static RevocationStatus check(X509Certificate cert,
+ URI responderURI, TrustAnchor anchor, X509Certificate issuerCert,
+ X509Certificate responderCert, Date date,
+ List<Extension> extensions)
+ throws IOException, CertPathValidatorException
+ {
CertId certId = null;
try {
X509CertImpl certImpl = X509CertImpl.toImpl(cert);
@@ -173,8 +183,8 @@
("Exception while encoding OCSPRequest", e);
}
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
- responderURI, new OCSPResponse.IssuerInfo(issuerCert),
- responderCert, date, extensions);
+ responderURI, new OCSPResponse.IssuerInfo(anchor, issuerCert),
+ responderCert, date, extensions);
return (RevocationStatus) ocspResponse.getSingleResponse(certId);
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java Thu Oct 27 08:52:00 2016 -0700
@@ -507,9 +507,8 @@
// Check algorithm constraints specified in security property
// "jdk.certpath.disabledAlgorithms".
- AlgorithmChecker algChecker = new AlgorithmChecker(
- new TrustAnchor(issuerInfo.getName(),
- issuerInfo.getPublicKey(), null));
+ AlgorithmChecker algChecker =
+ new AlgorithmChecker(issuerInfo.getAnchor(), date);
algChecker.init(false);
algChecker.check(signerCert, Collections.<String>emptySet());
@@ -982,36 +981,38 @@
/**
* Helper class that allows consumers to pass in issuer information. This
* will always consist of the issuer's name and public key, but may also
- * contain a certificate if the originating data is in that form.
+ * contain a certificate if the originating data is in that form. The
+ * trust anchor for the certificate chain will be included for certpath
+ * disabled algorithm checking.
*/
static final class IssuerInfo {
+ private final TrustAnchor anchor;
private final X509Certificate certificate;
private final X500Principal name;
private final PublicKey pubKey;
+ IssuerInfo(TrustAnchor anchor) {
+ this(anchor, (anchor != null) ? anchor.getTrustedCert() : null);
+ }
+
IssuerInfo(X509Certificate issuerCert) {
- certificate = Objects.requireNonNull(issuerCert,
- "Constructor requires non-null certificate");
- name = certificate.getSubjectX500Principal();
- pubKey = certificate.getPublicKey();
+ this(null, issuerCert);
}
- IssuerInfo(X500Principal subjectName, PublicKey key) {
- certificate = null;
- name = Objects.requireNonNull(subjectName,
- "Constructor requires non-null subject");
- pubKey = Objects.requireNonNull(key,
- "Constructor requires non-null public key");
- }
-
- IssuerInfo(TrustAnchor anchor) {
- certificate = anchor.getTrustedCert();
- if (certificate != null) {
- name = certificate.getSubjectX500Principal();
- pubKey = certificate.getPublicKey();
+ IssuerInfo(TrustAnchor anchor, X509Certificate issuerCert) {
+ if (anchor == null && issuerCert == null) {
+ throw new NullPointerException("TrustAnchor and issuerCert " +
+ "cannot be null");
+ }
+ this.anchor = anchor;
+ if (issuerCert != null) {
+ name = issuerCert.getSubjectX500Principal();
+ pubKey = issuerCert.getPublicKey();
+ certificate = issuerCert;
} else {
name = anchor.getCA();
pubKey = anchor.getCAPublicKey();
+ certificate = anchor.getTrustedCert();
}
}
@@ -1047,6 +1048,15 @@
}
/**
+ * Get the TrustAnchor for the certificate chain.
+ *
+ * @return a {@code TrustAnchor}.
+ */
+ TrustAnchor getAnchor() {
+ return anchor;
+ }
+
+ /**
* Create a string representation of this IssuerInfo.
*
* @return a {@code String} form of this IssuerInfo object.
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Thu Oct 27 08:52:00 2016 -0700
@@ -437,7 +437,7 @@
private void updateState(X509Certificate cert)
throws CertPathValidatorException
{
- issuerInfo = new OCSPResponse.IssuerInfo(cert);
+ issuerInfo = new OCSPResponse.IssuerInfo(anchor, cert);
// Make new public key if parameters are missing
PublicKey pubKey = cert.getPublicKey();
@@ -740,8 +740,8 @@
}
response = OCSP.check(Collections.singletonList(certId),
- responderURI, issuerInfo,
- responderCert, null, ocspExtensions);
+ responderURI, issuerInfo, responderCert, params.date(),
+ ocspExtensions);
}
} catch (IOException e) {
throw new CertPathValidatorException(
--- a/jdk/src/java.base/share/classes/sun/security/util/CurveDB.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/util/CurveDB.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -664,6 +664,74 @@
0xFF70, nameSplitPattern);
*/
+ /*
+ * Brainpool curves (RFC 5639)
+ * (Twisted curves are not included)
+ */
+
+ add("brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1", P,
+ "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
+ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
+ "1E589A8595423412134FAA2DBDEC95C8D8675E58",
+ "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
+ "1667CB477A1A8EC338F94741669C976316DA6321",
+ "E95E4A5F737059DC60DF5991D45029409E60FC09",
+ 1, nameSplitPattern);
+
+ add("brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", P,
+ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
+ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
+ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
+ "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
+ "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
+ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
+ 1, nameSplitPattern);
+
+ add("brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", P,
+ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
+ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
+ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
+ "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
+ "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
+ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
+ 1, nameSplitPattern);
+
+ add("brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", P,
+ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
+ "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
+ "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
+ "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
+ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
+ "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
+ 1, nameSplitPattern);
+
+ add("brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", P,
+ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
+ "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
+ "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
+ "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
+ "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
+ "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
+ 1, nameSplitPattern);
+
+ add("brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", P,
+ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
+ "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
+ "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
+ "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
+ "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
+ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
+ 1, nameSplitPattern);
+
+ add("brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", P,
+ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
+ "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
+ "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
+ "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
+ "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
+ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
+ 1, nameSplitPattern);
+
specCollection = Collections.unmodifiableCollection(oidMap.values());
}
}
--- a/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Thu Oct 27 08:52:00 2016 -0700
@@ -60,6 +60,10 @@
public static final String PROPERTY_TLS_DISABLED_ALGS =
"jdk.tls.disabledAlgorithms";
+ // the known security property, jdk.jar.disabledAlgorithms
+ public static final String PROPERTY_JAR_DISABLED_ALGS =
+ "jdk.jar.disabledAlgorithms";
+
private final String[] disabledAlgorithms;
private final Constraints algorithmConstraints;
@@ -73,6 +77,14 @@
this(propertyName, new AlgorithmDecomposer());
}
+ /**
+ * Initialize algorithm constraints with the specified security property
+ * for a specific usage type.
+ *
+ * @param propertyName the security property name that define the disabled
+ * algorithm constraints
+ * @param decomposer an alternate AlgorithmDecomposer.
+ */
public DisabledAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) {
super(decomposer);
@@ -530,7 +542,8 @@
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on certificate " +
- "anchor limits",
+ "anchor limits. " + algorithm + " used with " +
+ cp.getCertificate().getSubjectX500Principal(),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -611,8 +624,8 @@
return;
}
throw new CertPathValidatorException(
- "denyAfter constraint check failed. " +
- "Constraint date: " +
+ "denyAfter constraint check failed: " + algorithm +
+ " used with Constraint date: " +
dateFormat.format(denyAfterDate) + "; "
+ errmsg + dateFormat.format(currentDate),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
@@ -644,6 +657,7 @@
private int minSize; // the minimal available key size
private int maxSize; // the maximal available key size
private int prohibitedSize = -1; // unavailable key sizes
+ private int size;
public KeySizeConstraint(String algo, Operator operator, int length) {
algorithm = algo;
@@ -695,7 +709,9 @@
return;
}
throw new CertPathValidatorException(
- "Algorithm constraints check failed on keysize limits",
+ "Algorithm constraints check failed on keysize limits. "
+ + algorithm + " " + size + "bit key used with "
+ + cp.getCertificate().getSubjectX500Principal(),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -722,7 +738,7 @@
return true;
}
- int size = KeyUtil.getKeySize(key);
+ size = KeyUtil.getKeySize(key);
if (size == 0) {
return false; // we don't allow any key of size 0.
} else if (size > 0) {
--- a/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, 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
@@ -25,26 +25,49 @@
package sun.security.util;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.CodeSigner;
+import java.security.CryptoPrimitive;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-import java.security.*;
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-import sun.security.pkcs.*;
+import java.util.ArrayList;
import java.util.Base64;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.JarException;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
import sun.security.jca.Providers;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.SignerInfo;
public class SignatureFileVerifier {
/* Are we debugging ? */
private static final Debug debug = Debug.getInstance("jar");
- /* cache of CodeSigner objects */
+ private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
+
+ private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
+ new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
+
private ArrayList<CodeSigner[]> signerCache;
private static final String ATTR_DIGEST =
@@ -199,8 +222,15 @@
/** get digest from cache */
- private MessageDigest getDigest(String algorithm)
- {
+ private MessageDigest getDigest(String algorithm) throws SignatureException {
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, algorithm, null)) {
+ SignatureException e =
+ new SignatureException("SignatureFile check failed. " +
+ "Disabled algorithm used: " + algorithm);
+ throw e;
+ }
+
if (createdDigests == null)
createdDigests = new HashMap<>();
@@ -320,7 +350,7 @@
private boolean verifyManifestHash(Manifest sf,
ManifestDigester md,
List<Object> manifestDigests)
- throws IOException
+ throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean manifestSigned = false;
@@ -364,7 +394,7 @@
private boolean verifyManifestMainAttrs(Manifest sf,
ManifestDigester md)
- throws IOException
+ throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean attrsVerified = true;
@@ -430,14 +460,14 @@
private boolean verifySection(Attributes sfAttr,
String name,
ManifestDigester md)
- throws IOException
+ throws IOException, SignatureException
{
boolean oneDigestVerified = false;
ManifestDigester.Entry mde = md.get(name,block.isOldStyle());
if (mde == null) {
throw new SecurityException(
- "no manifiest section for signature file entry "+name);
+ "no manifest section for signature file entry "+name);
}
if (sfAttr != null) {
--- a/jdk/src/java.base/share/conf/net.properties Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/conf/net.properties Thu Oct 27 08:52:00 2016 -0700
@@ -72,3 +72,30 @@
# value is 10).
# http.KeepAlive.remainingData=512
# http.KeepAlive.queuedConnections=10
+
+# Authentication Scheme restrictions for HTTP and HTTPS.
+#
+# In some environments certain authentication schemes may be undesirable
+# when proxying HTTP or HTTPS. For example, "Basic" results in effectively the
+# cleartext transmission of the user's password over the physical network.
+# This section describes the mechanism for disabling authentication schemes
+# based on the scheme name. Disabled schemes will be treated as if they are not
+# supported by the implementation.
+#
+# The 'jdk.http.auth.tunneling.disabledSchemes' property lists the authentication
+# schemes that will be disabled when tunneling HTTPS over a proxy, HTTP CONNECT.
+# The 'jdk.http.auth.proxying.disabledSchemes' property lists the authentication
+# schemes that will be disabled when proxying HTTP.
+#
+# In both cases the property is a comma-separated list of, case-insensitive,
+# authentication scheme names, as defined by their relevant RFCs. An
+# implementation may, but is not required to, support common schemes whose names
+# include: 'Basic', 'Digest', 'NTLM', 'Kerberos', 'Negotiate'. A scheme that
+# is not known, or not supported, by the implementation is ignored.
+#
+# Note: This property is currently used by the JDK Reference implementation. It
+# is not guaranteed to be examined and used by other implementations.
+#
+#jdk.http.auth.proxying.disabledSchemes=
+jdk.http.auth.tunneling.disabledSchemes=Basic
+
--- a/jdk/src/java.base/share/conf/security/java.security Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/conf/security/java.security Thu Oct 27 08:52:00 2016 -0700
@@ -655,6 +655,44 @@
jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & denyAfter 2017-01-01, \
RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
+# Algorithm restrictions for signed JAR files
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# for signed JAR validation. For example, "MD2" is generally no longer
+# considered to be a secure hash algorithm. This section describes the
+# mechanism for disabling algorithms based on algorithm name and/or key length.
+# JARs signed with any of the disabled algorithms or key sizes will be treated
+# as unsigned.
+#
+# The syntax of the disabled algorithm string is described as follows:
+# DisabledAlgorithms:
+# " DisabledAlgorithm { , DisabledAlgorithm } "
+#
+# DisabledAlgorithm:
+# AlgorithmName [Constraint]
+#
+# AlgorithmName:
+# (see below)
+#
+# Constraint:
+# KeySizeConstraint
+#
+# KeySizeConstraint:
+# keySize Operator KeyLength
+#
+# Operator:
+# <= | < | == | != | >= | >
+#
+# KeyLength:
+# Integer value of the algorithm's key length in bits
+#
+# Note: This property is currently used by the JDK Reference
+# implementation. It is not guaranteed to be examined and used by other
+# implementations.
+#
+jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
+ DSA keySize < 1024
+
# Algorithm restrictions for Secure Socket Layer/Transport Layer Security
# (SSL/TLS/DTLS) processing
#
@@ -935,3 +973,4 @@
# Otherwise, the status is UNDECIDED.
#
#jdk.serialFilter=pattern;pattern
+
--- a/jdk/src/java.base/share/lib/security/default.policy Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/lib/security/default.policy Thu Oct 27 08:52:00 2016 -0700
@@ -103,7 +103,6 @@
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.*";
permission java.lang.RuntimePermission "loadLibrary.sunec";
- permission java.util.PropertyPermission "*", "read";
permission java.security.SecurityPermission "putProviderProperty.SunEC";
permission java.security.SecurityPermission "clearProviderProperties.SunEC";
permission java.security.SecurityPermission "removeProviderProperty.SunEC";
@@ -112,11 +111,11 @@
grant codeBase "jrt:/jdk.crypto.pkcs11" {
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.*";
- permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
permission java.lang.RuntimePermission "loadLibrary.j2pkcs11";
- // needs "security.pkcs11.allowSingleThreadedModules"
- permission java.util.PropertyPermission "*", "read";
+ permission java.util.PropertyPermission "sun.security.pkcs11.allowSingleThreadedModules", "read";
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.util.PropertyPermission "os.arch", "read";
permission java.security.SecurityPermission "putProviderProperty.*";
permission java.security.SecurityPermission "clearProviderProperties.*";
permission java.security.SecurityPermission "removeProviderProperty.*";
--- a/jdk/src/java.base/share/native/libverify/check_code.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/share/native/libverify/check_code.c Thu Oct 27 08:52:00 2016 -0700
@@ -1293,14 +1293,13 @@
case JVM_OPC_invokevirtual:
case JVM_OPC_invokespecial:
case JVM_OPC_invokestatic:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokeinterface: {
/* Make sure the constant pool item is the right type. */
int key = (code[offset + 1] << 8) + code[offset + 2];
const char *methodname;
jclass cb = context->class;
fullinfo_type clazz_info;
- int is_constructor, is_internal, is_invokedynamic;
+ int is_constructor, is_internal;
int kind;
switch (opcode ) {
@@ -1309,9 +1308,6 @@
? (1 << JVM_CONSTANT_Methodref)
: ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref)));
break;
- case JVM_OPC_invokedynamic:
- kind = 1 << JVM_CONSTANT_NameAndType;
- break;
case JVM_OPC_invokeinterface:
kind = 1 << JVM_CONSTANT_InterfaceMethodref;
break;
@@ -1319,7 +1315,6 @@
kind = 1 << JVM_CONSTANT_Methodref;
}
- is_invokedynamic = opcode == JVM_OPC_invokedynamic;
/* Make sure the constant pool item is the right type. */
verify_constant_pool_type(context, key, kind);
methodname = JVM_GetCPMethodNameUTF(env, cb, key);
@@ -1328,11 +1323,8 @@
is_internal = methodname[0] == '<';
pop_and_free(context);
- if (is_invokedynamic)
- clazz_info = context->object_info; // anything will do
- else
- clazz_info = cp_index_to_class_fullinfo(context, key,
- JVM_CONSTANT_Methodref);
+ clazz_info = cp_index_to_class_fullinfo(context, key,
+ JVM_CONSTANT_Methodref);
this_idata->operand.i = key;
this_idata->operand2.fi = clazz_info;
if (is_constructor) {
@@ -1387,17 +1379,15 @@
"Fourth operand byte of invokeinterface must be zero");
}
pop_and_free(context);
- } else if (opcode == JVM_OPC_invokedynamic) {
- if (code[offset + 3] != 0 || code[offset + 4] != 0) {
- CCerror(context,
- "Third and fourth operand bytes of invokedynamic must be zero");
- }
} else if (opcode == JVM_OPC_invokevirtual
|| opcode == JVM_OPC_invokespecial)
set_protected(context, inumber, key, opcode);
break;
}
+ case JVM_OPC_invokedynamic:
+ CCerror(context,
+ "invokedynamic bytecode is not supported in this class file version");
case JVM_OPC_instanceof:
case JVM_OPC_checkcast:
@@ -2085,7 +2075,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit: /* invokespecial call to <init> */
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: {
/* The top stuff on the stack depends on the method signature */
int operand = this_idata->operand.i;
@@ -2101,8 +2090,7 @@
print_formatted_methodname(context, operand);
}
#endif
- if (opcode != JVM_OPC_invokestatic &&
- opcode != JVM_OPC_invokedynamic)
+ if (opcode != JVM_OPC_invokestatic)
/* First, push the object */
*ip++ = (opcode == JVM_OPC_invokeinit ? '@' : 'A');
for (p = signature + 1; *p != JVM_SIGNATURE_ENDFUNC; ) {
@@ -2388,7 +2376,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokeinterface: case JVM_OPC_invokestatic: {
int operand = this_idata->operand.i;
const char *signature =
@@ -2398,8 +2385,7 @@
int item;
const char *p;
check_and_push(context, signature, VM_STRING_UTF);
- if (opcode == JVM_OPC_invokestatic ||
- opcode == JVM_OPC_invokedynamic) {
+ if (opcode == JVM_OPC_invokestatic) {
item = 0;
} else if (opcode == JVM_OPC_invokeinit) {
fullinfo_type init_type = this_idata->operand2.fi;
@@ -2795,7 +2781,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: {
/* Look to signature to determine correct result. */
int operand = this_idata->operand.i;
--- a/jdk/src/java.base/solaris/lib/security/default.policy Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/solaris/lib/security/default.policy Thu Oct 27 08:52:00 2016 -0700
@@ -4,7 +4,10 @@
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
permission java.lang.RuntimePermission "loadLibrary.j2ucrypto";
// need "com.oracle.security.ucrypto.debug" for debugging
- permission java.util.PropertyPermission "*", "read";
+ permission java.util.PropertyPermission "com.oracle.security.ucrypto.debug", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.util.PropertyPermission "java.home", "read";
+ permission java.util.PropertyPermission "os.name", "read";
permission java.security.SecurityPermission
"putProviderProperty.OracleUcrypto";
permission java.security.SecurityPermission
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.c Thu Oct 27 08:52:00 2016 -0700
@@ -273,13 +273,10 @@
#endif
-
void
NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultDetail) {
- char errmsg[255];
- sprintf(errmsg, "errno: %d, error: %s\n", errno, defaultDetail);
- JNU_ThrowByNameWithLastError(env, name, errmsg);
+ JNU_ThrowByNameWithMessageAndLastError(env, name, defaultDetail);
}
void
--- a/jdk/src/java.base/windows/native/libjli/java_md.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/windows/native/libjli/java_md.c Thu Oct 27 08:52:00 2016 -0700
@@ -48,6 +48,10 @@
char *jvmpath, jint jvmpathsize);
static jboolean GetJREPath(char *path, jint pathsize);
+#ifdef USE_REGISTRY_LOOKUP
+jboolean GetPublicJREHome(char *buf, jint bufsize);
+#endif
+
/* We supports warmup for UI stack that is performed in parallel
* to VM initialization.
* This helps to improve startup of UI application as warmup phase
@@ -346,6 +350,14 @@
}
}
+#ifdef USE_REGISTRY_LOOKUP
+ /* Lookup public JRE using Windows registry. */
+ if (GetPublicJREHome(path, pathsize)) {
+ JLI_TraceLauncher("JRE path is %s\n", path);
+ return JNI_TRUE;
+ }
+#endif
+
JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
return JNI_FALSE;
}
--- a/jdk/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Thu Oct 27 08:52:00 2016 -0700
@@ -554,14 +554,20 @@
* Create a NetworkInterface object and populate it
*/
netifObj = (*env)->NewObject(env, ni_class, ni_ctor);
+ if (netifObj == NULL) {
+ return NULL;
+ }
name = (*env)->NewStringUTF(env, ifs->name);
+ if (name == NULL) {
+ return NULL;
+ }
if (ifs->dNameIsUnicode) {
displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName,
(jsize)wcslen ((PWCHAR)ifs->displayName));
} else {
displayName = (*env)->NewStringUTF(env, ifs->displayName);
}
- if (netifObj == NULL || name == NULL || displayName == NULL) {
+ if (displayName == NULL) {
return NULL;
}
(*env)->SetObjectField(env, netifObj, ni_nameID, name);
@@ -621,26 +627,28 @@
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
} else /* AF_INET6 */ {
int scope;
+ jboolean ret;
iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
- if (iaObj) {
- jboolean ret = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(addrs->addr.sa6.sin6_addr.s6_addr));
- if (ret == JNI_FALSE) {
- return NULL;
- }
- scope = addrs->addr.sa6.sin6_scope_id;
- if (scope != 0) { /* zero is default value, no need to set */
- setInet6Address_scopeid(env, iaObj, scope);
- setInet6Address_scopeifname(env, iaObj, netifObj);
- }
- ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
- if (ibObj == NULL) {
- free_netaddr(netaddrP);
- return NULL;
- }
- (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
- (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
- (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
+ if (iaObj == NULL) {
+ return NULL;
+ }
+ ret = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(addrs->addr.sa6.sin6_addr.s6_addr));
+ if (ret == JNI_FALSE) {
+ return NULL;
}
+ scope = addrs->addr.sa6.sin6_scope_id;
+ if (scope != 0) { /* zero is default value, no need to set */
+ setInet6Address_scopeid(env, iaObj, scope);
+ setInet6Address_scopeifname(env, iaObj, netifObj);
+ }
+ ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
+ if (ibObj == NULL) {
+ free_netaddr(netaddrP);
+ return NULL;
+ }
+ (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
+ (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
+ (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
}
(*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
addrs = addrs->next;
--- a/jdk/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Thu Oct 27 08:52:00 2016 -0700
@@ -830,6 +830,7 @@
}
if (IS_NULL(addressObj)) {
JNU_ThrowNullPointerException(env, "Null address in peek()");
+ return -1;
} else {
address = getInetAddress_addr(env, addressObj);
/* We only handle IPv4 for now. Will support IPv6 once its in the os */
@@ -1127,11 +1128,23 @@
}
if (n == -1) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
+ if (packetBufferLen > MAX_BUFFER_LEN) {
+ free(fullPacket);
+ }
+ return -1;
} else if (n == -2) {
JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
"operation interrupted");
+ if (packetBufferLen > MAX_BUFFER_LEN) {
+ free(fullPacket);
+ }
+ return -1;
} else if (n < 0) {
NET_ThrowCurrent(env, "Datagram receive failed");
+ if (packetBufferLen > MAX_BUFFER_LEN) {
+ free(fullPacket);
+ }
+ return -1;
} else {
jobject packetAddress;
@@ -1882,7 +1895,7 @@
default :
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket option not supported by PlainDatagramSocketImp");
- break;
+ return;
}
@@ -2325,6 +2338,7 @@
if (NET_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl,
sizeof (ittl)) < 0) {
NET_ThrowCurrent(env, "set IP_MULTICAST_TTL failed");
+ return;
}
}
@@ -2518,6 +2532,9 @@
} else {
ifindex = getIndexFromIf (env, niObj);
if (ifindex == -1) {
+ if ((*env)->ExceptionOccurred(env)) {
+ return;
+ }
NET_ThrowCurrent(env, "get ifindex failed");
return;
}
--- a/jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c Thu Oct 27 08:52:00 2016 -0700
@@ -108,7 +108,7 @@
psi_portID = (*env)->GetFieldID(env, cls, "port", "I");
CHECK_NULL(psi_portID);
psi_lastfdID = (*env)->GetFieldID(env, cls, "lastfd", "I");
- CHECK_NULL(psi_portID);
+ CHECK_NULL(psi_lastfdID);
psi_localportID = (*env)->GetFieldID(env, cls, "localport", "I");
CHECK_NULL(psi_localportID);
psi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
@@ -153,17 +153,17 @@
fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
if (IS_NULL(fd1Obj)) {
+ (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
+ NET_SocketClose(fd);
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"null fd1 object");
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
- NET_SocketClose(fd);
return;
}
fd1 = socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
if (fd1 == -1) {
- NET_ThrowCurrent(env, "create");
(*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
NET_SocketClose(fd);
+ NET_ThrowCurrent(env, "create");
return;
} else {
/* Set socket attribute so it is not passed to any child process */
@@ -907,6 +907,7 @@
isRcvTimeoutSupported = JNI_FALSE;
} else {
NET_ThrowCurrent(env, "setsockopt SO_RCVTIMEO");
+ return;
}
}
if (fd1 != -1) {
--- a/jdk/src/java.base/windows/native/libnet/net_util_md.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/windows/native/libnet/net_util_md.c Thu Oct 27 08:52:00 2016 -0700
@@ -205,9 +205,7 @@
void
NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultDetail) {
- char errmsg[255];
- sprintf(errmsg, "errno: %d, error: %s\n", WSAGetLastError(), defaultDetail);
- JNU_ThrowByNameWithLastError(env, name, errmsg);
+ JNU_ThrowByNameWithMessageAndLastError(env, name, defaultDetail);
}
jfieldID
--- a/jdk/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c Thu Oct 27 08:52:00 2016 -0700
@@ -202,6 +202,7 @@
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
+ return IOS_THROWN;
}
return convertReturnVal(env, (jint)written, JNI_FALSE);
@@ -250,6 +251,7 @@
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
+ return IOS_THROWN;
}
return convertLongReturnVal(env, totalWritten, JNI_FALSE);
--- a/jdk/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -817,6 +817,10 @@
ERROR1("<<DAUDIO_Open: ERROR: unsupported encoding (%d)\n", encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1("<<DAUDIO_Open: ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
OSX_DirectAudioDevice *device = new OSX_DirectAudioDevice();
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletSecurity.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletSecurity.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2014, 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
@@ -40,36 +40,25 @@
import java.util.StringTokenizer;
import java.security.*;
import java.lang.reflect.*;
+import jdk.internal.misc.JavaNetURLClassLoaderAccess;
+import jdk.internal.misc.JavaSecurityAccess;
+import jdk.internal.misc.SharedSecrets;
import sun.awt.AWTSecurityManager;
import sun.awt.AppContext;
import sun.awt.AWTPermissions;
import sun.security.util.SecurityConstants;
+
/**
* This class defines an applet security policy
*
*/
public
class AppletSecurity extends AWTSecurityManager {
-
- //URLClassLoader.acc
- private static Field facc = null;
-
- //AccessControlContext.context;
- private static Field fcontext = null;
-
- static {
- try {
- facc = URLClassLoader.class.getDeclaredField("acc");
- facc.setAccessible(true);
- fcontext = AccessControlContext.class.getDeclaredField("context");
- fcontext.setAccessible(true);
- } catch (NoSuchFieldException e) {
- throw new UnsupportedOperationException(e);
- }
- }
-
+ private static final JavaNetURLClassLoaderAccess JNUCLA
+ = SharedSecrets.getJavaNetURLClassLoaderAccess();
+ private static final JavaSecurityAccess JSA = SharedSecrets.getJavaSecurityAccess();
/**
* Construct and initialize.
@@ -148,6 +137,7 @@
final ClassLoader currentLoader = context[i].getClassLoader();
if (currentLoader instanceof URLClassLoader) {
+ URLClassLoader ld = (URLClassLoader)currentLoader;
loader = AccessController.doPrivileged(
new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
@@ -156,12 +146,12 @@
ProtectionDomain[] pds = null;
try {
- acc = (AccessControlContext) facc.get(currentLoader);
+ acc = JNUCLA.getAccessControlContext(ld);
if (acc == null) {
return null;
}
- pds = (ProtectionDomain[]) fcontext.get(acc);
+ pds = JSA.getProtectDomains(acc);
if (pds == null) {
return null;
}
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -46,6 +46,7 @@
ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success)
{
+ if (LE_FAILURE(success)) return;
contextualGlyphSubstitutionHeader.orphan();
substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
@@ -66,10 +67,10 @@
markGlyph = 0;
}
-ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR;
const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
+ if (LE_FAILURE(success)) return 0;
ByteOffset newState = SWAPW(entry->newStateOffset);
le_int16 flags = SWAPW(entry->flags);
WordOffset markOffset = SWAPW(entry->markOffset);
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.h Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.h Thu Oct 27 08:52:00 2016 -0700
@@ -52,7 +52,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -63,10 +63,10 @@
lastGlyph = 0;
}
-ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR; // todo- make a param?
- const IndicRearrangementStateEntry *entry = entryTable.getAlias(index,success);
+ const IndicRearrangementStateEntry *entry = entryTable.getAlias(index, success);
+ if (LE_FAILURE(success)) return 0;
ByteOffset newState = SWAPW(entry->newStateOffset);
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.h Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.h Thu Oct 27 08:52:00 2016 -0700
@@ -52,7 +52,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -67,9 +67,8 @@
m = -1;
}
-ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR;
const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
if (LE_FAILURE(success)) {
currGlyph++;
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.h Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.h Thu Oct 27 08:52:00 2016 -0700
@@ -54,7 +54,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -81,6 +81,7 @@
while (currGlyph <= glyphCount) {
if(LE_STATE_PATIENCE_DECR()) break; // patience exceeded.
+ if (LE_FAILURE(success)) break;
ClassCode classCode = classCodeOOB;
if (currGlyph == glyphCount) {
// XXX: How do we handle EOT vs. EOL?
@@ -100,7 +101,7 @@
EntryTableIndex entryTableIndex = stateArray.getObject((le_uint8)classCode, success);
if (LE_FAILURE(success)) { break; }
LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
- currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
+ currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success);
LE_STATE_PATIENCE_INCR(currGlyph);
}
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.h Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.h Thu Oct 27 08:52:00 2016 -0700
@@ -53,7 +53,7 @@
virtual void beginStateTable() = 0;
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) = 0;
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success) = 0;
virtual void endStateTable() = 0;
--- a/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c Thu Oct 27 08:52:00 2016 -0700
@@ -244,7 +244,7 @@
// To prevent out of bounds indexing
cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v)
{
- return v < 0.0f ? 0.0f : (v > 1.0f ? 1.0f : v);
+ return v < 0.0f || v != v ? 0.0f : (v > 1.0f ? 1.0f : v);
}
// Floating-point version of 1D interpolation
--- a/jdk/src/java.desktop/share/native/liblcms/cmsio0.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsio0.c Thu Oct 27 08:52:00 2016 -0700
@@ -1543,6 +1543,13 @@
// If the element is already in memory, return the pointer
if (Icc -> TagPtrs[n]) {
+ if (Icc -> TagTypeHandlers[n] == NULL) goto Error;
+ BaseType = Icc -> TagTypeHandlers[n]->Signature;
+ if (BaseType == 0) goto Error;
+ TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
+ if (TagDescriptor == NULL) goto Error;
+ if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+
if (Icc ->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked
_cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
--- a/jdk/src/java.desktop/share/native/liblcms/cmstypes.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/share/native/liblcms/cmstypes.c Thu Oct 27 08:52:00 2016 -0700
@@ -4313,7 +4313,10 @@
// Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number
nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? MAX_INPUT_DIMENSIONS : InputChans;
- for (i=0; i < nMaxGrids; i++) GridPoints[i] = (cmsUInt32Number) Dimensions8[i];
+ for (i=0; i < nMaxGrids; i++) {
+ if (Dimensions8[i] == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least
+ GridPoints[i] = (cmsUInt32Number)Dimensions8[i];
+ }
// Allocate the true CLUT
mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL);
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java Thu Oct 27 08:52:00 2016 -0700
@@ -102,10 +102,13 @@
int w, int h)
{
if (cachedData == null) {
- // Bitmask will be created lazily during the blit phase
- cachedData = X11SurfaceData.createData(x11gc, w, h,
- x11gc.getColorModel(),
- null, 0, getTransparency());
+ try {
+ // Bitmask will be created lazily during the blit phase
+ cachedData = X11SurfaceData.createData(x11gc, w, h,
+ x11gc.getColorModel(),
+ null, 0, getTransparency());
+ } catch (OutOfMemoryError oome) {
+ }
}
return cachedData;
}
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java Thu Oct 27 08:52:00 2016 -0700
@@ -138,6 +138,9 @@
vImg = (SunVolatileImage) dst.getGraphicsConfig().createCompatibleVolatileImage(w, h, src.getTransparency());
vImg.setAccelerationPriority(1.0f);
+ if (!(vImg.getDestSurface() instanceof XRSurfaceData)) {
+ throw new InvalidPipeException("Could not create XRSurfaceData");
+ }
if (src.getTransparency() == SurfaceData.OPAQUE) {
rgbTmpPM = new WeakReference<SunVolatileImage>(vImg);
} else {
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java Thu Oct 27 08:52:00 2016 -0700
@@ -59,9 +59,12 @@
public SurfaceData validateSurfaceData(SurfaceData srcData,
SurfaceData cachedData, int w, int h) {
if (cachedData == null) {
- cachedData = XRSurfaceData.createData(xrgc, w, h,
- xrgc.getColorModel(), null, 0,
- getTransparency(), true);
+ try {
+ cachedData = XRSurfaceData.createData(xrgc, w, h,
+ xrgc.getColorModel(), null, 0,
+ getTransparency(), true);
+ } catch (OutOfMemoryError oome) {
+ }
}
return cachedData;
}
--- a/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c Thu Oct 27 08:52:00 2016 -0700
@@ -441,7 +441,7 @@
* width , height must be nonzero otherwise XCreatePixmap
* generates BadValue in error_handler
*/
- if (width <= 0 || height <= 0) {
+ if (width <= 0 || height <= 0 || width > 32767 || height > 32767) {
JNU_ThrowOutOfMemoryError(env,
"Can't create offscreen surface");
return JNI_FALSE;
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c Thu Oct 27 08:52:00 2016 -0700
@@ -434,7 +434,10 @@
snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
}
#endif
-
+ if (channels <= 0) {
+ ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
if (!info) {
ERROR0("Out of memory\n");
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c Thu Oct 27 08:52:00 2016 -0700
@@ -434,7 +434,10 @@
snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
}
#endif
-
+ if (channels <= 0) {
+ ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
if (!info) {
ERROR0("Out of memory\n");
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c Thu Oct 27 08:52:00 2016 -0700
@@ -182,6 +182,10 @@
ERROR1(" DAUDIO_Open: invalid encoding %d\n", (int) encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1(" DAUDIO_Open: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (SolPcmInfo*) malloc(sizeof(SolPcmInfo));
if (!info) {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -153,6 +153,19 @@
@Override
public void setMenuBar(MenuBar mb) {
WMenuBarPeer mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
+ if (mbPeer != null) {
+ if (mbPeer.framePeer != this) {
+ mb.removeNotify();
+ mb.addNotify();
+ mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
+ if (mbPeer != null && mbPeer.framePeer != this) {
+ throw new IllegalStateException("Wrong parent peer");
+ }
+ }
+ if (mbPeer != null) {
+ addChildPeer(mbPeer);
+ }
+ }
setMenuBar0(mbPeer);
updateInsets(insets_);
}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuBarPeer.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuBarPeer.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -31,6 +31,8 @@
// MenuBarPeer implementation
+ final WFramePeer framePeer;
+
@Override
public native void addMenu(Menu m);
@Override
@@ -44,8 +46,11 @@
// Toolkit & peer internals
WMenuBarPeer(MenuBar target) {
this.target = target;
- WFramePeer framePeer = (WFramePeer)
+ framePeer = (WFramePeer)
WToolkit.targetToPeer(target.getParent());
+ if (framePeer != null) {
+ framePeer.addChildPeer(this);
+ }
create(framePeer);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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,6 +107,7 @@
this.target = target;
this.parent = (WMenuPeer) WToolkit.targetToPeer(target.getParent());
this.isCheckbox = isCheckbox;
+ parent.addChildPeer(this);
create(parent);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuPeer.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuPeer.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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,10 +51,12 @@
if (parent instanceof MenuBar) {
WMenuBarPeer mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(parent);
this.parent = mbPeer;
+ mbPeer.addChildPeer(this);
createMenu(mbPeer);
}
else if (parent instanceof Menu) {
this.parent = (WMenuPeer) WToolkit.targetToPeer(parent);
+ this.parent.addChildPeer(this);
createSubMenu(this.parent);
}
else {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -24,6 +24,9 @@
*/
package sun.awt.windows;
+import java.util.Map;
+import java.util.WeakHashMap;
+
abstract class WObjectPeer {
static {
@@ -45,6 +48,8 @@
// used to synchronize the state of this peer
private final Object stateLock = new Object();
+ private volatile Map<WObjectPeer, WObjectPeer> childPeers;
+
public static WObjectPeer getPeerForTarget(Object t) {
WObjectPeer peer = (WObjectPeer) WToolkit.targetToPeer(t);
return peer;
@@ -77,6 +82,9 @@
}
if (call_disposeImpl) {
+ if (childPeers != null) {
+ disposeChildPeers();
+ }
disposeImpl();
}
}
@@ -88,4 +96,33 @@
* Initialize JNI field and method IDs
*/
private static native void initIDs();
+
+ // if a child peer existence depends on this peer, add it to this collection
+ final void addChildPeer(WObjectPeer child) {
+ synchronized (getStateLock()) {
+ if (childPeers == null) {
+ childPeers = new WeakHashMap<>();
+ }
+ if (isDisposed()) {
+ throw new IllegalStateException("Parent peer is disposed");
+ }
+ childPeers.put(child, this);
+ }
+ }
+
+ // called to dispose dependent child peers
+ private void disposeChildPeers() {
+ synchronized (getStateLock()) {
+ for (WObjectPeer child : childPeers.keySet()) {
+ if (child != null) {
+ try {
+ child.dispose();
+ }
+ catch (Exception e) {
+ // ignored
+ }
+ }
+ }
+ }
+ }
}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -58,6 +58,7 @@
parent = WToolkit.getNativeContainer((Component)parent);
parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent);
}
+ parentPeer.addChildPeer(this);
createMenu(parentPeer);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -640,7 +640,7 @@
int AwtFont::getFontDescriptorNumber(JNIEnv *env, jobject font,
jobject fontDescriptor)
{
- int i, num;
+ int i, num = 0;
jobject refFontDescriptor;
jobjectArray array;
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -1113,11 +1113,19 @@
void AwtFrame::SetMenuBar(AwtMenuBar* mb)
{
+ if (menuBar) {
+ menuBar->SetFrame(NULL);
+ }
menuBar = mb;
if (mb == NULL) {
// Remove existing menu bar, if any.
::SetMenu(GetHWnd(), NULL);
} else {
+ AwtFrame* oldFrame = menuBar->GetFrame();
+ if (oldFrame && oldFrame != this) {
+ oldFrame->SetMenuBar(NULL);
+ }
+ menuBar->SetFrame(this);
if (menuBar->GetHMenu() != NULL) {
::SetMenu(GetHWnd(), menuBar->GetHMenu());
}
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -58,6 +58,9 @@
void AwtMenuBar::Dispose()
{
+ if (m_frame != NULL && m_frame->GetMenuBar() == this) {
+ m_frame->SetMenuBar(NULL);
+ }
m_frame = NULL;
AwtMenu::Dispose();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -63,6 +63,9 @@
virtual AwtMenuBar* GetMenuBar() { return this; }
INLINE AwtFrame* GetFrame() { return m_frame; }
+ INLINE void SetFrame(AwtFrame* frame) {
+ m_frame = frame;
+ }
virtual HWND GetOwnerHWnd();
virtual void RedrawMenuBar();
--- a/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -859,6 +859,10 @@
ERROR1("DAUDIO_Open: ERROR: cannot open the device with encoding=%d!\n", encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1("DAUDIO_Open: ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
if (sampleSizeInBits > 8 &&
#ifdef _LITTLE_ENDIAN
isBigEndian
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Thu Oct 27 08:52:00 2016 -0700
@@ -39,8 +39,9 @@
}
protected Class<?> findClass(String name) throws ClassNotFoundException {
+ Class<?> cls;
try {
- return repository.loadClass(name);
+ cls = repository.loadClass(name);
} catch (ClassNotFoundException cne) {
if (cl2 != null) {
return cl2.loadClass(name);
@@ -48,6 +49,15 @@
throw cne;
}
}
+
+ if(!cls.getName().equals(name)){
+ if (cl2 != null) {
+ return cl2.loadClass(name);
+ } else {
+ throw new ClassNotFoundException(name);
+ }
+ }
+ return cls;
}
private ClassLoaderRepository repository;
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptContext.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptContext.java Thu Oct 27 08:52:00 2016 -0700
@@ -85,7 +85,8 @@
public Bindings getBindings(int scope);
/**
- * Sets the value of an attribute in a given scope.
+ * Sets the value of an attribute in a given scope. If the scope is <code>GLOBAL_SCOPE</code>
+ * and no Bindings is set for <code>GLOBAL_SCOPE</code>, then setAttribute call is a no-op.
*
* @param name The name of the attribute to set
* @param value The value of the attribute
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Thu Oct 27 08:52:00 2016 -0700
@@ -216,8 +216,9 @@
* @param statements The statements to be executed. May be return values of
* calls to the <code>getMethodCallSyntax</code> and <code>getOutputStatement</code> methods.
* @return The Program
+ *
+ * @throws NullPointerException if the <code>statements</code> array or any of its elements is null
*/
-
public String getProgram(String... statements);
/**
--- a/jdk/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java Thu Oct 27 08:52:00 2016 -0700
@@ -213,7 +213,8 @@
}
/**
- * Sets the value of an attribute in a given scope.
+ * Sets the value of an attribute in a given scope. If the scope is <code>GLOBAL_SCOPE</code>
+ * and no Bindings is set for <code>GLOBAL_SCOPE</code>, then setAttribute call is a no-op.
*
* @param name The name of the attribute to set
* @param value The value of the attribute
--- a/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java Thu Oct 27 08:52:00 2016 -0700
@@ -694,7 +694,7 @@
"Proxy Ticket " + flags[PROXY_TICKET_FLAG] + "\n" +
"Postdated Ticket " + flags[POSTDATED_TICKET_FLAG] + "\n" +
"Renewable Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
- "Initial Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
+ "Initial Ticket " + flags[INITIAL_TICKET_FLAG] + "\n" +
"Auth Time = " + String.valueOf(authTime) + "\n" +
"Start Time = " + String.valueOf(startTime) + "\n" +
"End Time = " + endTime.toString() + "\n" +
--- a/jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -36,6 +36,7 @@
#include <BaseTsd.h>
#include <wincrypt.h>
#include <stdio.h>
+#include <memory>
#define OID_EKU_ANY "2.5.29.37.0"
@@ -48,6 +49,7 @@
#define KEYSTORE_EXCEPTION "java/security/KeyStoreException"
#define PROVIDER_EXCEPTION "java/security/ProviderException"
#define SIGNATURE_EXCEPTION "java/security/SignatureException"
+#define OUT_OF_MEMORY_ERROR "java/lang/OutOfMemoryError"
extern "C" {
@@ -57,10 +59,22 @@
DEF_STATIC_JNI_OnLoad
/*
+ * Throws an arbitrary Java exception with the given message.
+ */
+void ThrowExceptionWithMessage(JNIEnv *env, const char *exceptionName,
+ const char *szMessage)
+{
+ jclass exceptionClazz = env->FindClass(exceptionName);
+ if (exceptionClazz != NULL) {
+ env->ThrowNew(exceptionClazz, szMessage);
+ }
+}
+
+/*
* Throws an arbitrary Java exception.
* The exception message is a Windows system error message.
*/
-void ThrowException(JNIEnv *env, char *exceptionName, DWORD dwError)
+void ThrowException(JNIEnv *env, const char *exceptionName, DWORD dwError)
{
char szMessage[1024];
szMessage[0] = '\0';
@@ -71,12 +85,22 @@
strcpy(szMessage, "Unknown error");
}
- jclass exceptionClazz = env->FindClass(exceptionName);
- if (exceptionClazz != NULL) {
- env->ThrowNew(exceptionClazz, szMessage);
- }
+ ThrowExceptionWithMessage(env, exceptionName, szMessage);
}
+/*
+ * Overloaded 'operator new[]' variant, which will raise Java's
+ * OutOfMemoryError in the case of a failure.
+ */
+static void* operator new[](std::size_t size, JNIEnv *env)
+{
+ void* buf = ::operator new[](size, std::nothrow);
+ if (buf == NULL) {
+ ThrowExceptionWithMessage(env, OUT_OF_MEMORY_ERROR,
+ "Native memory allocation failed");
+ }
+ return buf;
+}
/*
* Maps the name of a hash algorithm to an algorithm identifier.
@@ -211,7 +235,10 @@
} else if (length > 0) {
- pbData = new BYTE[length];
+ pbData = new (env) BYTE[length];
+ if (pbData == NULL) {
+ __leave;
+ }
if (::CryptGenRandom(
hCryptProv,
@@ -441,7 +468,11 @@
NULL, 0)) > 1) {
// Found friendly name
- pszNameString = new char[cchNameString];
+ pszNameString = new (env) char[cchNameString];
+ if (pszNameString == NULL) {
+ __leave;
+ }
+
CertGetNameString(pc,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL,
pszNameString, cchNameString);
@@ -578,7 +609,10 @@
}
// Copy hash from Java to native buffer
- pHashBuffer = new jbyte[jHashSize];
+ pHashBuffer = new (env) jbyte[jHashSize];
+ if (pHashBuffer == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
// Set hash value in the hash object
@@ -616,7 +650,10 @@
__leave;
}
- pSignedHashBuffer = new jbyte[dwBufLen];
+ pSignedHashBuffer = new (env) jbyte[dwBufLen];
+ if (pSignedHashBuffer == NULL) {
+ __leave;
+ }
if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE)
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
@@ -704,9 +741,16 @@
}
// Copy hash and signedHash from Java to native buffer
- pHashBuffer = new jbyte[jHashSize];
+ pHashBuffer = new (env) jbyte[jHashSize];
+ if (pHashBuffer == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
- pSignedHashBuffer = new jbyte[jSignedHashSize];
+
+ pSignedHashBuffer = new (env) jbyte[jSignedHashSize];
+ if (pSignedHashBuffer == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jSignedHash, 0, jSignedHashSize,
pSignedHashBuffer);
@@ -919,7 +963,10 @@
}
// Copy encoding from Java to native buffer
- pbCertEncoding = new jbyte[jCertEncodingSize];
+ pbCertEncoding = new (env) jbyte[jCertEncodingSize];
+ if (pbCertEncoding == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding);
// Create a certificate context from the encoded cert
@@ -932,7 +979,10 @@
// Set the certificate's friendly name
int size = env->GetStringLength(jCertAliasName);
- pszCertAliasName = new WCHAR[size + 1];
+ pszCertAliasName = new (env) WCHAR[size + 1];
+ if (pszCertAliasName == NULL) {
+ __leave;
+ }
jCertAliasChars = env->GetStringChars(jCertAliasName, NULL);
memcpy(pszCertAliasName, jCertAliasChars, size * sizeof(WCHAR));
@@ -970,7 +1020,10 @@
__leave;
}
- pszContainerName = new char[dwDataLen];
+ pszContainerName = new (env) char[dwDataLen];
+ if (pszContainerName == NULL) {
+ __leave;
+ }
if (! ::CryptGetProvParam(
(HCRYPTPROV) hCryptProv,
@@ -984,7 +1037,10 @@
}
// Convert to a wide char string
- pwszContainerName = new WCHAR[dwDataLen];
+ pwszContainerName = new (env) WCHAR[dwDataLen];
+ if (pwszContainerName == NULL) {
+ __leave;
+ }
if (mbstowcs(pwszContainerName, pszContainerName, dwDataLen) == 0) {
ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
@@ -1007,7 +1063,10 @@
__leave;
}
- pszProviderName = new char[dwDataLen];
+ pszProviderName = new (env) char[dwDataLen];
+ if (pszProviderName == NULL) {
+ __leave;
+ }
if (! ::CryptGetProvParam(
(HCRYPTPROV) hCryptProv,
@@ -1021,7 +1080,10 @@
}
// Convert to a wide char string
- pwszProviderName = new WCHAR[dwDataLen];
+ pwszProviderName = new (env) WCHAR[dwDataLen];
+ if (pwszProviderName == NULL) {
+ __leave;
+ }
if (mbstowcs(pwszProviderName, pszProviderName, dwDataLen) == 0) {
ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
@@ -1161,7 +1223,10 @@
}
// Copy encoding from Java to native buffer
- pbCertEncoding = new jbyte[jCertEncodingSize];
+ pbCertEncoding = new (env) jbyte[jCertEncodingSize];
+ if (pbCertEncoding == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding);
// Create a certificate context from the encoded cert
@@ -1184,7 +1249,10 @@
if ((cchNameString = ::CertGetNameString(pTBDCertContext,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) > 1) {
- pszNameString = new char[cchNameString];
+ pszNameString = new (env) char[cchNameString];
+ if (pszNameString == NULL) {
+ __leave;
+ }
::CertGetNameString(pTBDCertContext,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString,
@@ -1334,7 +1402,10 @@
continue; // not found
}
- pszNameString = new char[cchNameString];
+ pszNameString = new (env) char[cchNameString];
+ if (pszNameString == NULL) {
+ __leave;
+ }
if (::CertGetNameString(pCertContext,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString,
@@ -1510,7 +1581,10 @@
__try
{
// Copy data from Java buffer to native buffer
- pData = new jbyte[dwBufLen];
+ pData = new (env) jbyte[dwBufLen];
+ if (pData == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jData, 0, dwBufLen, pData);
if (doEncrypt == JNI_TRUE) {
@@ -1584,7 +1658,10 @@
__leave;
}
- pbKeyBlob = new BYTE[dwBlobLen];
+ pbKeyBlob = new (env) BYTE[dwBlobLen];
+ if (pbKeyBlob == NULL) {
+ __leave;
+ }
// Generate key blob
if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0,
@@ -1638,8 +1715,12 @@
RSAPUBKEY* pRsaPubKey =
(RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));
+
int len = sizeof(pRsaPubKey->pubexp);
- exponentBytes = new jbyte[len];
+ exponentBytes = new (env) jbyte[len];
+ if (exponentBytes == NULL) {
+ __leave;
+ }
// convert from little-endian while copying from blob
for (int i = 0, j = len - 1; i < len; i++, j--) {
@@ -1690,9 +1771,12 @@
RSAPUBKEY* pRsaPubKey =
(RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));
+
int len = pRsaPubKey->bitlen / 8;
-
- modulusBytes = new jbyte[len];
+ modulusBytes = new (env) jbyte[len];
+ if (modulusBytes == NULL) {
+ __leave;
+ }
BYTE * pbModulus =
(BYTE *) (keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));
@@ -1813,12 +1897,16 @@
(jKeyBitLength / 8);
}
- jbyte* jBlobBytes = new jbyte[jBlobLength];
+ jbyte* jBlobBytes = NULL;
jbyte* jBlobElement;
jbyteArray jBlob = NULL;
jsize jElementLength;
__try {
+ jBlobBytes = new (env) jbyte[jBlobLength];
+ if (jBlobBytes == NULL) {
+ __leave;
+ }
BLOBHEADER *pBlobHeader = (BLOBHEADER *) jBlobBytes;
if (bGeneratePrivateKeyBlob) {
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Config.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Config.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,6 @@
import java.security.*;
-import sun.security.action.GetPropertyAction;
import sun.security.util.PropertyExpander;
import sun.security.pkcs11.wrapper.*;
@@ -58,15 +57,30 @@
// will accept single threaded modules regardless of the setting in their
// config files.
private static final boolean staticAllowSingleThreadedModules;
+ private static final String osName;
+ private static final String osArch;
static {
- String p = "sun.security.pkcs11.allowSingleThreadedModules";
- String s = AccessController.doPrivileged(new GetPropertyAction(p));
- if ("false".equalsIgnoreCase(s)) {
+ List<String> props = AccessController.doPrivileged(
+ new PrivilegedAction<>() {
+ @Override
+ public List<String> run() {
+ return List.of(
+ System.getProperty(
+ "sun.security.pkcs11.allowSingleThreadedModules",
+ "true"),
+ System.getProperty("os.name"),
+ System.getProperty("os.arch"));
+ }
+ }
+ );
+ if ("false".equalsIgnoreCase(props.get(0))) {
staticAllowSingleThreadedModules = false;
} else {
staticAllowSingleThreadedModules = true;
}
+ osName = props.get(1);
+ osArch = props.get(2);
}
private final static boolean DEBUG = false;
@@ -650,8 +664,6 @@
// replace "/$ISA/" with "/sparcv9/" on 64-bit Solaris SPARC
// and with "/amd64/" on Solaris AMD64.
// On all other platforms, just turn it into a "/"
- String osName = System.getProperty("os.name", "");
- String osArch = System.getProperty("os.arch", "");
String prefix = lib.substring(0, i);
String suffix = lib.substring(i + 5);
if (osName.equals("SunOS") && osArch.equals("sparcv9")) {
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/wrapper/Constants.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/wrapper/Constants.java Thu Oct 27 08:52:00 2016 -0700
@@ -58,7 +58,7 @@
*/
public class Constants {
- public static final String NEWLINE = System.getProperty("line.separator");
+ public static final String NEWLINE = System.lineSeparator();
public static final String INDENT = " ";
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java Thu Oct 27 08:52:00 2016 -0700
@@ -50,12 +50,13 @@
try {
// cannot use LoadLibraryAction because that would make the native
// library available to the bootclassloader, but we run in the
- // extension classloader.
- String osname = System.getProperty("os.name");
- if (osname.startsWith("SunOS")) {
- provProp = AccessController.doPrivileged
- (new PrivilegedAction<HashMap<String, ServiceDesc>>() {
- public HashMap<String, ServiceDesc> run() {
+ // platform classloader.
+ provProp = AccessController.doPrivileged
+ (new PrivilegedAction<>() {
+ @Override
+ public HashMap<String, ServiceDesc> run() {
+ String osname = System.getProperty("os.name");
+ if (osname.startsWith("SunOS")) {
try {
DEBUG = Boolean.parseBoolean(System.getProperty("com.oracle.security.ucrypto.debug"));
String javaHome = System.getProperty("java.home");
@@ -66,14 +67,13 @@
return new HashMap<>();
} catch (Error err) {
if (DEBUG) err.printStackTrace();
- return null;
} catch (SecurityException se) {
if (DEBUG) se.printStackTrace();
- return null;
}
}
- });
- }
+ return null;
+ }
+ });
if (provProp != null) {
boolean[] result = loadLibraries();
if (result.length == 2) {
--- a/jdk/src/jdk.httpserver/share/classes/module-info.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.httpserver/share/classes/module-info.java Thu Oct 27 08:52:00 2016 -0700
@@ -24,7 +24,6 @@
*/
module jdk.httpserver {
- requires java.logging;
exports com.sun.net.httpserver;
exports com.sun.net.httpserver.spi;
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ExchangeImpl.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ExchangeImpl.java Thu Oct 27 08:52:00 2016 -0700
@@ -29,7 +29,8 @@
import java.net.*;
import javax.net.ssl.*;
import java.util.*;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.text.*;
import com.sun.net.httpserver.*;
@@ -221,7 +222,7 @@
Logger logger = server.getLogger();
String msg = "sendResponseHeaders: rCode = "+ rCode
+ ": forcing contentLen = -1";
- logger.warning (msg);
+ logger.log (Level.WARNING, msg);
}
contentLen = -1;
}
@@ -234,7 +235,7 @@
final Logger logger = server.getLogger();
String msg =
"sendResponseHeaders: being invoked with a content length for a HEAD request";
- logger.warning (msg);
+ logger.log (Level.WARNING, msg);
}
noContentToSend = true;
contentLen = 0;
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpConnection.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpConnection.java Thu Oct 27 08:52:00 2016 -0700
@@ -28,7 +28,8 @@
import java.io.*;
import javax.net.ssl.*;
import java.nio.channels.*;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.*;
@@ -119,7 +120,7 @@
}
closed = true;
if (logger != null && chan != null) {
- logger.finest ("Closing connection: " + chan.toString());
+ logger.log (Level.TRACE, "Closing connection: " + chan.toString());
}
if (!chan.isOpen()) {
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpContextImpl.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpContextImpl.java Thu Oct 27 08:52:00 2016 -0700
@@ -26,7 +26,7 @@
package sun.net.httpserver;
import java.io.*;
import java.util.*;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.*;
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerConfig.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerConfig.java Thu Oct 27 08:52:00 2016 -0700
@@ -25,7 +25,8 @@
package sun.net.httpserver;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.security.PrivilegedAction;
/**
@@ -115,7 +116,8 @@
if (System.getProperty("sun.net.httpserver.readTimeout")
!=null)
{
- logger.warning ("sun.net.httpserver.readTimeout "+
+ logger.log (Level.WARNING,
+ "sun.net.httpserver.readTimeout "+
"property is no longer used. "+
"Use sun.net.httpserver.maxReqTime instead."
);
@@ -123,7 +125,8 @@
if (System.getProperty("sun.net.httpserver.writeTimeout")
!=null)
{
- logger.warning ("sun.net.httpserver.writeTimeout "+
+ logger.log (Level.WARNING,
+ "sun.net.httpserver.writeTimeout "+
"property is no longer used. Use "+
"sun.net.httpserver.maxRspTime instead."
);
@@ -131,7 +134,8 @@
if (System.getProperty("sun.net.httpserver.selCacheTimeout")
!=null)
{
- logger.warning ("sun.net.httpserver.selCacheTimeout "+
+ logger.log (Level.WARNING,
+ "sun.net.httpserver.selCacheTimeout "+
"property is no longer used."
);
}
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java Thu Oct 27 08:52:00 2016 -0700
@@ -30,8 +30,8 @@
import java.nio.channels.*;
import java.util.*;
import java.util.concurrent.*;
-import java.util.logging.Logger;
-import java.util.logging.Level;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import javax.net.ssl.*;
import com.sun.net.httpserver.*;
import java.security.AccessController;
@@ -81,7 +81,7 @@
final static boolean timer1Enabled = MAX_REQ_TIME != -1 || MAX_RSP_TIME != -1;
private Timer timer, timer1;
- private Logger logger;
+ private final Logger logger;
private Thread dispatcherThread;
ServerImpl (
@@ -90,7 +90,7 @@
this.protocol = protocol;
this.wrapper = wrapper;
- this.logger = Logger.getLogger ("com.sun.net.httpserver");
+ this.logger = System.getLogger ("com.sun.net.httpserver");
ServerConfig.checkLegacyProperties (logger);
https = protocol.equalsIgnoreCase ("https");
this.address = addr;
@@ -115,12 +115,12 @@
if (timer1Enabled) {
timer1 = new Timer ("server-timer1", true);
timer1.schedule (new ServerTimerTask1(),TIMER_MILLIS,TIMER_MILLIS);
- logger.config ("HttpServer timer1 enabled period in ms: "+TIMER_MILLIS);
- logger.config ("MAX_REQ_TIME: "+MAX_REQ_TIME);
- logger.config ("MAX_RSP_TIME: "+MAX_RSP_TIME);
+ logger.log (Level.DEBUG, "HttpServer timer1 enabled period in ms: ", TIMER_MILLIS);
+ logger.log (Level.DEBUG, "MAX_REQ_TIME: "+MAX_REQ_TIME);
+ logger.log (Level.DEBUG, "MAX_RSP_TIME: "+MAX_RSP_TIME);
}
events = new LinkedList<Event>();
- logger.config ("HttpServer created "+protocol+" "+ addr);
+ logger.log (Level.DEBUG, "HttpServer created "+protocol+" "+ addr);
}
public void bind (InetSocketAddress addr, int backlog) throws IOException {
@@ -211,7 +211,7 @@
dispatcherThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
- logger.log(Level.FINER, "ServerImpl.stop: ", e);
+ logger.log (Level.TRACE, "ServerImpl.stop: ", e);
}
}
}
@@ -224,7 +224,7 @@
}
HttpContextImpl context = new HttpContextImpl (protocol, path, handler, this);
contexts.add (context);
- logger.config ("context created: " + path);
+ logger.log (Level.DEBUG, "context created: " + path);
return context;
}
@@ -234,7 +234,7 @@
}
HttpContextImpl context = new HttpContextImpl (protocol, path, null, this);
contexts.add (context);
- logger.config ("context created: " + path);
+ logger.log (Level.DEBUG, "context created: " + path);
return context;
}
@@ -243,7 +243,7 @@
throw new NullPointerException ("null path parameter");
}
contexts.remove (protocol, path);
- logger.config ("context removed: " + path);
+ logger.log (Level.DEBUG, "context removed: " + path);
}
public synchronized void removeContext (HttpContext context) throws IllegalArgumentException {
@@ -251,7 +251,7 @@
throw new IllegalArgumentException ("wrong HttpContext type");
}
contexts.remove ((HttpContextImpl)context);
- logger.config ("context removed: " + context.getPath());
+ logger.log (Level.DEBUG, "context removed: " + context.getPath());
}
public InetSocketAddress getAddress() {
@@ -310,7 +310,7 @@
}
} catch (IOException e) {
logger.log (
- Level.FINER, "Dispatcher (1)", e
+ Level.TRACE, "Dispatcher (1)", e
);
c.close();
}
@@ -331,7 +331,7 @@
idleConnections.add (c);
} catch (IOException e) {
dprint(e);
- logger.log(Level.FINER, "Dispatcher(8)", e);
+ logger.log (Level.TRACE, "Dispatcher(8)", e);
c.close();
}
}
@@ -416,9 +416,9 @@
// call the selector just to process the cancelled keys
selector.selectNow();
} catch (IOException e) {
- logger.log (Level.FINER, "Dispatcher (4)", e);
+ logger.log (Level.TRACE, "Dispatcher (4)", e);
} catch (Exception e) {
- logger.log (Level.FINER, "Dispatcher (7)", e);
+ logger.log (Level.TRACE, "Dispatcher (7)", e);
}
}
try {selector.close(); } catch (Exception e) {}
@@ -427,7 +427,7 @@
private void handleException (SelectionKey key, Exception e) {
HttpConnection conn = (HttpConnection)key.attachment();
if (e != null) {
- logger.log (Level.FINER, "Dispatcher (2)", e);
+ logger.log (Level.TRACE, "Dispatcher (2)", e);
}
closeConnection(conn);
}
@@ -439,10 +439,10 @@
Exchange t = new Exchange (chan, protocol, conn);
executor.execute (t);
} catch (HttpError e1) {
- logger.log (Level.FINER, "Dispatcher (4)", e1);
+ logger.log (Level.TRACE, "Dispatcher (4)", e1);
closeConnection(conn);
} catch (IOException e) {
- logger.log (Level.FINER, "Dispatcher (5)", e);
+ logger.log (Level.TRACE, "Dispatcher (5)", e);
closeConnection(conn);
}
}
@@ -522,7 +522,8 @@
newconnection = true;
if (https) {
if (sslContext == null) {
- logger.warning ("SSL connection received. No https contxt created");
+ logger.log (Level.WARNING,
+ "SSL connection received. No https contxt created");
throw new HttpError ("No SSL context established");
}
sslStreams = new SSLStreams (ServerImpl.this, sslContext, chan);
@@ -657,7 +658,7 @@
}
} catch (IOException e1) {
- logger.log (Level.FINER, "ServerImpl.Exchange (1)", e1);
+ logger.log (Level.TRACE, "ServerImpl.Exchange (1)", e1);
closeConnection(connection);
} catch (NumberFormatException e3) {
reject (Code.HTTP_BAD_REQUEST,
@@ -666,7 +667,7 @@
reject (Code.HTTP_BAD_REQUEST,
requestLine, "URISyntaxException thrown");
} catch (Exception e4) {
- logger.log (Level.FINER, "ServerImpl.Exchange (2)", e4);
+ logger.log (Level.TRACE, "ServerImpl.Exchange (2)", e4);
closeConnection(connection);
}
}
@@ -722,7 +723,7 @@
closeConnection(connection);
}
} catch (IOException e) {
- logger.log (Level.FINER, "ServerImpl.sendReply", e);
+ logger.log (Level.TRACE, "ServerImpl.sendReply", e);
closeConnection(connection);
}
}
@@ -730,7 +731,7 @@
}
void logReply (int code, String requestStr, String text) {
- if (!logger.isLoggable(Level.FINE)) {
+ if (!logger.isLoggable(Level.DEBUG)) {
return;
}
if (text == null) {
@@ -744,7 +745,7 @@
}
String message = r + " [" + code + " " +
Code.msg(code) + "] ("+text+")";
- logger.fine (message);
+ logger.log (Level.DEBUG, message);
}
long getTicks() {
@@ -843,7 +844,7 @@
}
}
for (HttpConnection c : toClose) {
- logger.log (Level.FINE, "closing: no request: " + c);
+ logger.log (Level.DEBUG, "closing: no request: " + c);
reqConnections.remove (c);
allConnections.remove (c);
c.close();
@@ -859,7 +860,7 @@
}
}
for (HttpConnection c : toClose) {
- logger.log (Level.FINE, "closing: no response: " + c);
+ logger.log (Level.DEBUG, "closing: no response: " + c);
rspConnections.remove (c);
allConnections.remove (c);
c.close();
@@ -870,13 +871,13 @@
}
void logStackTrace (String s) {
- logger.finest (s);
+ logger.log (Level.TRACE, s);
StringBuilder b = new StringBuilder ();
StackTraceElement[] e = Thread.currentThread().getStackTrace();
for (int i=0; i<e.length; i++) {
b.append (e[i].toString()).append("\n");
}
- logger.finest (b.toString());
+ logger.log (Level.TRACE, b.toString());
}
static long getTimeMillis(long secs) {
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java Thu Oct 27 08:52:00 2016 -0700
@@ -50,6 +50,9 @@
import jdk.security.jarsigner.JarSigner;
import jdk.security.jarsigner.JarSignerException;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.SignerInfo;
+import sun.security.timestamp.TimestampToken;
import sun.security.tools.KeyStoreUtil;
import sun.security.x509.*;
import sun.security.util.*;
@@ -87,6 +90,15 @@
private static final long SIX_MONTHS = 180*24*60*60*1000L; //milliseconds
+ private static final DisabledAlgorithmConstraints DISABLED_CHECK =
+ new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
+
+ private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET = Collections
+ .unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
+ private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
+ .unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
+
// Attention:
// This is the entry that get launched by the security tool jarsigner.
public static void main(String args[]) throws Exception {
@@ -163,6 +175,8 @@
private Throwable chainNotValidatedReason = null;
+ private boolean seeWeak = false;
+
CertificateFactory certificateFactory;
CertPathValidator validator;
PKIXParameters pkixParameters;
@@ -628,6 +642,10 @@
{
boolean anySigned = false; // if there exists entry inside jar signed
JarFile jf = null;
+ Map<String,String> digestMap = new HashMap<>();
+ Map<String,PKCS7> sigMap = new HashMap<>();
+ Map<String,String> sigNameMap = new HashMap<>();
+ Map<String,String> unparsableSignatures = new HashMap<>();
try {
jf = new JarFile(jarName, true);
@@ -638,21 +656,50 @@
while (entries.hasMoreElements()) {
JarEntry je = entries.nextElement();
entriesVec.addElement(je);
- InputStream is = null;
- try {
- is = jf.getInputStream(je);
- while (is.read(buffer, 0, buffer.length) != -1) {
- // we just read. this will throw a SecurityException
- // if a signature/digest check fails.
- }
- } finally {
- if (is != null) {
- is.close();
+ try (InputStream is = jf.getInputStream(je)) {
+ String name = je.getName();
+ if (signatureRelated(name)
+ && SignatureFileVerifier.isBlockOrSF(name)) {
+ String alias = name.substring(name.lastIndexOf('/') + 1,
+ name.lastIndexOf('.'));
+ try {
+ if (name.endsWith(".SF")) {
+ Manifest sf = new Manifest(is);
+ boolean found = false;
+ for (Object obj : sf.getMainAttributes().keySet()) {
+ String key = obj.toString();
+ if (key.endsWith("-Digest-Manifest")) {
+ digestMap.put(alias,
+ key.substring(0, key.length() - 16));
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ unparsableSignatures.putIfAbsent(alias,
+ String.format(
+ rb.getString("history.unparsable"),
+ name));
+ }
+ } else {
+ sigNameMap.put(alias, name);
+ sigMap.put(alias, new PKCS7(is));
+ }
+ } catch (IOException ioe) {
+ unparsableSignatures.putIfAbsent(alias, String.format(
+ rb.getString("history.unparsable"), name));
+ }
+ } else {
+ while (is.read(buffer, 0, buffer.length) != -1) {
+ // we just read. this will throw a SecurityException
+ // if a signature/digest check fails.
+ }
}
}
}
Manifest man = jf.getManifest();
+ boolean hasSignature = false;
// The map to record display info, only used when -verbose provided
// key: signer info string
@@ -668,6 +715,10 @@
while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
String name = je.getName();
+
+ hasSignature = hasSignature
+ || SignatureFileVerifier.isBlockOrSF(name);
+
CodeSigner[] signers = je.getCodeSigners();
boolean isSigned = (signers != null);
anySigned |= isSigned;
@@ -800,10 +851,11 @@
System.out.println(rb.getString(
".X.not.signed.by.specified.alias.es."));
}
- System.out.println();
}
- if (man == null)
+ if (man == null) {
+ System.out.println();
System.out.println(rb.getString("no.manifest."));
+ }
// If signer is a trusted cert or private entry in user's own
// keystore, it can be self-signed.
@@ -811,9 +863,103 @@
signerSelfSigned = false;
}
+ // Even if the verbose option is not specified, all out strings
+ // must be generated so seeWeak can be updated.
+ if (!digestMap.isEmpty()
+ || !sigMap.isEmpty()
+ || !unparsableSignatures.isEmpty()) {
+ if (verbose != null) {
+ System.out.println();
+ }
+ for (String s : sigMap.keySet()) {
+ if (!digestMap.containsKey(s)) {
+ unparsableSignatures.putIfAbsent(s, String.format(
+ rb.getString("history.nosf"), s));
+ }
+ }
+ for (String s : digestMap.keySet()) {
+ PKCS7 p7 = sigMap.get(s);
+ if (p7 != null) {
+ String history;
+ try {
+ SignerInfo si = p7.getSignerInfos()[0];
+ X509Certificate signer = si.getCertificate(p7);
+ String digestAlg = digestMap.get(s);
+ String sigAlg = AlgorithmId.makeSigAlg(
+ si.getDigestAlgorithmId().getName(),
+ si.getDigestEncryptionAlgorithmId().getName());
+ PublicKey key = signer.getPublicKey();
+ PKCS7 tsToken = si.getTsToken();
+ if (tsToken != null) {
+ SignerInfo tsSi = tsToken.getSignerInfos()[0];
+ X509Certificate tsSigner = tsSi.getCertificate(tsToken);
+ byte[] encTsTokenInfo = tsToken.getContentInfo().getData();
+ TimestampToken tsTokenInfo = new TimestampToken(encTsTokenInfo);
+ PublicKey tsKey = tsSigner.getPublicKey();
+ String tsDigestAlg = tsTokenInfo.getHashAlgorithm().getName();
+ String tsSigAlg = AlgorithmId.makeSigAlg(
+ tsSi.getDigestAlgorithmId().getName(),
+ tsSi.getDigestEncryptionAlgorithmId().getName());
+ Calendar c = Calendar.getInstance(
+ TimeZone.getTimeZone("UTC"),
+ Locale.getDefault(Locale.Category.FORMAT));
+ c.setTime(tsTokenInfo.getDate());
+ history = String.format(
+ rb.getString("history.with.ts"),
+ signer.getSubjectX500Principal(),
+ withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
+ withWeak(sigAlg, SIG_PRIMITIVE_SET),
+ withWeak(key),
+ c,
+ tsSigner.getSubjectX500Principal(),
+ withWeak(tsDigestAlg, DIGEST_PRIMITIVE_SET),
+ withWeak(tsSigAlg, SIG_PRIMITIVE_SET),
+ withWeak(tsKey));
+ } else {
+ history = String.format(
+ rb.getString("history.without.ts"),
+ signer.getSubjectX500Principal(),
+ withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
+ withWeak(sigAlg, SIG_PRIMITIVE_SET),
+ withWeak(key));
+ }
+ } catch (Exception e) {
+ // The only usage of sigNameMap, remember the name
+ // of the block file if it's invalid.
+ history = String.format(
+ rb.getString("history.unparsable"),
+ sigNameMap.get(s));
+ }
+ if (verbose != null) {
+ System.out.println(history);
+ }
+ } else {
+ unparsableSignatures.putIfAbsent(s, String.format(
+ rb.getString("history.nobk"), s));
+ }
+ }
+ if (verbose != null) {
+ for (String s : unparsableSignatures.keySet()) {
+ System.out.println(unparsableSignatures.get(s));
+ }
+ }
+ }
+ System.out.println();
if (!anySigned) {
- System.out.println(rb.getString(
- "jar.is.unsigned.signatures.missing.or.not.parsable."));
+ if (seeWeak) {
+ if (verbose != null) {
+ System.out.println(rb.getString("jar.treated.unsigned.see.weak.verbose"));
+ System.out.println("\n " +
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS +
+ "=" + Security.getProperty(DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS));
+ } else {
+ System.out.println(rb.getString("jar.treated.unsigned.see.weak"));
+ }
+ } else if (hasSignature) {
+ System.out.println(rb.getString("jar.treated.unsigned"));
+ } else {
+ System.out.println(rb.getString("jar.is.unsigned"));
+ }
} else {
boolean warningAppeared = false;
boolean errorAppeared = false;
@@ -837,7 +983,9 @@
if (weakAlg != 0) {
// In fact, jarsigner verification did not catch this
// since it has not read the JarFile content itself.
- // Everything is done with JarFile API.
+ // Everything is done with JarFile API. The signing
+ // history (digestMap etc) will show these info and
+ // print out proper warnings.
}
if (badKeyUsage) {
@@ -928,6 +1076,26 @@
System.exit(1);
}
+ private String withWeak(String alg, Set<CryptoPrimitive> primitiveSet) {
+ if (DISABLED_CHECK.permits(primitiveSet, alg, null)) {
+ return alg;
+ } else {
+ seeWeak = true;
+ return String.format(rb.getString("with.weak"), alg);
+ }
+ }
+
+ private String withWeak(PublicKey key) {
+ if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
+ return String.format(
+ rb.getString("key.bit"), KeyUtil.getKeySize(key));
+ } else {
+ seeWeak = true;
+ return String.format(
+ rb.getString("key.bit.weak"), KeyUtil.getKeySize(key));
+ }
+ }
+
private static MessageFormat validityTimeForm = null;
private static MessageFormat notYetTimeForm = null;
private static MessageFormat expiredTimeForm = null;
@@ -1117,22 +1285,22 @@
void signJar(String jarName, String alias)
throws Exception {
- DisabledAlgorithmConstraints dac =
- new DisabledAlgorithmConstraints(
- DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
-
- if (digestalg != null && !dac.permits(
- Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), digestalg, null)) {
+ if (digestalg != null && !DISABLED_CHECK.permits(
+ DIGEST_PRIMITIVE_SET, digestalg, null)) {
weakAlg |= 1;
}
- if (tSADigestAlg != null && !dac.permits(
- Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), tSADigestAlg, null)) {
+ if (tSADigestAlg != null && !DISABLED_CHECK.permits(
+ DIGEST_PRIMITIVE_SET, tSADigestAlg, null)) {
weakAlg |= 4;
}
- if (sigalg != null && !dac.permits(
- Collections.singleton(CryptoPrimitive.SIGNATURE), sigalg, null)) {
+ if (sigalg != null && !DISABLED_CHECK.permits(
+ SIG_PRIMITIVE_SET , sigalg, null)) {
weakAlg |= 2;
}
+ if (!DISABLED_CHECK.permits(
+ SIG_PRIMITIVE_SET, privateKey)) {
+ weakAlg |= 8;
+ }
boolean aliasUsed = false;
X509Certificate tsaCert = null;
@@ -1377,6 +1545,11 @@
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
tSADigestAlg, "-tsadigestalg"));
}
+ if ((weakAlg & 8) == 8) {
+ System.out.println(String.format(
+ rb.getString("The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk."),
+ privateKey.getAlgorithm(), KeyUtil.getKeySize(privateKey)));
+ }
} else {
System.out.println(rb.getString("jar.signed."));
}
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java Thu Oct 27 08:52:00 2016 -0700
@@ -142,12 +142,29 @@
{"no.manifest.", "no manifest."},
{".Signature.related.entries.","(Signature related entries)"},
{".Unsigned.entries.", "(Unsigned entries)"},
- {"jar.is.unsigned.signatures.missing.or.not.parsable.",
- "jar is unsigned. (signatures missing or not parsable)"},
+ {"jar.is.unsigned",
+ "jar is unsigned."},
+ {"jar.treated.unsigned",
+ "WARNING: Signature is either not parsable or not verifiable, and the jar will be treated as unsigned. For more information, re-run jarsigner with debug enabled (-J-Djava.security.debug=jar)."},
+ {"jar.treated.unsigned.see.weak",
+ "The jar will be treated as unsigned, because it is signed with a weak algorithm that is now disabled.\n\nRe-run jarsigner with the -verbose option for more details."},
+ {"jar.treated.unsigned.see.weak.verbose",
+ "WARNING: The jar will be treated as unsigned, because it is signed with a weak algorithm that is now disabled by the security property:"},
{"jar.signed.", "jar signed."},
{"jar.signed.with.signer.errors.", "jar signed, with signer errors."},
{"jar.verified.", "jar verified."},
{"jar.verified.with.signer.errors.", "jar verified, with signer errors."},
+
+ {"history.with.ts", "- Signed by \"%1$s\"\n Digest algorithm: %2$s\n Signature algorithm: %3$s, %4$s\n Timestamped by \"%6$s\" on %5$tc\n Timestamp digest algorithm: %7$s\n Timestamp signature algorithm: %8$s, %9$s"},
+ {"history.without.ts", "- Signed by \"%1$s\"\n Digest algorithm: %2$s\n Signature algorithm: %3$s, %4$s"},
+ {"history.unparsable", "- Unparsable signature-related file %s"},
+ {"history.nosf", "- Missing signature-related file META-INF/%s.SF"},
+ {"history.nobk", "- Missing block file for signature-related file META-INF/%s.SF"},
+
+ {"with.weak", "%s (weak)"},
+ {"key.bit", "%d-bit key"},
+ {"key.bit.weak", "%d-bit key (weak)"},
+
{"jarsigner.", "jarsigner: "},
{"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.",
"signature filename must consist of the following characters: A-Z, 0-9, _ or -"},
@@ -246,6 +263,8 @@
"The signer's certificate is self-signed."},
{"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.",
"The %1$s algorithm specified for the %2$s option is considered a security risk."},
+ {"The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk.",
+ "The %s signing key has a keysize of %d which is considered a security risk."},
{"This.jar.contains.entries.whose.certificate.chain.is.not.validated.reason.1",
"This jar contains entries whose certificate chain is not validated. Reason: %s"},
{"no.timestamp.signing",
--- a/jdk/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -96,6 +96,11 @@
*/
enum {
+ /*
+ * If additional flags are added that apply to jdwpCmdPacket,
+ * then debugLoop.c: reader() will need to be updated to
+ * accept more than JDWPTRANSPORT_FLAGS_NONE.
+ */
JDWPTRANSPORT_FLAGS_NONE = 0x0,
JDWPTRANSPORT_FLAGS_REPLY = 0x80
};
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugLoop.c Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugLoop.c Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -218,6 +218,20 @@
if (rc != 0 || (rc == 0 && packet.type.cmd.len == 0)) {
shouldListen = JNI_FALSE;
notifyTransportError();
+ } else if (packet.type.cmd.flags != JDWPTRANSPORT_FLAGS_NONE) {
+ /*
+ * Close the connection when we get a jdwpCmdPacket with an
+ * invalid flags field value. This is a protocol violation
+ * so we drop the connection. Also this could be a web
+ * browser generating an HTTP request that passes the JDWP
+ * handshake. HTTP requests requires that everything be in
+ * the ASCII printable range so a flags value of
+ * JDWPTRANSPORT_FLAGS_NONE(0) cannot be generated via HTTP.
+ */
+ ERROR_MESSAGE(("Received jdwpPacket with flags != 0x%d (actual=0x%x) when a jdwpCmdPacket was expected.",
+ JDWPTRANSPORT_FLAGS_NONE, packet.type.cmd.flags));
+ shouldListen = JNI_FALSE;
+ notifyTransportError();
} else {
cmd = &packet.type.cmd;
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/Jlink.java Wed Oct 19 08:05:48 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink;
-
-import java.lang.reflect.Layer;
-import java.nio.ByteOrder;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import jdk.tools.jlink.internal.ExecutableImage;
-import jdk.tools.jlink.internal.JlinkTask;
-import jdk.tools.jlink.plugin.Plugin;
-import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.builder.ImageBuilder;
-import jdk.tools.jlink.internal.PluginRepository;
-
-/**
- * API to call jlink.
- */
-public final class Jlink {
-
- /**
- * Create a plugin.
- *
- * @param name Plugin name
- * @param configuration Plugin configuration.
- * @param pluginsLayer Plugins Layer. null means boot layer.
- * @return A new plugin or null if plugin is unknown.
- */
- public static Plugin newPlugin(String name,
- Map<String, String> configuration, Layer pluginsLayer) {
- Objects.requireNonNull(name);
- Objects.requireNonNull(configuration);
- pluginsLayer = pluginsLayer == null ? Layer.boot() : pluginsLayer;
- return PluginRepository.newPlugin(configuration, name, pluginsLayer);
- }
-
- /**
- * A complete plugin configuration. Instances of this class are used to
- * configure jlink.
- */
- public static final class PluginsConfiguration {
-
- private final List<Plugin> plugins;
- private final ImageBuilder imageBuilder;
- private final String lastSorterPluginName;
-
- /**
- * Empty plugins configuration.
- */
- public PluginsConfiguration() {
- this(Collections.emptyList());
- }
-
- /**
- * Plugins configuration.
- *
- * @param plugins List of plugins.
- */
- public PluginsConfiguration(List<Plugin> plugins) {
- this(plugins, null, null);
- }
-
- /**
- * Plugins configuration with a last sorter and an ImageBuilder. No
- * sorting can occur after the last sorter plugin. The ImageBuilder is
- * in charge to layout the image content on disk.
- *
- * @param plugins List of transformer plugins.
- * @param imageBuilder Image builder.
- * @param lastSorterPluginName Name of last sorter plugin, no sorting
- * can occur after it.
- */
- public PluginsConfiguration(List<Plugin> plugins,
- ImageBuilder imageBuilder, String lastSorterPluginName) {
- this.plugins = plugins == null ? Collections.emptyList()
- : plugins;
- this.imageBuilder = imageBuilder;
- this.lastSorterPluginName = lastSorterPluginName;
- }
-
- /**
- * @return the plugins
- */
- public List<Plugin> getPlugins() {
- return plugins;
- }
-
- /**
- * @return the imageBuilder
- */
- public ImageBuilder getImageBuilder() {
- return imageBuilder;
- }
-
- /**
- * @return the lastSorterPluginName
- */
- public String getLastSorterPluginName() {
- return lastSorterPluginName;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("imagebuilder=").append(imageBuilder).append("\n");
- StringBuilder pluginsBuilder = new StringBuilder();
- for (Plugin p : plugins) {
- pluginsBuilder.append(p).append(",");
- }
- builder.append("plugins=").append(pluginsBuilder).append("\n");
- builder.append("lastsorter=").append(lastSorterPluginName).append("\n");
-
- return builder.toString();
- }
- }
-
- /**
- * Jlink configuration. Instances of this class are used to configure jlink.
- */
- public static final class JlinkConfiguration {
-
- private final List<Path> modulepaths;
- private final Path output;
- private final Set<String> modules;
- private final Set<String> limitmods;
-
- private final ByteOrder endian;
-
- /**
- * jlink configuration,
- *
- * @param output Output directory, must not exist.
- * @param modulepaths Modules paths
- * @param modules Root modules to resolve
- * @param limitmods Limit the universe of observable modules
- * @param endian Jimage byte order. Native order by default
- */
- public JlinkConfiguration(Path output,
- List<Path> modulepaths,
- Set<String> modules,
- Set<String> limitmods,
- ByteOrder endian) {
- this.output = output;
- this.modulepaths = modulepaths == null ? Collections.emptyList() : modulepaths;
- this.modules = modules == null ? Collections.emptySet() : modules;
- this.limitmods = limitmods == null ? Collections.emptySet() : limitmods;
- this.endian = endian == null ? ByteOrder.nativeOrder() : endian;
- }
-
- /**
- * jlink configuration,
- *
- * @param output Output directory, must not exist.
- * @param modulepaths Modules paths
- * @param modules Root modules to resolve
- * @param limitmods Limit the universe of observable modules
- */
- public JlinkConfiguration(Path output,
- List<Path> modulepaths,
- Set<String> modules,
- Set<String> limitmods) {
- this(output, modulepaths, modules, limitmods,
- ByteOrder.nativeOrder());
- }
-
- /**
- * @return the modulepaths
- */
- public List<Path> getModulepaths() {
- return modulepaths;
- }
-
- /**
- * @return the byte ordering
- */
- public ByteOrder getByteOrder() {
- return endian;
- }
-
- /**
- * @return the output
- */
- public Path getOutput() {
- return output;
- }
-
- /**
- * @return the modules
- */
- public Set<String> getModules() {
- return modules;
- }
-
- /**
- * @return the limitmods
- */
- public Set<String> getLimitmods() {
- return limitmods;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
-
- builder.append("output=").append(output).append("\n");
- StringBuilder pathsBuilder = new StringBuilder();
- for (Path p : modulepaths) {
- pathsBuilder.append(p).append(",");
- }
- builder.append("modulepaths=").append(pathsBuilder).append("\n");
-
- StringBuilder modsBuilder = new StringBuilder();
- for (String p : modules) {
- modsBuilder.append(p).append(",");
- }
- builder.append("modules=").append(modsBuilder).append("\n");
-
- StringBuilder limitsBuilder = new StringBuilder();
- for (String p : limitmods) {
- limitsBuilder.append(p).append(",");
- }
- builder.append("limitmodules=").append(limitsBuilder).append("\n");
- builder.append("endian=").append(endian).append("\n");
- return builder.toString();
- }
- }
-
- /**
- * Jlink instance constructor, if a security manager is set, the jlink
- * permission is checked.
- */
- public Jlink() {
- if (System.getSecurityManager() != null) {
- System.getSecurityManager().
- checkPermission(new JlinkPermission("jlink"));
- }
- }
-
- /**
- * Build the image.
- *
- * @param config Jlink config, must not be null.
- * @throws PluginException
- */
- public void build(JlinkConfiguration config) {
- build(config, null);
- }
-
- /**
- * Build the image with a plugin configuration.
- *
- * @param config Jlink config, must not be null.
- * @param pluginsConfig Plugins config, can be null
- * @throws PluginException
- */
- public void build(JlinkConfiguration config, PluginsConfiguration pluginsConfig) {
- Objects.requireNonNull(config);
- try {
- JlinkTask.createImage(config, pluginsConfig);
- } catch (Exception ex) {
- throw new PluginException(ex);
- }
- }
-
- /**
- * Post process the image with a plugin configuration.
- *
- * @param image Existing image.
- * @param plugins Plugins cannot be null
- */
- public void postProcess(ExecutableImage image, List<Plugin> plugins) {
- Objects.requireNonNull(image);
- Objects.requireNonNull(plugins);
- try {
- JlinkTask.postProcessImage(image, plugins);
- } catch (Exception ex) {
- throw new PluginException(ex);
- }
- }
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/JlinkPermission.java Wed Oct 19 08:05:48 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink;
-
-import java.security.BasicPermission;
-
-/**
- * The permission required to use jlink API. The permission target_name is
- * "jlink". e.g.: permission jdk.tools.jlink.plugins.JlinkPermission "jlink";
- *
- */
-public final class JlinkPermission extends BasicPermission {
-
- private static final long serialVersionUID = -3687912306077727801L;
-
- public JlinkPermission(String name) {
- super(name);
- }
-
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Thu Oct 27 08:52:00 2016 -0700
@@ -37,17 +37,17 @@
import java.io.UncheckedIOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import java.io.UncheckedIOException;
import java.io.Writer;
import java.lang.module.ModuleDescriptor;
import java.nio.charset.StandardCharsets;
+import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
-import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
-import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -55,7 +55,8 @@
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
-import java.util.stream.Collectors;
+import static java.util.stream.Collectors.*;
+
import jdk.tools.jlink.internal.BasicImageWriter;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin.SymImageFile;
import jdk.tools.jlink.internal.ExecutableImage;
@@ -171,15 +172,36 @@
Properties release = releaseProperties(files);
Path bin = root.resolve("bin");
- files.entries().forEach(f -> {
- if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
+ // check any duplicated resource files
+ Map<Path, Set<String>> duplicates = new HashMap<>();
+ files.entries()
+ .filter(f -> f.type() != ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ .collect(groupingBy(this::entryToImagePath,
+ mapping(ResourcePoolEntry::moduleName, toSet())))
+ .entrySet()
+ .stream()
+ .filter(e -> e.getValue().size() > 1)
+ .forEach(e -> duplicates.put(e.getKey(), e.getValue()));
+
+ // write non-classes resource files to the image
+ files.entries()
+ .filter(f -> f.type() != ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ .forEach(f -> {
try {
accept(f);
+ } catch (FileAlreadyExistsException e) {
+ // error for duplicated entries
+ Path path = entryToImagePath(f);
+ UncheckedIOException x =
+ new UncheckedIOException(path + " duplicated in " +
+ duplicates.get(path), e);
+ x.addSuppressed(e);
+ throw x;
} catch (IOException ioExp) {
throw new UncheckedIOException(ioExp);
}
- }
- });
+ });
+
files.moduleView().modules().forEach(m -> {
// Only add modules that contain packages
if (!m.packages().isEmpty()) {
@@ -226,7 +248,7 @@
version().
stream().
map(Object::toString).
- collect(Collectors.joining("."));
+ collect(joining("."));
}
private static String quote(String str) {
@@ -344,28 +366,69 @@
}
}
+ /**
+ * Returns the file name of this entry
+ */
+ private String entryToFileName(ResourcePoolEntry entry) {
+ if (entry.type() == ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ throw new IllegalArgumentException("invalid type: " + entry);
+
+ String module = "/" + entry.moduleName() + "/";
+ String filename = entry.path().substring(module.length());
+ // Remove radical native|config|...
+ return filename.substring(filename.indexOf('/') + 1);
+ }
+
+ /**
+ * Returns the path of the given entry to be written in the image
+ */
+ private Path entryToImagePath(ResourcePoolEntry entry) {
+ switch (entry.type()) {
+ case NATIVE_LIB:
+ String filename = entryToFileName(entry);
+ return Paths.get(nativeDir(filename), filename);
+ case NATIVE_CMD:
+ return Paths.get("bin", entryToFileName(entry));
+ case CONFIG:
+ return Paths.get("conf", entryToFileName(entry));
+ case HEADER_FILE:
+ return Paths.get("include", entryToFileName(entry));
+ case MAN_PAGE:
+ return Paths.get("man", entryToFileName(entry));
+ case TOP:
+ return Paths.get(entryToFileName(entry));
+ case OTHER:
+ return Paths.get("other", entryToFileName(entry));
+ default:
+ throw new IllegalArgumentException("invalid type: " + entry);
+ }
+ }
+
private void accept(ResourcePoolEntry file) throws IOException {
- String fullPath = file.path();
- String module = "/" + file.moduleName() + "/";
- String filename = fullPath.substring(module.length());
- // Remove radical native|config|...
- filename = filename.substring(filename.indexOf('/') + 1);
try (InputStream in = file.content()) {
switch (file.type()) {
case NATIVE_LIB:
- writeEntry(in, destFile(nativeDir(filename), filename));
+ Path dest = root.resolve(entryToImagePath(file));
+ writeEntry(in, dest);
break;
case NATIVE_CMD:
- Path path = destFile("bin", filename);
- writeEntry(in, path);
- path.toFile().setExecutable(true);
+ Path p = root.resolve(entryToImagePath(file));
+ writeEntry(in, p);
+ p.toFile().setExecutable(true);
break;
case CONFIG:
- writeEntry(in, destFile("conf", filename));
+ writeEntry(in, root.resolve(entryToImagePath(file)));
+ break;
+ case HEADER_FILE:
+ writeEntry(in, root.resolve(entryToImagePath(file)));
+ break;
+ case MAN_PAGE:
+ writeEntry(in, root.resolve(entryToImagePath(file)));
break;
case TOP:
break;
case OTHER:
+ String filename = entryToFileName(file);
if (file instanceof SymImageFile) {
SymImageFile sym = (SymImageFile) file;
Path target = root.resolve(sym.getTargetPath());
@@ -379,15 +442,11 @@
}
break;
default:
- throw new InternalError("unexpected entry: " + fullPath);
+ throw new InternalError("unexpected entry: " + file.path());
}
}
}
- private Path destFile(String dir, String filename) {
- return root.resolve(dir).resolve(filename);
- }
-
private void writeEntry(InputStream in, Path dstFile) throws IOException {
Objects.requireNonNull(in);
Objects.requireNonNull(dstFile);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Archive.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Archive.java Thu Oct 27 08:52:00 2016 -0700
@@ -44,9 +44,11 @@
public static enum EntryType {
MODULE_NAME,
CLASS_OR_RESOURCE,
+ CONFIG,
NATIVE_LIB,
NATIVE_CMD,
- CONFIG,
+ HEADER_FILE,
+ MAN_PAGE,
SERVICE;
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ArchiveEntryResourcePoolEntry.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ArchiveEntryResourcePoolEntry.java Thu Oct 27 08:52:00 2016 -0700
@@ -73,6 +73,10 @@
return ResourcePoolEntry.Type.NATIVE_CMD;
case NATIVE_LIB:
return ResourcePoolEntry.Type.NATIVE_LIB;
+ case HEADER_FILE:
+ return ResourcePoolEntry.Type.HEADER_FILE;
+ case MAN_PAGE:
+ return ResourcePoolEntry.Type.MAN_PAGE;
default:
return ResourcePoolEntry.Type.OTHER;
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Thu Oct 27 08:52:00 2016 -0700
@@ -33,7 +33,6 @@
import java.util.Map;
import java.util.Map.Entry;
import jdk.tools.jlink.builder.ImageBuilder;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Plugin.Category;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal;
+
+import java.lang.reflect.Layer;
+import java.nio.ByteOrder;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.builder.ImageBuilder;
+
+/**
+ * API to call jlink.
+ */
+public final class Jlink {
+
+ /**
+ * Create a plugin.
+ *
+ * @param name Plugin name
+ * @param configuration Plugin configuration.
+ * @param pluginsLayer Plugins Layer. null means boot layer.
+ * @return A new plugin or null if plugin is unknown.
+ */
+ public static Plugin newPlugin(String name,
+ Map<String, String> configuration, Layer pluginsLayer) {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(configuration);
+ pluginsLayer = pluginsLayer == null ? Layer.boot() : pluginsLayer;
+ return PluginRepository.newPlugin(configuration, name, pluginsLayer);
+ }
+
+ /**
+ * A complete plugin configuration. Instances of this class are used to
+ * configure jlink.
+ */
+ public static final class PluginsConfiguration {
+
+ private final List<Plugin> plugins;
+ private final ImageBuilder imageBuilder;
+ private final String lastSorterPluginName;
+
+ /**
+ * Empty plugins configuration.
+ */
+ public PluginsConfiguration() {
+ this(Collections.emptyList());
+ }
+
+ /**
+ * Plugins configuration.
+ *
+ * @param plugins List of plugins.
+ */
+ public PluginsConfiguration(List<Plugin> plugins) {
+ this(plugins, null, null);
+ }
+
+ /**
+ * Plugins configuration with a last sorter and an ImageBuilder. No
+ * sorting can occur after the last sorter plugin. The ImageBuilder is
+ * in charge to layout the image content on disk.
+ *
+ * @param plugins List of transformer plugins.
+ * @param imageBuilder Image builder.
+ * @param lastSorterPluginName Name of last sorter plugin, no sorting
+ * can occur after it.
+ */
+ public PluginsConfiguration(List<Plugin> plugins,
+ ImageBuilder imageBuilder, String lastSorterPluginName) {
+ this.plugins = plugins == null ? Collections.emptyList()
+ : plugins;
+ this.imageBuilder = imageBuilder;
+ this.lastSorterPluginName = lastSorterPluginName;
+ }
+
+ /**
+ * @return the plugins
+ */
+ public List<Plugin> getPlugins() {
+ return plugins;
+ }
+
+ /**
+ * @return the imageBuilder
+ */
+ public ImageBuilder getImageBuilder() {
+ return imageBuilder;
+ }
+
+ /**
+ * @return the lastSorterPluginName
+ */
+ public String getLastSorterPluginName() {
+ return lastSorterPluginName;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("imagebuilder=").append(imageBuilder).append("\n");
+ StringBuilder pluginsBuilder = new StringBuilder();
+ for (Plugin p : plugins) {
+ pluginsBuilder.append(p).append(",");
+ }
+ builder.append("plugins=").append(pluginsBuilder).append("\n");
+ builder.append("lastsorter=").append(lastSorterPluginName).append("\n");
+
+ return builder.toString();
+ }
+ }
+
+ /**
+ * Jlink configuration. Instances of this class are used to configure jlink.
+ */
+ public static final class JlinkConfiguration {
+
+ private final List<Path> modulepaths;
+ private final Path output;
+ private final Set<String> modules;
+ private final Set<String> limitmods;
+
+ private final ByteOrder endian;
+
+ /**
+ * jlink configuration,
+ *
+ * @param output Output directory, must not exist.
+ * @param modulepaths Modules paths
+ * @param modules Root modules to resolve
+ * @param limitmods Limit the universe of observable modules
+ * @param endian Jimage byte order. Native order by default
+ */
+ public JlinkConfiguration(Path output,
+ List<Path> modulepaths,
+ Set<String> modules,
+ Set<String> limitmods,
+ ByteOrder endian) {
+ this.output = output;
+ this.modulepaths = modulepaths == null ? Collections.emptyList() : modulepaths;
+ this.modules = modules == null ? Collections.emptySet() : modules;
+ this.limitmods = limitmods == null ? Collections.emptySet() : limitmods;
+ this.endian = endian == null ? ByteOrder.nativeOrder() : endian;
+ }
+
+ /**
+ * jlink configuration,
+ *
+ * @param output Output directory, must not exist.
+ * @param modulepaths Modules paths
+ * @param modules Root modules to resolve
+ * @param limitmods Limit the universe of observable modules
+ */
+ public JlinkConfiguration(Path output,
+ List<Path> modulepaths,
+ Set<String> modules,
+ Set<String> limitmods) {
+ this(output, modulepaths, modules, limitmods,
+ ByteOrder.nativeOrder());
+ }
+
+ /**
+ * @return the modulepaths
+ */
+ public List<Path> getModulepaths() {
+ return modulepaths;
+ }
+
+ /**
+ * @return the byte ordering
+ */
+ public ByteOrder getByteOrder() {
+ return endian;
+ }
+
+ /**
+ * @return the output
+ */
+ public Path getOutput() {
+ return output;
+ }
+
+ /**
+ * @return the modules
+ */
+ public Set<String> getModules() {
+ return modules;
+ }
+
+ /**
+ * @return the limitmods
+ */
+ public Set<String> getLimitmods() {
+ return limitmods;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("output=").append(output).append("\n");
+ StringBuilder pathsBuilder = new StringBuilder();
+ for (Path p : modulepaths) {
+ pathsBuilder.append(p).append(",");
+ }
+ builder.append("modulepaths=").append(pathsBuilder).append("\n");
+
+ StringBuilder modsBuilder = new StringBuilder();
+ for (String p : modules) {
+ modsBuilder.append(p).append(",");
+ }
+ builder.append("modules=").append(modsBuilder).append("\n");
+
+ StringBuilder limitsBuilder = new StringBuilder();
+ for (String p : limitmods) {
+ limitsBuilder.append(p).append(",");
+ }
+ builder.append("limitmodules=").append(limitsBuilder).append("\n");
+ builder.append("endian=").append(endian).append("\n");
+ return builder.toString();
+ }
+ }
+
+ /**
+ * Jlink instance constructor, if a security manager is set, the jlink
+ * permission is checked.
+ */
+ public Jlink() {
+ if (System.getSecurityManager() != null) {
+ System.getSecurityManager().
+ checkPermission(new JlinkPermission("jlink"));
+ }
+ }
+
+ /**
+ * Build the image.
+ *
+ * @param config Jlink config, must not be null.
+ * @throws PluginException
+ */
+ public void build(JlinkConfiguration config) {
+ build(config, null);
+ }
+
+ /**
+ * Build the image with a plugin configuration.
+ *
+ * @param config Jlink config, must not be null.
+ * @param pluginsConfig Plugins config, can be null
+ * @throws PluginException
+ */
+ public void build(JlinkConfiguration config, PluginsConfiguration pluginsConfig) {
+ Objects.requireNonNull(config);
+ try {
+ JlinkTask.createImage(config, pluginsConfig);
+ } catch (Exception ex) {
+ throw new PluginException(ex);
+ }
+ }
+
+ /**
+ * Post process the image with a plugin configuration.
+ *
+ * @param image Existing image.
+ * @param plugins Plugins cannot be null
+ */
+ public void postProcess(ExecutableImage image, List<Plugin> plugins) {
+ Objects.requireNonNull(image);
+ Objects.requireNonNull(plugins);
+ try {
+ JlinkTask.postProcessImage(image, plugins);
+ } catch (Exception ex) {
+ throw new PluginException(ex);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkPermission.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal;
+
+import java.security.BasicPermission;
+
+/**
+ * The permission required to use jlink API. The permission target_name is
+ * "jlink". e.g.: permission jdk.tools.jlink.plugins.JlinkPermission "jlink";
+ *
+ */
+public final class JlinkPermission extends BasicPermission {
+
+ private static final long serialVersionUID = -3687912306077727801L;
+
+ public JlinkPermission(String name) {
+ super(name);
+ }
+
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Thu Oct 27 08:52:00 2016 -0700
@@ -46,11 +46,11 @@
import jdk.internal.module.ConfigurableModuleFinder.Phase;
import jdk.tools.jlink.internal.TaskHelper.BadArgs;
import static jdk.tools.jlink.internal.TaskHelper.JLINK_BUNDLE;
+import jdk.tools.jlink.internal.Jlink.JlinkConfiguration;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.TaskHelper.Option;
import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
import jdk.tools.jlink.internal.ImagePluginStack.ImageProvider;
-import jdk.tools.jlink.Jlink.JlinkConfiguration;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.plugin.Plugin;
@@ -213,8 +213,8 @@
}
return EXIT_OK;
- } catch (UncheckedIOException | PluginException | IllegalArgumentException |
- IOException | ResolutionException e) {
+ } catch (PluginException | IllegalArgumentException |
+ UncheckedIOException |IOException | ResolutionException e) {
log.println(taskHelper.getMessage("error.prefix") + " " + e.getMessage());
if (DEBUG) {
e.printStackTrace(log);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java Thu Oct 27 08:52:00 2016 -0700
@@ -128,12 +128,16 @@
switch (section) {
case CLASSES:
return EntryType.CLASS_OR_RESOURCE;
+ case CONFIG:
+ return EntryType.CONFIG;
case NATIVE_LIBS:
return EntryType.NATIVE_LIB;
case NATIVE_CMDS:
return EntryType.NATIVE_CMD;
- case CONFIG:
- return EntryType.CONFIG;
+ case HEADER_FILES:
+ return EntryType.HEADER_FILE;
+ case MAN_PAGES:
+ return EntryType.MAN_PAGE;
default:
throw new InternalError("unexpected entry: " + section);
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java Thu Oct 27 08:52:00 2016 -0700
@@ -30,9 +30,9 @@
public class Main {
public static void main(String... args) throws Exception {
- JlinkTask t = new JlinkTask();
- int rc = t.run(args);
- System.exit(rc);
+ System.exit(run(new PrintWriter(System.out, true),
+ new PrintWriter(System.err, true),
+ args));
}
/**
@@ -44,6 +44,11 @@
* @return an exit code. 0 means success, non-zero means an error occurred.
*/
public static int run(PrintWriter out, PrintWriter err, String... args) {
+ if (System.getSecurityManager() != null) {
+ System.getSecurityManager().
+ checkPermission(new JlinkPermission("jlink"));
+ }
+
JlinkTask t = new JlinkTask();
t.setLog(out, err);
return t.run(args);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Thu Oct 27 08:52:00 2016 -0700
@@ -49,13 +49,14 @@
import jdk.internal.module.ConfigurableModuleFinder;
import jdk.internal.module.ConfigurableModuleFinder.Phase;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
+import jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
+import jdk.tools.jlink.internal.plugins.ExcludeJmodSectionPlugin;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Plugin.Category;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.plugins.PluginsResourceBundle;
import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
@@ -323,6 +324,20 @@
addArgumentMap(plugin);
}, "-G");
mainOptions.add(plugOption);
+ } else if (plugin instanceof ExcludeJmodSectionPlugin) {
+ plugOption = new PlugOption(false, (task, opt, arg) -> {
+ Map<String, String> m = addArgumentMap(plugin);
+ m.put(ExcludeJmodSectionPlugin.NAME,
+ ExcludeJmodSectionPlugin.MAN_PAGES);
+ }, "--no-man-pages");
+ mainOptions.add(plugOption);
+
+ plugOption = new PlugOption(false, (task, opt, arg) -> {
+ Map<String, String> m = addArgumentMap(plugin);
+ m.put(ExcludeJmodSectionPlugin.NAME,
+ ExcludeJmodSectionPlugin.INCLUDE_HEADER_FILES);
+ }, "--no-header-files");
+ mainOptions.add(plugOption);
}
}
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java Thu Oct 27 08:52:00 2016 -0700
@@ -26,8 +26,8 @@
package jdk.tools.jlink.internal.packager;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.builder.DefaultImageBuilder;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.internal.JlinkTask;
import jdk.tools.jlink.plugin.Plugin;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeJmodSectionPlugin.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal.plugins;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry.Type;
+
+/**
+ *
+ * A plugin to exclude a JMOD section such as man pages or header files
+ */
+public final class ExcludeJmodSectionPlugin implements Plugin {
+
+ public static final String NAME = "exclude-jmod-section";
+ public static final String MAN_PAGES = "man";
+ public static final String INCLUDE_HEADER_FILES = "headers";
+
+ private final Set<Type> filters = new HashSet<>();
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public void configure(Map<String, String> config) {
+ String arg = config.get(NAME);
+ if (arg.isEmpty()) {
+ throw new PluginException("Section name must be specified");
+ }
+
+ switch (arg) {
+ case MAN_PAGES:
+ filters.add(Type.MAN_PAGE);
+ break;
+ case INCLUDE_HEADER_FILES:
+ filters.add(Type.HEADER_FILE);
+ break;
+ default:
+ throw new PluginException("Invalid section name: " + arg);
+ }
+ }
+
+ @Override
+ public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
+ in.transformAndCopy(entry -> {
+ // filter entries whose type corresponds to the specified JMOD section
+ if (filters.contains(entry.type())) {
+ entry = null;
+ }
+ return entry;
+ }, out);
+ return out.build();
+ }
+
+ @Override
+ public Category getType() {
+ return Category.FILTER;
+ }
+
+ @Override
+ public String getDescription() {
+ return PluginsResourceBundle.getDescription(NAME);
+ }
+
+ @Override
+ public boolean hasArguments() {
+ return true;
+ }
+
+ @Override
+ public String getArgumentsDescription() {
+ return PluginsResourceBundle.getArgument(NAME);
+ }
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java Thu Oct 27 08:52:00 2016 -0700
@@ -24,13 +24,12 @@
*/
package jdk.tools.jlink.plugin;
-import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
-import java.nio.file.Files;
import java.nio.file.Path;
+
import jdk.tools.jlink.internal.ResourcePoolEntryFactory;
/**
@@ -64,6 +63,8 @@
CONFIG,
NATIVE_CMD,
NATIVE_LIB,
+ HEADER_FILE,
+ MAN_PAGE,
TOP,
OTHER
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Thu Oct 27 08:52:00 2016 -0700
@@ -68,6 +68,12 @@
exclude-resources.description=\
Specify resources to exclude. e.g.: **.jcov,glob:**/META-INF/**
+exclude-jmod-section.argument=<section-name>\n\
+where <section-name> is \"man\" or \"headers".
+
+exclude-jmod-section.description=\
+Specify a JMOD section to exclude
+
generate-jli-classes.argument=<none|@filename>
generate-jli-classes.description=\
@@ -145,6 +151,12 @@
plugin.opt.G=\
\ -G, --strip-debug Strip debug information
+plugin.opt.no-man-pages=\
+\ --no-man-pages Exclude man pages
+
+plugin.opt.no-header-files=\
+\ --no-header-files Exclude include header files
+
main.plugin.name=\
\Plugin Name
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu Oct 27 08:52:00 2016 -0700
@@ -165,6 +165,8 @@
List<Path> cmds;
List<Path> configs;
List<Path> libs;
+ List<Path> headerFiles;
+ List<Path> manPages;
ModuleFinder moduleFinder;
Version moduleVersion;
String mainClass;
@@ -346,6 +348,9 @@
final List<Path> libs = options.libs;
final List<Path> configs = options.configs;
final List<Path> classpath = options.classpath;
+ final List<Path> headerFiles = options.headerFiles;
+ final List<Path> manPages = options.manPages;
+
final Version moduleVersion = options.moduleVersion;
final String mainClass = options.mainClass;
final String osName = options.osName;
@@ -369,6 +374,9 @@
processSection(out, Section.NATIVE_CMDS, cmds);
processSection(out, Section.NATIVE_LIBS, libs);
processSection(out, Section.CONFIG, configs);
+ processSection(out, Section.HEADER_FILES, headerFiles);
+ processSection(out, Section.MAN_PAGES, manPages);
+
}
/**
@@ -596,7 +604,7 @@
return "";
}
- void processClasses(JmodOutputStream zos, List<Path> classpaths)
+ void processClasses(JmodOutputStream out, List<Path> classpaths)
throws IOException
{
if (classpaths == null)
@@ -604,24 +612,24 @@
for (Path p : classpaths) {
if (Files.isDirectory(p)) {
- processSection(zos, Section.CLASSES, p);
+ processSection(out, Section.CLASSES, p);
} else if (Files.isRegularFile(p) && p.toString().endsWith(".jar")) {
try (JarFile jf = new JarFile(p.toFile())) {
- JarEntryConsumer jec = new JarEntryConsumer(zos, jf);
+ JarEntryConsumer jec = new JarEntryConsumer(out, jf);
jf.stream().filter(jec).forEach(jec);
}
}
}
}
- void processSection(JmodOutputStream zos, Section section, List<Path> paths)
+ void processSection(JmodOutputStream out, Section section, List<Path> paths)
throws IOException
{
if (paths == null)
return;
for (Path p : paths)
- processSection(zos, section, p);
+ processSection(out, section, p);
}
void processSection(JmodOutputStream out, Section section, Path top)
@@ -1195,6 +1203,12 @@
= parser.acceptsAll(Set.of("h", "help"), getMessage("main.opt.help"))
.forHelp();
+ OptionSpec<Path> headerFiles
+ = parser.accepts("header-files", getMessage("main.opt.header-files"))
+ .withRequiredArg()
+ .withValuesSeparatedBy(File.pathSeparatorChar)
+ .withValuesConvertedBy(DirPathConverter.INSTANCE);
+
OptionSpec<Path> libs
= parser.accepts("libs", getMessage("main.opt.libs"))
.withRequiredArg()
@@ -1206,6 +1220,12 @@
.withRequiredArg()
.describedAs(getMessage("main.opt.main-class.arg"));
+ OptionSpec<Path> manPages
+ = parser.accepts("man-pages", getMessage("main.opt.man-pages"))
+ .withRequiredArg()
+ .withValuesSeparatedBy(File.pathSeparatorChar)
+ .withValuesConvertedBy(DirPathConverter.INSTANCE);
+
OptionSpec<Path> modulePath
= parser.acceptsAll(Set.of("p", "module-path"),
getMessage("main.opt.module-path"))
@@ -1272,6 +1292,10 @@
options.excludes = opts.valuesOf(excludes);
if (opts.has(libs))
options.libs = opts.valuesOf(libs);
+ if (opts.has(headerFiles))
+ options.headerFiles = opts.valuesOf(headerFiles);
+ if (opts.has(manPages))
+ options.manPages = opts.valuesOf(manPages);
if (opts.has(modulePath)) {
Path[] dirs = opts.valuesOf(modulePath).toArray(new Path[0]);
options.moduleFinder = ModuleFinder.of(dirs);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Thu Oct 27 08:52:00 2016 -0700
@@ -54,9 +54,11 @@
main.opt.exclude=Exclude files matching the supplied comma separated pattern\
\ list, each element using one the following forms: <glob-pattern>,\
\ glob:<glob-pattern> or regex:<regex-pattern>
+main.opt.header-files=Location of header files
main.opt.module-version= Module version
main.opt.main-class=Main class
main.opt.main-class.arg=class-name
+main.opt.man-pages=Location of man pages
main.opt.os-name=Operating system name
main.opt.os-name.arg=os-name
main.opt.os-arch=Operating system architecture
--- a/jdk/src/jdk.jlink/share/classes/module-info.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/module-info.java Thu Oct 27 08:52:00 2016 -0700
@@ -38,6 +38,7 @@
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.StripDebugPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludePlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
+ provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludeJmodSectionPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.StripNativeCommandsPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.OrderResourcesPlugin;
--- a/jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -174,7 +174,10 @@
const char* utf8String() {
assert(tagMatches(CONSTANT_Utf8));
- assert(value.b.len == strlen((const char*)value.b.ptr));
+ if (value.b.len != strlen((const char*)value.b.ptr)) {
+ unpack_abort("bad utf8 encoding");
+ // and fall through
+ }
return (const char*)value.b.ptr;
}
@@ -1319,10 +1322,10 @@
CHECK;
int nc = 0;
- for ( const char* ncp = form.utf8String() ; *ncp; ncp++) {
- if (*ncp == 'L') nc++;
+ for (int j = 0; j < (int)form.value.b.len; j++) {
+ int c = form.value.b.ptr[j];
+ if (c == 'L') nc++;
}
-
ncTotal += nc;
e.refs = U_NEW(entry*, cpMap[i].nrefs = 1 + nc);
CHECK;
@@ -2830,6 +2833,7 @@
}
assert(!b.le_bci || prevBCI == (int)to_bci(prevBII));
+ CHECK;
switch (b.le_len) {
case 0: break;
case 1: putu1(x); break;
@@ -4026,6 +4030,10 @@
uint len = bcimap.length();
uint* map = (uint*) bcimap.base();
assert(len > 0); // must be initialized before using to_bci
+ if (len == 0) {
+ abort("bad bcimap");
+ return 0;
+ }
if (bii < len)
return map[bii];
// Else it's a fractional or out-of-range BCI.
@@ -4048,6 +4056,7 @@
break;
case 8: // (8) [PH]
putu2(to_bci(code_StackMapTable_P.getInt()));
+ CHECK;
break;
}
}
@@ -4095,6 +4104,7 @@
CHECK;
for (int curIP = 0; ; curIP++) {
+ CHECK;
int curPC = (int)(wpoffset() - codeBase);
bcimap.add(curPC);
ensure_put_space(10); // covers most instrs w/o further bounds check
@@ -4336,6 +4346,7 @@
int curIP = code_fixup_source.get(i);
int destIP = curIP + bc_label.getInt();
int span = to_bci(destIP) - to_bci(curIP);
+ CHECK;
switch (type) {
case 2: putu2_at(bp, (ushort)span); break;
case 4: putu4_at(bp, span); break;
@@ -4532,11 +4543,13 @@
if (tag <= 127) {
// (64-127) [(2)]
if (tag >= 64) put_stackmap_type();
+ CHECK_0;
} else if (tag <= 251) {
// (247) [(1)(2)]
// (248-251) [(1)]
if (tag >= 247) putu2(code_StackMapTable_offset.getInt());
if (tag == 247) put_stackmap_type();
+ CHECK_0;
} else if (tag <= 254) {
// (252) [(1)(2)]
// (253) [(1)(2)(2)]
@@ -4563,6 +4576,7 @@
putu2(count = code_LineNumberTable_N.getInt());
for (j = 0; j < count; j++) {
putu2(to_bci(code_LineNumberTable_bci_P.getInt()));
+ CHECK_0;
putu2(code_LineNumberTable_line.getInt());
}
break;
@@ -4573,9 +4587,11 @@
for (j = 0; j < count; j++) {
int bii = code_LocalVariableTable_bci_P.getInt();
int bci = to_bci(bii);
+ CHECK_0;
putu2(bci);
bii += code_LocalVariableTable_span_O.getInt();
putu2(to_bci(bii) - bci);
+ CHECK_0;
putref(code_LocalVariableTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTable_type_RS.getRefN());
@@ -4590,9 +4606,11 @@
for (j = 0; j < count; j++) {
int bii = code_LocalVariableTypeTable_bci_P.getInt();
int bci = to_bci(bii);
+ CHECK_0;
putu2(bci);
bii += code_LocalVariableTypeTable_span_O.getInt();
putu2(to_bci(bii) - bci);
+ CHECK_0;
putref(code_LocalVariableTypeTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTypeTable_type_RS.getRefN());
@@ -5036,6 +5054,7 @@
entry* e = file_name.getRef();
CHECK_0;
cur_file.name = e->utf8String();
+ CHECK_0;
bool haveLongSize = (testBit(archive_options, AO_HAVE_FILE_SIZE_HI));
cur_file.size = file_size_hi.getLong(file_size_lo, haveLongSize);
if (testBit(archive_options, AO_HAVE_FILE_MODTIME))
--- a/jdk/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java Thu Oct 27 08:52:00 2016 -0700
@@ -25,24 +25,34 @@
package sun.reflect;
+import java.io.OptionalDataException;
+import java.lang.invoke.MethodHandle;
import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
+/**
+ * ReflectionFactory supports custom serialization.
+ * Its methods support the creation of uninitialized objects, invoking serialization
+ * private methods for readObject, writeObject, readResolve, and writeReplace.
+ * <p>
+ * ReflectionFactory access is restricted, if a security manager is active,
+ * unless the permission {@code RuntimePermission("reflectionFactoryAccess")}
+ * is granted.
+ */
public class ReflectionFactory {
private static final ReflectionFactory soleInstance = new ReflectionFactory();
- private final jdk.internal.reflect.ReflectionFactory delegate;
-
- private ReflectionFactory() {
- delegate = AccessController.doPrivileged(
+ private static final jdk.internal.reflect.ReflectionFactory delegate = AccessController.doPrivileged(
new PrivilegedAction<jdk.internal.reflect.ReflectionFactory>() {
public jdk.internal.reflect.ReflectionFactory run() {
return jdk.internal.reflect.ReflectionFactory.getReflectionFactory();
}
- });
- }
+ });
+
+ private ReflectionFactory() {}
private static final Permission REFLECTION_FACTORY_ACCESS_PERM
= new RuntimePermission("reflectionFactoryAccess");
@@ -53,7 +63,7 @@
*
* <p> First, if there is a security manager, its {@code checkPermission}
* method is called with a {@link java.lang.RuntimePermission} with target
- * {@code "reflectionFactoryAccess"}. This may result in a securit
+ * {@code "reflectionFactoryAccess"}. This may result in a security
* exception.
*
* <p> The returned {@code ReflectionFactory} object should be carefully
@@ -61,6 +71,7 @@
* data and invoke private methods, as well as to load unverified bytecodes.
* It must never be passed to untrusted code.
*
+ * @return the ReflectionFactory
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method doesn't allow access to
* the RuntimePermission "reflectionFactoryAccess".
@@ -73,11 +84,129 @@
return soleInstance;
}
- public Constructor<?> newConstructorForSerialization(Class<?> classToInstantiate,
- Constructor<?> constructorToCall)
+ /**
+ * Returns an accessible no-arg constructor for a class.
+ * The no-arg constructor is found searching the class and its supertypes.
+ *
+ * @param cl the class to instantiate
+ * @return a no-arg constructor for the class or {@code null} if
+ * the class or supertypes do not have a suitable no-arg constructor
+ */
+ public final Constructor<?> newConstructorForSerialization(Class<?> cl)
{
- return delegate.newConstructorForSerialization(classToInstantiate,
- constructorToCall);
+ return delegate.newConstructorForSerialization(cl);
+ }
+
+ /**
+ * Returns an accessible no-arg constructor for an externalizable class to be
+ * initialized using a public no-argument constructor.
+ *
+ * @param cl the class to instantiate
+ * @return A no-arg constructor for the class; returns {@code null} if
+ * the class does not implement {@link java.io.Externalizable}
+ */
+ public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
+ return delegate.newConstructorForExternalization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code readObject} method on
+ * a Serializable class.
+ * The first argument of {@link MethodHandle#invoke} is the serializable
+ * object and the second argument is the {@code ObjectInputStream} passed to
+ * {@code readObject}.
+ *
+ * @param cl a Serializable class
+ * @return a direct MethodHandle for the {@code readObject} method of the class or
+ * {@code null} if the class does not have a {@code readObject} method
+ */
+ public final MethodHandle readObjectForSerialization(Class<?> cl) {
+ return delegate.readObjectForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code readObjectNoData} method on
+ * a Serializable class.
+ * The first argument of {@link MethodHandle#invoke} is the serializable
+ * object and the second argument is the {@code ObjectInputStream} passed to
+ * {@code readObjectNoData}.
+ *
+ * @param cl a Serializable class
+ * @return a direct MethodHandle for the {@code readObjectNoData} method
+ * of the class or {@code null} if the class does not have a
+ * {@code readObjectNoData} method
+ */
+ public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
+ return delegate.readObjectNoDataForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code writeObject} method on
+ * a Serializable class.
+ * The first argument of {@link MethodHandle#invoke} is the serializable
+ * object and the second argument is the {@code ObjectOutputStream} passed to
+ * {@code writeObject}.
+ *
+ * @param cl a Serializable class
+ * @return a direct MethodHandle for the {@code writeObject} method of the class or
+ * {@code null} if the class does not have a {@code writeObject} method
+ */
+ public final MethodHandle writeObjectForSerialization(Class<?> cl) {
+ return delegate.writeObjectForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code readResolve} method on
+ * a serializable class.
+ * The single argument of {@link MethodHandle#invoke} is the serializable
+ * object.
+ *
+ * @param cl the Serializable class
+ * @return a direct MethodHandle for the {@code readResolve} method of the class or
+ * {@code null} if the class does not have a {@code readResolve} method
+ */
+ public final MethodHandle readResolveForSerialization(Class<?> cl) {
+ return delegate.readResolveForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code writeReplace} method on
+ * a serializable class.
+ * The single argument of {@link MethodHandle#invoke} is the serializable
+ * object.
+ *
+ * @param cl the Serializable class
+ * @return a direct MethodHandle for the {@code writeReplace} method of the class or
+ * {@code null} if the class does not have a {@code writeReplace} method
+ */
+ public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
+ return delegate.writeReplaceForSerialization(cl);
+ }
+
+ /**
+ * Returns true if the class has a static initializer.
+ * The presence of a static initializer is used to compute the serialVersionUID.
+ * @param cl a serializable class
+ * @return {@code true} if the class has a static initializer,
+ * otherwise {@code false}
+ */
+ public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
+ return delegate.hasStaticInitializerForSerialization(cl);
+ }
+
+ /**
+ * Returns a new OptionalDataException with {@code eof} set to {@code true}
+ * or {@code false}.
+ * @param bool the value of {@code eof} in the created OptionalDataException
+ * @return a new OptionalDataException
+ */
+ public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
+ Constructor<OptionalDataException> cons = delegate.newOptionalDataExceptionForSerialization();
+ try {
+ return cons.newInstance(bool);
+ } catch (InstantiationException|IllegalAccessException|InvocationTargetException ex) {
+ throw new InternalError("unable to create OptionalDataException", ex);
+ }
}
}
--- a/jdk/test/com/oracle/security/ucrypto/TestAES.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/com/oracle/security/ucrypto/TestAES.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,11 @@
/*
* @test
- * @bug 7088989 8014374
+ * @bug 7088989 8014374 8167512
* @summary Ensure the AES ciphers of OracleUcrypto provider works correctly
* @key randomness
+ * @run main TestAES
+ * @run main/othervm/java.security.policy==empty.policy TestAES
*/
import java.io.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/ObjectStreamTest$_Echo_Stub.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.rmi.UnexpectedException;
+
+import javax.rmi.CORBA.Stub;
+import javax.rmi.CORBA.Util;
+
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.ApplicationException;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.RemarshalException;
+import org.omg.CORBA.portable.ServantObject;
+
+
+/**
+ * ObjectStreamTest$Echo Stub class generated by rmic, do not edit.
+ */
+public class ObjectStreamTest$_Echo_Stub extends Stub implements ObjectStreamTest.Echo {
+
+ private static final String[] _type_ids = {
+ "RMI:ObjectStreamTest\\U0024Echo:0000000000000000"
+ };
+
+ private static final long serialVersionUID = 5217577841494640354L;
+
+ public String[] _ids() {
+ return _type_ids.clone();
+ }
+
+ public Object echo(Object arg0) throws java.rmi.RemoteException {
+ if (!Util.isLocal(this)) {
+ try {
+ org.omg.CORBA.portable.InputStream in = null;
+ try {
+ OutputStream out = _request("echo", true);
+ Util.writeAny(out,arg0);
+ in = _invoke(out);
+ return Util.readAny(in);
+ } catch (ApplicationException ex) {
+ in = ex.getInputStream();
+ String $_id = in.read_string();
+ throw new UnexpectedException($_id);
+ } catch (RemarshalException ex) {
+ return echo(arg0);
+ } finally {
+ _releaseReply(in);
+ }
+ } catch (SystemException ex) {
+ throw Util.mapSystemException(ex);
+ }
+ } else {
+ ServantObject so = _servant_preinvoke("echo",ObjectStreamTest.Echo.class);
+ if (so == null) {
+ return echo(arg0);
+ }
+ try {
+ Object arg0Copy = Util.copyObject(arg0,_orb());
+ Object result = ((ObjectStreamTest.Echo)so.servant).echo(arg0Copy);
+ return Util.copyObject(result,_orb());
+ } catch (Throwable ex) {
+ Throwable exCopy = (Throwable)Util.copyObject(ex,_orb());
+ throw Util.wrapException(exCopy);
+ } finally {
+ _servant_postinvoke(so);
+ }
+ }
+ }
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/ObjectStreamTest$_Server_Tie.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.rmi.Remote;
+
+import javax.rmi.CORBA.Tie;
+import javax.rmi.CORBA.Util;
+
+import org.omg.CORBA.BAD_OPERATION;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.InputStream;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.ResponseHandler;
+import org.omg.CORBA.portable.UnknownException;
+import org.omg.CORBA_2_3.portable.ObjectImpl;
+
+
+/**
+ * ObjectStreamClass$Echo server tie class generated by rmic, do not edit.
+ */
+public class ObjectStreamTest$_Server_Tie extends ObjectImpl implements Tie {
+
+ volatile private ObjectStreamTest.Server target = null;
+
+ private static final String[] _type_ids = {
+ "RMI:ObjectStreamTest\\U0024Echo:0000000000000000"
+ };
+
+ public void setTarget(Remote target) {
+ this.target = (ObjectStreamTest.Server) target;
+ }
+
+ public Remote getTarget() {
+ return target;
+ }
+
+ public org.omg.CORBA.Object thisObject() {
+ return this;
+ }
+
+ public void deactivate() {
+ _orb().disconnect(this);
+ _set_delegate(null);
+ target = null;
+ }
+
+ public ORB orb() {
+ return _orb();
+ }
+
+ public void orb(ORB orb) {
+ orb.connect(this);
+ }
+
+ public String[] _ids() {
+ return _type_ids.clone();
+ }
+
+ public OutputStream _invoke(String method, InputStream _in, ResponseHandler reply) throws SystemException {
+ try {
+ ObjectStreamTest.Server target = this.target;
+ if (target == null) {
+ throw new java.io.IOException();
+ }
+ org.omg.CORBA_2_3.portable.InputStream in =
+ (org.omg.CORBA_2_3.portable.InputStream) _in;
+ if (method.equals("echo")) {
+ Object arg0 = Util.readAny(in);
+ Object result = target.echo(arg0);
+ OutputStream out = reply.createReply();
+ Util.writeAny(out,result);
+ return out;
+ }
+ throw new BAD_OPERATION();
+ } catch (SystemException ex) {
+ throw ex;
+ } catch (Throwable ex) {
+ throw new UnknownException(ex);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/ObjectStreamTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Objects;
+import java.util.PropertyPermission;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+
+import javax.naming.CommunicationException;
+import javax.naming.InitialContext;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.rmi.CORBA.Util;
+import javax.rmi.PortableRemoteObject;
+
+import org.omg.CORBA_2_3.ORB;
+import org.omg.CORBA_2_3.portable.OutputStream;
+import org.omg.CORBA_2_3.portable.InputStream;
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.JDKToolLauncher;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import org.testng.TestNG;
+
+/*
+ * @test
+ * @library /test/lib
+ * @build jdk.test.lib.*
+ * @compile ObjectStreamTest.java ObjectStreamTest$_Echo_Stub.java ObjectStreamTest$_Server_Tie.java
+ * @modules java.corba/com.sun.corba.se.impl.io java.base/java.io java.corba/com.sun.corba.se.impl.activation
+ * @summary Tests of ReflectionFactory use in IIOP Serialization
+ * @run testng/othervm
+ * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ * -Djava.naming.provider.url=iiop://localhost:1050 ObjectStreamTest
+ * @run testng/othervm/policy=security.policy
+ * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ * -Djava.naming.provider.url=iiop://localhost:1050 ObjectStreamTest
+ */
+
+@Test
+public class ObjectStreamTest {
+
+ enum Colors {RED, GREEN, YELLOW}
+
+ static Set<Colors> colorSet = new HashSet<>();
+
+ static {
+ colorSet.add(Colors.RED);
+ colorSet.add(Colors.GREEN);
+ }
+
+ /**
+ * The process spawned to run orbd.
+ */
+ static Process orbdProcess;
+ static Thread orbThread;
+
+ @DataProvider(name = "Objects")
+ static Object[][] patterns() {
+ BigInteger bigInteger = new BigInteger("8943892002309239");
+ InetAddress inetAddr;
+ try {
+ inetAddr = java.net.InetAddress.getByAddress(new byte[]{127, 0, 0, 1});
+ } catch (UnknownHostException ignored) {
+ inetAddr = null;
+ // ignored
+ }
+ HashMap<String, Object> hashMap = new HashMap<>();
+ hashMap.put("BigInteger", bigInteger);
+ hashMap.put("InetAddress", inetAddr);
+ hashMap.put("String", "bString");
+ Object[][] patterns = new Object[][]{
+ {"aString"},
+ {Integer.valueOf(5)},
+ {new SimpleObject(4, 4.0f)},
+ {Arrays.asList("a", "b", "c")},
+ {new String[]{"x", "y", "z"}},
+ {new ArrayList<Object>(1)}, // uses readObject/writeObject
+ {new StringBuffer("abc")}, // Has serialPersistentFields
+ {new StringBuilder("abc")},
+ {Colors.RED},
+ {inetAddr},
+ {LocalTime.MIDNIGHT}, // uses writeReplace/readResolve
+ {new LongAdder()}, // uses writeReplace/readResolve
+ {EnumSet.allOf(Colors.class)}, // used writeReplace/readResolve
+ {bigInteger},
+ {new BigDecimal(bigInteger)},
+ {hashMap},
+ {new PropertyPermission("abc", "read")}, // has serialPersistentFields
+ };
+ return patterns;
+ }
+
+
+ /**
+ * Check ObjectStreamClass facts match between core serialization and CORBA.
+ *
+ * @param value
+ */
+ @Test(dataProvider = "Objects")
+ static void factCheck(Serializable value) {
+ Class<?> clazz = value.getClass();
+ java.io.ObjectStreamClass sOSC = java.io.ObjectStreamClass.lookup(clazz);
+ java.io.ObjectStreamField[] sFields = sOSC.getFields();
+ com.sun.corba.se.impl.io.ObjectStreamClass cOSC = corbaLookup(clazz);
+ com.sun.corba.se.impl.io.ObjectStreamField[] cFields = cOSC.getFields();
+
+ Assert.assertEquals(sFields.length, cFields.length, "Different number of fields");
+ for (int i = 0; i < sFields.length; i++) {
+ Assert.assertEquals(sFields[i].getName(), cFields[i].getName(), "different field names " + cFields[i].getName());
+ Assert.assertEquals(sFields[i].getType(), cFields[i].getType(), "different field types " + cFields[i].getName());
+ Assert.assertEquals(sFields[i].getTypeString(), cFields[i].getTypeString(), "different field typestrings " + cFields[i].getName());
+ }
+
+ Assert.assertEquals(baseMethod("hasReadObjectMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasReadObject", cOSC, (Class<?>[]) null), "hasReadObject: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("hasWriteObjectMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasWriteObject", cOSC, (Class<?>[]) null), "hasWriteObject: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("hasWriteReplaceMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasWriteReplaceMethod", cOSC, (Class<?>[]) null), "hasWriteReplace: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("hasReadResolveMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasReadResolveMethod", cOSC, (Class<?>[]) null), "hasReadResolve: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("getSerialVersionUID", sOSC, (Class<?>[]) null),
+ corbaMethod("getSerialVersionUID", cOSC, (Class<?>[]) null), "getSerialVersionUID: " + value.getClass());
+
+ }
+
+
+ /**
+ * Test that objects written using Util.writeAny can be serialized
+ * and deserialized using Util.readAny to equivalent objects.
+ */
+ @Test(dataProvider = "Objects", enabled = true, dependsOnMethods = {"factCheck"})
+ static void WriteValueObjectStreamTest01(Serializable value) throws Exception {
+ ORB orb = (ORB) ORB.init(new String[0], null);
+
+ OutputStream out = (OutputStream) orb.create_output_stream();
+ Util.writeAny(out, value);
+
+ InputStream in = (InputStream) out.create_input_stream();
+ Object actual = Util.readAny(in);
+
+ checkEquals(actual, value);
+ }
+
+ /**
+ * Test that objects can be echoed to a server and come back equivalent.
+ */
+ @Test(dataProvider = "Objects", enabled = false, dependsOnMethods = {"factCheck"})
+ static void echoObjects(Serializable value) throws Exception {
+ Context initialNamingContext = Server.init();
+ Echo echo = (Echo) PortableRemoteObject.narrow(
+ initialNamingContext.lookup(Server.serverID), Echo.class);
+ Object actual = echo.echo(value);
+ checkEquals(actual, value);
+ }
+
+ /**
+ * Check if the value and result are equals, with some tests depending on the type.
+ * @param expected the expected value
+ * @param actual the actual value
+ */
+ static void checkEquals(Object actual, Object expected) {
+ Class<?> cl = expected.getClass();
+ Assert.assertEquals(actual.getClass(), cl, "type of value not equal to class of result");
+ try {
+ if (cl.isArray() || !(cl.getDeclaredMethod("equals", cl) == null)) {
+ Assert.assertEquals(actual, expected, "echo'd object not equal");
+ } else {
+ Assert.assertEquals(toString(actual), toString(expected), "toString values not equal");
+ }
+ } catch (NoSuchMethodException ex) {
+ Assert.assertEquals(toString(actual), toString(expected), "toString values not equal");
+ }
+ }
+
+ /**
+ * Convert an object to a String, and correctly for arrays.
+ * @param obj an object
+ * @return the tostring for the object.
+ */
+ static String toString(Object obj) {
+ return obj.getClass().isArray()
+ ? Arrays.toString((Object[]) obj)
+ : Objects.toString(obj);
+ }
+
+ /**
+ * SimpleObject to test round trip.
+ */
+ static class SimpleObject implements Serializable {
+ private static final long serialVersionUID = 5217577841494640354L;
+
+ private int i = 0;
+ private float f = 0.0f;
+
+ SimpleObject(int i, float f) {
+ this.i = i;
+ this.f = f;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ SimpleObject that = (SimpleObject) o;
+
+ if (i != that.i) return false;
+ return Float.compare(that.f, f) == 0;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = i;
+ result = 31 * result + (f != +0.0f ? Float.floatToIntBits(f) : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "SimpleObject{" +
+ "i=" + i +
+ ", f=" + f +
+ '}';
+ }
+ }
+
+
+ /**
+ * Lookup the CORBA ObjectStreamClass instance for a class.
+ * @param clazz the class
+ * @return the CORBA ObjectStreamClass instance for the class
+ */
+ static com.sun.corba.se.impl.io.ObjectStreamClass corbaLookup(Class<?> clazz) {
+ Class<?> oscClass = com.sun.corba.se.impl.io.ObjectStreamClass.class;
+
+ try {
+ Method meth = oscClass.getDeclaredMethod("lookup", Class.class);
+ meth.setAccessible(true);
+ return (com.sun.corba.se.impl.io.ObjectStreamClass) meth.invoke(null, clazz);
+ } catch (NoSuchMethodException noMeth) {
+ throw new RuntimeException("missing method", noMeth);
+ } catch (IllegalAccessException | InvocationTargetException rex) {
+ throw new RuntimeException("invocation failed", rex);
+ }
+ }
+
+ /**
+ * Lookup aand invoke method on a serializable object via the CORBA ObjectStreamClass.
+ * @param methodName method name
+ * @param osc CORBA ObjectStreamClass
+ * @param argClasses method arguments
+ * @return the value returned from invoking the method
+ */
+ static Object corbaMethod(String methodName, com.sun.corba.se.impl.io.ObjectStreamClass osc, Class<?>... argClasses) {
+ Class<?> oscClass = com.sun.corba.se.impl.io.ObjectStreamClass.class;
+
+ try {
+ Method meth = oscClass.getDeclaredMethod(methodName, argClasses);
+ meth.setAccessible(true);
+ return meth.invoke(osc);
+
+ } catch (NoSuchMethodException noMeth) {
+ throw new RuntimeException("missing method" + osc.getName()
+ + "::" + methodName, noMeth);
+ } catch (IllegalAccessException | InvocationTargetException rex) {
+ throw new RuntimeException("invocation failed", rex);
+ }
+ }
+
+
+ /**
+ * Lookup aand invoke method on a serializable object via java.io.ObjectStreamClass.
+ * @param methodName method name
+ * @param osc java.io.ObjectStreamClass
+ * @param argClasses method arguments
+ * @return the value returned from invoking the method
+ */
+ static Object baseMethod(String methodName, java.io.ObjectStreamClass osc, Class<?>... argClasses) {
+ Class<?> oscClass = java.io.ObjectStreamClass.class;
+
+ try {
+ Method meth = oscClass.getDeclaredMethod(methodName, argClasses);
+ meth.setAccessible(true);
+ return meth.invoke(osc);
+
+ } catch (NoSuchMethodException noMeth) {
+ throw new RuntimeException("missing method: " + osc.getName()
+ + "::" + methodName, noMeth);
+ } catch (IllegalAccessException | InvocationTargetException rex) {
+ throw new RuntimeException("invocation failed", rex);
+ }
+ }
+
+ /**
+ * Simple echo interface to check serialization/deserialization.
+ */
+ interface Echo extends Remote {
+ Object echo(Object obj) throws RemoteException;
+ }
+
+ static class Server extends PortableRemoteObject implements Echo {
+
+ public static final String serverID = "ObjectStreamTestServer";
+
+ private static Context initialNamingContext;
+
+ private static Server server;
+
+ public Server() throws RemoteException {
+ super();
+ }
+
+ public Object echo(Object obj) {
+ return obj;
+ }
+
+
+ public static Context init() {
+ if (initialNamingContext == null) {
+ try {
+ startOrbd();
+ Thread.sleep(5000L); // Give it 5 seconds
+ } catch (Exception eex) {
+ throw new RuntimeException("Orbd", eex);
+ }
+ for (int i = 0; i < 1; i++) {
+ try {
+ Thread.sleep(1L);
+ initialNamingContext = new InitialContext();
+ server = new Server();
+ initialNamingContext.rebind(serverID, server);
+ } catch (CommunicationException | InterruptedException cex) {
+ System.out.printf("retry #%d sec: ex: %s%n", i, cex);
+ } catch (NamingException ex) {
+ throw new RuntimeException("can't initialize naming context", ex);
+ } catch (RemoteException rex) {
+ throw new RuntimeException("can't initialize server", rex);
+ }
+ }
+ }
+ if (initialNamingContext == null) {
+ Assert.fail("Can't initialize the Orb, no naming context");
+ }
+ return initialNamingContext;
+ }
+ }
+
+ static void startOrbd() throws Exception {
+ System.out.println("\nStarting orbd with NS port 1050 ");
+ JDKToolLauncher orbdLauncher = JDKToolLauncher.create("orbd")
+ .addToolArg("-ORBInitialHost").addToolArg("localhost")
+ .addToolArg("-ORBInitialPort").addToolArg("1050");
+
+ System.out.println("ObjectStreamTest: Executing: " + Arrays.asList(orbdLauncher.getCommand()));
+ ProcessBuilder pb = new ProcessBuilder(orbdLauncher.getCommand());
+
+ pb.redirectError(ProcessBuilder.Redirect.INHERIT);
+ orbdProcess = pb.start();
+ }
+
+ @AfterSuite
+ static void killOrbd() throws Exception {
+ if (orbdProcess != null) {
+ orbdProcess.destroyForcibly();
+ orbdProcess.waitFor();
+ System.out.printf("destroyed orbd, pid: %d, exitValue: %d%n",
+ orbdProcess.getPid(), orbdProcess.exitValue());
+ }
+ }
+
+
+
+ // Main can be used to run the tests from the command line with only testng.jar.
+ @SuppressWarnings("raw_types")
+ @Test(enabled = false)
+ public static void main(String[] args) {
+ Class<?>[] testclass = {ObjectStreamTest.class};
+ TestNG testng = new TestNG();
+ testng.setTestClasses(testclass);
+ testng.run();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/security.policy Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,15 @@
+// Individual Permissions for ObjectStreamTest
+grant {
+ // Permissions needed to run the test
+ permission java.util.PropertyPermission "*", "read";
+ permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete,execute";
+ permission java.net.SocketPermission "*", "resolve,connect,listen,accept";
+
+ // Permissions to allow ObjectTest to use IIOP ObjectStreamClass
+ permission java.lang.RuntimePermission "accessClassInPackage.com.sun.corba.se.impl.io";
+ permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+ permission java.lang.RuntimePermission "accessDeclaredMembers";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
+ permission java.io.SerializablePermission "enableSubclassImplementation";
+};
--- a/jdk/test/java/io/Serializable/serialFilter/FilterWithSecurityManagerTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/java/io/Serializable/serialFilter/FilterWithSecurityManagerTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -28,6 +28,7 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import org.testng.Assert;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@@ -65,20 +66,21 @@
*/
@Test
public void testGlobalFilter() throws Exception {
- if (ObjectInputFilter.Config.getSerialFilter() == null) {
- return;
- }
- try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
- ObjectInputStream ois = new ObjectInputStream(bais)) {
+ ObjectInputFilter global = ObjectInputFilter.Config.getSerialFilter();
+
+ try {
ObjectInputFilter.Config.setSerialFilter(filter);
assertFalse(setSecurityManager,
"When SecurityManager exists, without "
- + "java.security.SerializablePermission(serialFilter) Exception should be thrown");
- Object o = ois.readObject();
+ + "java.io.SerializablePermission(serialFilter) "
+ + "IllegalStateException should be thrown");
} catch (AccessControlException ex) {
assertTrue(setSecurityManager);
assertTrue(ex.getMessage().contains("java.io.SerializablePermission"));
assertTrue(ex.getMessage().contains("serialFilter"));
+ } catch (IllegalStateException ise) {
+ // ISE should occur only if global filter already set
+ Assert.assertNotNull(global, "Global filter should be non-null");
}
}
--- a/jdk/test/java/io/Serializable/serialFilter/GlobalFilterTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/java/io/Serializable/serialFilter/GlobalFilterTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -126,9 +126,7 @@
ObjectInputFilter.Config.setSerialFilter(filter);
Assert.fail("set only once process-wide filter");
} catch (IllegalStateException ise) {
- if (sm != null) {
- Assert.fail("wrong exception when security manager is set", ise);
- }
+ // Normal, once set can never be re-set even if no security manager
} catch (SecurityException se) {
if (sm == null) {
Assert.fail("wrong exception when security manager is not set", se);
--- a/jdk/test/java/io/Serializable/serialFilter/security.policy Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/java/io/Serializable/serialFilter/security.policy Thu Oct 27 08:52:00 2016 -0700
@@ -1,7 +1,8 @@
-// Individual Permissions to for GlobalFilterTest
+// Individual Permissions to for GlobalFilterTest and FilterWithSecurityManager
grant {
// Specific permission under test
- permission java.security.SerializablePermission "serialFilter";
+ permission java.io.SerializablePermission "serialFilter";
+
// Permissions needed to run the test
permission java.util.PropertyPermission "*", "read";
permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
--- a/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java Thu Oct 27 08:52:00 2016 -0700
@@ -26,6 +26,7 @@
* @bug 8157464
* @summary Basic test for StackWalker.getCallerClass()
* @library src
+ * @modules java.base/jdk.internal.reflect
* @build java.base/java.util.CSM csm/*
* @run main/othervm csm/jdk.test.CallerSensitiveTest
* @run main/othervm csm/jdk.test.CallerSensitiveTest sm
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/AccessControlTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,454 @@
+/*
+ * 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 util.ClassSupplier;
+import util.MemberFactory;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.mapping;
+import static java.util.stream.Collectors.toCollection;
+import static util.MemberFactory.*;
+import static util.MemberFactory.Group.*;
+import static util.ClassSupplier.*;
+
+/**
+ * @test
+ * @summary An exhaustive test of reflective access controls
+ * @bug 6378384
+ * @build a.PublicSuper a.Package b.PublicSub b.Package
+ * util.MemberFactory util.ClassSupplier
+ * @run main AccessControlTest
+ */
+public class AccessControlTest {
+
+ public static void main(String[] args) throws Exception {
+ boolean ok = true;
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PUBLIC_MEMBERS, PROTECTED_STATIC_F_M)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_INSTANCE_F_M,
+ PROTECTED_C)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS, PROTECTED_INSTANCE_F_M, PROTECTED_STATIC_F_M)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_C)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ if (ok) {
+ System.out.println("\nAll cases passed.");
+ } else {
+ throw new RuntimeException("Some cases failed - see log.");
+ }
+ }
+
+ // use this for generating an exhaustive set of test cases on stdout
+ public static class Generate {
+ public static void main(String[] args) {
+ for (ClassSupplier current : ClassSupplier.values()) {
+ for (ClassSupplier member : ClassSupplier.values()) {
+ for (ClassSupplier target : ClassSupplier.values()) {
+ if (member.get().isAssignableFrom(target.get())) {
+ new Test()
+ .current(current).member(member).target(target)
+ .allowed(ALL)
+ .perform(true);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static class Test {
+
+ ClassSupplier currentClassSupplier, memberClassSupplier, targetClassSupplier;
+ EnumSet<MemberFactory> expectAllowedMembers = EnumSet.noneOf(MemberFactory.class);
+ EnumSet<MemberFactory> expectDeniedMembers = EnumSet.noneOf(MemberFactory.class);
+
+ Test current(ClassSupplier current) {
+ currentClassSupplier = current;
+ return this;
+ }
+
+ Test member(ClassSupplier member) {
+ memberClassSupplier = member;
+ return this;
+ }
+
+ Test target(ClassSupplier target) {
+ targetClassSupplier = target;
+ return this;
+ }
+
+ Test allowed(MemberFactory... allowed) {
+ expectAllowedMembers = MemberFactory.asSet(allowed);
+ return this;
+ }
+
+ Test allowed(MemberFactory.Group... allowedGroups) {
+ expectAllowedMembers = MemberFactory.groupsToMembers(
+ MemberFactory.Group.asSet(allowedGroups));
+ return this;
+ }
+
+ Test denied(MemberFactory... denied) {
+ expectDeniedMembers = MemberFactory.asSet(denied);
+ return this;
+ }
+
+ Test denied(MemberFactory.Group... deniedGroups) {
+ expectDeniedMembers = MemberFactory.groupsToMembers(
+ MemberFactory.Group.asSet(deniedGroups));
+ return this;
+ }
+
+ boolean perform() {
+ return perform(false);
+ }
+
+ boolean perform(boolean generateCases) {
+
+ // some validation 1st
+ EnumSet<MemberFactory> intersection = EnumSet.copyOf(expectAllowedMembers);
+ intersection.retainAll(expectDeniedMembers);
+ if (!intersection.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Expected allowed and denied MemberFactories have non-empty intersection: " +
+ intersection);
+ }
+
+ EnumSet<MemberFactory> missing = EnumSet.allOf(MemberFactory.class);
+ missing.removeAll(expectAllowedMembers);
+ missing.removeAll(expectDeniedMembers);
+ if (!missing.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Union of expected allowed and denied MemberFactories is missing elements: " +
+ missing);
+ }
+
+ // retrieve method that will perform reflective access
+ Method checkAccessMethod;
+ try {
+ checkAccessMethod = currentClassSupplier.get().getDeclaredMethod(
+ "checkAccess", AccessibleObject.class, Object.class);
+ // in case of inaccessible currentClass
+ checkAccessMethod.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+
+ // construct a target object (for instance field/method)
+ Object target;
+ Constructor<?> targetConstructor =
+ (Constructor<?>) PUBLIC_CONSTRUCTOR.apply(targetClassSupplier.get());
+ // in case of inaccessible targetClass
+ targetConstructor.setAccessible(true);
+ try {
+ target = targetConstructor.newInstance(
+ new Object[targetConstructor.getParameterCount()]);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+
+ Class<?> memberClass = memberClassSupplier.get();
+
+ Map<Boolean, EnumSet<MemberFactory>> actualMembers = Stream.concat(
+
+ expectAllowedMembers.stream().map(member -> new Trial(member, true)),
+ expectDeniedMembers.stream().map(member -> new Trial(member, false))
+
+ ).map(trial -> {
+
+ // obtain AccessibleObject to be used to perform reflective access
+ AccessibleObject accessibleObject = trial.member.apply(memberClass);
+
+ // only need target 'obj' for instance fields and methods
+ Object obj =
+ (accessibleObject instanceof Field &&
+ !Modifier.isStatic(((Field) accessibleObject).getModifiers())
+ ||
+ accessibleObject instanceof Method &&
+ !Modifier.isStatic(((Method) accessibleObject).getModifiers())
+ )
+ ? target : null;
+
+ // invoke checkAccess method and let it perform the reflective access
+ try {
+ checkAccessMethod.invoke(null, accessibleObject, obj);
+ trial.actualAllowed = true;
+ } catch (IllegalAccessException e) {
+ // should not happen as checkAccessMethod.isAccessible()
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ if (e.getTargetException() instanceof IllegalAccessException) {
+ trial.actualAllowed = false;
+ } else {
+ // any other Exception is a fault in test or infrastructure - fail fast
+ throw new RuntimeException(e.getTargetException());
+ }
+ }
+
+ if (!generateCases) {
+ System.out.printf(
+ "%-26s accessing %26s's %-25s %-43s - expected %s, actual %s: %s\n",
+ currentClassSupplier, memberClassSupplier, trial.member.name(),
+ (obj == null ? "" : "with instance of " + targetClassSupplier),
+ (trial.expectAllowed ? "allowed" : "denied "),
+ (trial.actualAllowed ? "allowed" : "denied "),
+ (trial.expectAllowed == trial.actualAllowed ? "OK" : "FAILURE")
+ );
+ }
+
+ return trial;
+
+ }).collect(
+ groupingBy(
+ Trial::isActualAllowed,
+ mapping(
+ Trial::getMember,
+ toCollection(() -> EnumSet.noneOf(MemberFactory.class))))
+ );
+
+ EnumSet<MemberFactory> actualAllowedMembers =
+ Optional.ofNullable(actualMembers.get(true))
+ .orElse(EnumSet.noneOf(MemberFactory.class));
+ EnumSet<MemberFactory> actualDeniedMembers =
+ Optional.ofNullable(actualMembers.get(false))
+ .orElse(EnumSet.noneOf(MemberFactory.class));
+
+ if (generateCases) {
+ System.out.printf(
+ " ok &= new Test()\n" +
+ " .current(%s)\n" +
+ " .member (%s).target(%s)\n",
+ currentClassSupplier,
+ memberClassSupplier, targetClassSupplier
+ );
+
+ if (!actualAllowedMembers.isEmpty()) {
+ EnumSet<? extends Enum> actualAllowed =
+ MemberFactory.membersToGroupsOrNull(actualAllowedMembers);
+ if (actualAllowed == null)
+ actualAllowed = actualAllowedMembers;
+ System.out.print(
+ chunkBy(3, actualAllowed.stream().map(Enum::name))
+ .map(chunk -> chunk.collect(joining(", ")))
+ .collect(joining(",\n" +
+ " ",
+ " .allowed(",
+ ")\n"))
+ );
+ }
+
+ if (!actualDeniedMembers.isEmpty()) {
+ EnumSet<? extends Enum> actualDenied =
+ MemberFactory.membersToGroupsOrNull(actualDeniedMembers);
+ if (actualDenied == null)
+ actualDenied = actualAllowedMembers;
+ System.out.print(
+ chunkBy(3, actualDenied.stream().map(Enum::name))
+ .map(chunk -> chunk.collect(joining(", ")))
+ .collect(joining(",\n" +
+ " ",
+ " .denied (",
+ ")\n"))
+ );
+ }
+
+ System.out.print(
+ " .perform();\n"
+ );
+ }
+
+ return expectAllowedMembers.equals(actualAllowedMembers) &&
+ expectDeniedMembers.equals(actualDeniedMembers);
+ }
+ }
+
+ private static <T> Stream<Stream<T>> chunkBy(int chunkSize, Stream<T> stream) {
+ Iterator<T> elements = stream.iterator();
+ Stream.Builder<Stream<T>> b1 = Stream.builder();
+ while (elements.hasNext()) {
+ Stream.Builder<T> b2 = Stream.builder();
+ for (int i = 0; i < chunkSize && elements.hasNext(); i++) {
+ b2.accept(elements.next());
+ }
+ b1.accept(b2.build());
+ }
+ return b1.build();
+ }
+
+ private static class Trial {
+ final MemberFactory member;
+ final boolean expectAllowed;
+ boolean actualAllowed;
+
+ Trial(MemberFactory member, boolean expectAllowed) {
+ this.member = member;
+ this.expectAllowed = expectAllowed;
+ }
+
+ MemberFactory getMember() {
+ return member;
+ }
+
+ boolean isActualAllowed() {
+ return actualAllowed;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/a/Package.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+package a;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A package-private class in a.
+ */
+class Package {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private Package(Void _1, Void _2, Void _3) {}
+ Package(Void _1, Void _2) {}
+ protected Package(Void _1) {}
+ public Package() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/a/PublicSuper.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+package a;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A public class in a which is a superclass of public class in b.
+ */
+public class PublicSuper {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private PublicSuper(Void _1, Void _2, Void _3) {}
+ PublicSuper(Void _1, Void _2) {}
+ protected PublicSuper(Void _1) {}
+ public PublicSuper() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/b/Package.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+package b;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A package-private class in b.
+ */
+class Package {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private Package(Void _1, Void _2, Void _3) {}
+ Package(Void _1, Void _2) {}
+ protected Package(Void _1) {}
+ public Package() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/b/PublicSub.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+package b;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A public class in b which is a subclass of public class in a.
+ */
+public class PublicSub extends a.PublicSuper {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private PublicSub(Void _1, Void _2, Void _3) {}
+ PublicSub(Void _1, Void _2) {}
+ protected PublicSub(Void _1) {}
+ public PublicSub() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/util/ClassSupplier.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.util.function.Supplier;
+
+/**
+ * An enumeration of suppliers of test classes.
+ */
+public enum ClassSupplier implements Supplier<Class<?>> {
+ PACKAGE_CLASS_IN_PKG_A("a.Package"),
+ PUBLIC_SUPERCLASS_IN_PKG_A("a.PublicSuper"),
+ PACKAGE_CLASS_IN_PKG_B("b.Package"),
+ PUBLIC_SUBCLASS_IN_PKG_B("b.PublicSub");
+
+ private final String className;
+
+ ClassSupplier(String className) {
+ this.className = className;
+ }
+
+ @Override
+ public Class<?> get() {
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ throw (Error) new NoClassDefFoundError(className).initCause(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/util/MemberFactory.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,220 @@
+/*
+ * 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.
+ */
+package util;
+
+import java.lang.reflect.AccessibleObject;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import static util.MemberFactory.Kind.CONSTRUCTOR;
+import static util.MemberFactory.Kind.FIELD;
+import static util.MemberFactory.Kind.METHOD;
+
+/**
+ * Enumeration of:
+ * <p>
+ * {private, package, protected, public} x {instance, static} x {field, method}
+ * <p>
+ * and:
+ * <p>
+ * {private, package, protected, public} x {constructor},
+ * <p>
+ * with each element acting as a factory of AccessibleObject(s)
+ * declared by given declaringClass(es).
+ */
+public enum MemberFactory implements Function<Class<?>, AccessibleObject> {
+ // instance fields
+ PRIVATE_INSTANCE_FIELD(FIELD, "privateInstance"),
+ PACKAGE_INSTANCE_FIELD(FIELD, "packageInstance"),
+ PROTECTED_INSTANCE_FIELD(FIELD, "protectedInstance"),
+ PUBLIC_INSTANCE_FIELD(FIELD, "publicInstance"),
+ // instance methods
+ PRIVATE_INSTANCE_METHOD(METHOD, "privateInstance"),
+ PACKAGE_INSTANCE_METHOD(METHOD, "packageInstance"),
+ PROTECTED_INSTANCE_METHOD(METHOD, "protectedInstance"),
+ PUBLIC_INSTANCE_METHOD(METHOD, "publicInstance"),
+ // static fields
+ PRIVATE_STATIC_FIELD(FIELD, "privateStatic"),
+ PACKAGE_STATIC_FIELD(FIELD, "packageStatic"),
+ PROTECTED_STATIC_FIELD(FIELD, "protectedStatic"),
+ PUBLIC_STATIC_FIELD(FIELD, "publicStatic"),
+ // static methods
+ PRIVATE_STATIC_METHOD(METHOD, "privateStatic"),
+ PACKAGE_STATIC_METHOD(METHOD, "packageStatic"),
+ PROTECTED_STATIC_METHOD(METHOD, "protectedStatic"),
+ PUBLIC_STATIC_METHOD(METHOD, "publicStatic"),
+ // constructors
+ PRIVATE_CONSTRUCTOR(CONSTRUCTOR, null, Void.class, Void.class, Void.class),
+ PACKAGE_CONSTRUCTOR(CONSTRUCTOR, null, Void.class, Void.class),
+ PROTECTED_CONSTRUCTOR(CONSTRUCTOR, null, Void.class),
+ PUBLIC_CONSTRUCTOR(CONSTRUCTOR, null),;
+
+ final Kind kind;
+ final String name;
+ final Class<?>[] parameterTypes;
+
+ MemberFactory(Kind kind, String name, Class<?>... parameterTypes) {
+ this.kind = kind;
+ this.name = name;
+ this.parameterTypes = parameterTypes;
+ }
+
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass) {
+ return kind.apply(declaringClass, this);
+ }
+
+ public static EnumSet<MemberFactory> asSet(MemberFactory... members) {
+ return members.length == 0 ? EnumSet.noneOf(MemberFactory.class)
+ : EnumSet.copyOf(Arrays.asList(members));
+ }
+
+ /**
+ * @param members the set of MemberFactory(s) to convert to set of
+ * MemberFactory.Group(s).
+ * @return a set of groups that cover all elements of the members set if
+ * such set of groups exists or null if it doesn't.
+ */
+ public static EnumSet<Group> membersToGroupsOrNull(EnumSet<MemberFactory> members) {
+ EnumSet<MemberFactory> mSet = members.clone();
+ EnumSet<Group> gSet = EnumSet.allOf(Group.class);
+ Iterator<Group> gIter = gSet.iterator();
+ while (gIter.hasNext()) {
+ Group g = gIter.next();
+ if (mSet.containsAll(g.members)) {
+ mSet.removeAll(g.members);
+ } else {
+ gIter.remove();
+ }
+ }
+ return mSet.isEmpty() ? gSet : null;
+ }
+
+ /**
+ * @param groups the set of MemberFactory.Group(s) to convert to set of
+ * MemberFactory(s).
+ * @return a set of members as a union of members of all groups.
+ */
+ public static EnumSet<MemberFactory> groupsToMembers(EnumSet<Group> groups) {
+ EnumSet<MemberFactory> mSet = EnumSet.noneOf(MemberFactory.class);
+ for (Group g : groups) {
+ mSet.addAll(g.members);
+ }
+ return mSet;
+ }
+
+ enum Kind implements BiFunction<Class<?>, MemberFactory, AccessibleObject> {
+ FIELD {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredField(factory.name);
+ } catch (NoSuchFieldException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ },
+ METHOD {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredMethod(factory.name, factory.parameterTypes);
+ } catch (NoSuchMethodException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ },
+ CONSTRUCTOR {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredConstructor(factory.parameterTypes);
+ } catch (NoSuchMethodException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ }
+ }
+
+ /**
+ * We define groups of MemberFactory(s) for members that commonly
+ * exhibit same access restrictions in various cases in order to allow
+ * specifying groups instead of individual members in the test cases,
+ * making them less verbose.
+ */
+ public enum Group {
+ // all members
+ ALL(MemberFactory.values()),
+ // all private members
+ PRIVATE_MEMBERS(PRIVATE_INSTANCE_FIELD, PRIVATE_INSTANCE_METHOD,
+ PRIVATE_STATIC_FIELD, PRIVATE_STATIC_METHOD,
+ PRIVATE_CONSTRUCTOR),
+ // all package members
+ PACKAGE_MEMBERS(PACKAGE_INSTANCE_FIELD, PACKAGE_INSTANCE_METHOD,
+ PACKAGE_STATIC_FIELD, PACKAGE_STATIC_METHOD,
+ PACKAGE_CONSTRUCTOR),
+ // all protected members
+ PROTECTED_MEMBERS(PROTECTED_INSTANCE_FIELD, PROTECTED_INSTANCE_METHOD,
+ PROTECTED_STATIC_FIELD, PROTECTED_STATIC_METHOD,
+ PROTECTED_CONSTRUCTOR),
+ // all public members
+ PUBLIC_MEMBERS(PUBLIC_INSTANCE_FIELD, PUBLIC_INSTANCE_METHOD,
+ PUBLIC_STATIC_FIELD, PUBLIC_STATIC_METHOD,
+ PUBLIC_CONSTRUCTOR),
+ // instance field and method pairs
+ PRIVATE_INSTANCE_F_M(PRIVATE_INSTANCE_FIELD, PRIVATE_INSTANCE_METHOD),
+ PACKAGE_INSTANCE_F_M(PACKAGE_INSTANCE_FIELD, PACKAGE_INSTANCE_METHOD),
+ PROTECTED_INSTANCE_F_M(PROTECTED_INSTANCE_FIELD, PROTECTED_INSTANCE_METHOD),
+ PUBLIC_INSTANCE_F_M(PUBLIC_INSTANCE_FIELD, PUBLIC_INSTANCE_METHOD),
+ // static field and method pairs
+ PRIVATE_STATIC_F_M(PRIVATE_STATIC_FIELD, PRIVATE_STATIC_METHOD),
+ PACKAGE_STATIC_F_M(PACKAGE_STATIC_FIELD, PACKAGE_STATIC_METHOD),
+ PROTECTED_STATIC_F_M(PROTECTED_STATIC_FIELD, PROTECTED_STATIC_METHOD),
+ PUBLIC_STATIC_F_M(PUBLIC_STATIC_FIELD, PUBLIC_STATIC_METHOD),
+ // constructor singles
+ PRIVATE_C(PRIVATE_CONSTRUCTOR),
+ PACKAGE_C(PACKAGE_CONSTRUCTOR),
+ PROTECTED_C(PROTECTED_CONSTRUCTOR),
+ PUBLIC_C(PUBLIC_CONSTRUCTOR);
+
+ final EnumSet<MemberFactory> members;
+
+ Group(MemberFactory... members) {
+ this.members = EnumSet.copyOf(Arrays.asList(members));
+ }
+
+ public static EnumSet<Group> asSet(Group... groups) {
+ return groups.length == 0 ? EnumSet.noneOf(Group.class)
+ : EnumSet.copyOf(Arrays.asList(groups));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/server/UnicastRemoteObject/serialFilter/FilterUROTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,194 @@
+/*
+ * 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.InvalidClassException;
+import java.io.ObjectInputFilter;
+import java.io.Serializable;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.UnmarshalException;
+import java.rmi.server.UnicastRemoteObject;
+
+import java.util.Objects;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @run testng/othervm FilterUROTest
+ * @summary Check that objects are exported with ObjectInputFilters via UnicastRemoteObject
+ */
+public class FilterUROTest {
+
+ /**
+ * Data to test serialFilter call counts.
+ * - name
+ * - Object
+ * - expected count of calls to checkInput.
+ *
+ * @return array of test data
+ */
+ @DataProvider(name = "bindData")
+ static Object[][] bindObjects() {
+ Object[][] data = {
+ {"SimpleString", "SimpleString", 0},
+ {"String", new XX("now is the time"), 1},
+ {"String[]", new XX(new String[3]), 3},
+ {"Long[4]", new XX(new Long[4]), 3},
+ {"RejectME", new XX(new RejectME()), -1},
+ };
+ return data;
+ }
+
+ /*
+ * Test exporting an object with a serialFilter using exportObject().
+ * Send some objects and check the number of calls to the serialFilter.
+ */
+ @Test(dataProvider = "bindData")
+ public void useExportObject(String name, Object obj, int expectedFilterCount) throws RemoteException {
+ try {
+ RemoteImpl impl = RemoteImpl.create();
+ Echo client = (Echo) UnicastRemoteObject
+ .exportObject(impl, 0, impl.checker);
+ int count = client.filterCount(obj);
+ System.out.printf("count: %d, obj: %s%n", count, obj);
+ Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
+ } catch (RemoteException rex) {
+ if (expectedFilterCount == -1 &&
+ UnmarshalException.class.equals(rex.getCause().getClass()) &&
+ InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
+ return; // normal expected exception
+ }
+ rex.printStackTrace();
+ Assert.fail("unexpected remote exception", rex);
+ } catch (Exception rex) {
+ Assert.fail("unexpected exception", rex);
+ }
+ }
+
+ /*
+ * Test exporting an object with a serialFilter using exportObject()
+ * with explicit (but null) SocketFactories.
+ * Send some objects and check the number of calls to the serialFilter.
+ */
+ @Test(dataProvider = "bindData")
+ public void useExportObject2(String name, Object obj, int expectedFilterCount) throws RemoteException {
+ try {
+ RemoteImpl impl = RemoteImpl.create();
+ Echo client = (Echo) UnicastRemoteObject
+ .exportObject(impl, 0, null, null, impl.checker);
+ int count = client.filterCount(obj);
+ System.out.printf("count: %d, obj: %s%n", count, obj);
+ Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
+ } catch (RemoteException rex) {
+ if (expectedFilterCount == -1 &&
+ UnmarshalException.class.equals(rex.getCause().getClass()) &&
+ InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
+ return; // normal expected exception
+ }
+ rex.printStackTrace();
+ Assert.fail("unexpected remote exception", rex);
+ } catch (Exception rex) {
+ Assert.fail("unexpected exception", rex);
+ }
+ }
+
+ /**
+ * A simple Serializable holding an object that is passed by value.
+ * It and its contents are checked by the filter.
+ */
+ static class XX implements Serializable {
+ private static final long serialVersionUID = 362498820763181265L;
+
+ final Object obj;
+
+ XX(Object obj) {
+ this.obj = obj;
+ }
+
+ public String toString() {
+ return super.toString() + "//" + Objects.toString(obj);
+ }
+ }
+
+ interface Echo extends Remote {
+ int filterCount(Object obj) throws RemoteException;
+ }
+
+ /**
+ * This remote object just counts the calls to the serialFilter
+ * and returns it. The caller can check the number against
+ * what was expected for the object passed as an argument.
+ * A new RemoteImpl is used for each test so the count starts at zero again.
+ */
+ static class RemoteImpl implements Echo {
+
+ private static final long serialVersionUID = -6999613679881262446L;
+
+ transient Checker checker;
+
+ static RemoteImpl create() throws RemoteException {
+ RemoteImpl impl = new RemoteImpl(new Checker());
+ return impl;
+ }
+
+ private RemoteImpl(Checker checker) throws RemoteException {
+ this.checker = checker;
+ }
+
+ public int filterCount(Object obj) throws RemoteException {
+ return checker.count();
+ }
+
+ }
+
+ /**
+ * A ObjectInputFilter that just counts when it is called.
+ */
+ static class Checker implements ObjectInputFilter {
+ int count;
+
+ @Override
+ public Status checkInput(FilterInfo filterInfo) {
+ if (filterInfo.serialClass() == RejectME.class) {
+ return Status.REJECTED;
+ }
+ count++;
+ return Status.UNDECIDED;
+ }
+
+ public int count() {
+ return count;
+ }
+ }
+
+ /**
+ * A class to be rejected by the filter.
+ */
+ static class RejectME implements Serializable {
+ private static final long serialVersionUID = 2L;
+ }
+}
--- a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -624,7 +624,7 @@
@Test
public void test_chronoFields() {
ChronoLocalDate hdate = HijrahChronology.INSTANCE.date(1434, 6, 28);
- assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), 3);
+ assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), 7);
assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), 7);
assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_MONTH), 4);
assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_YEAR), 25);
@@ -785,4 +785,32 @@
public void test_hijrahToJapanese(HijrahDate hijrah, String japanese) {
assertEquals(JapaneseChronology.INSTANCE.date(hijrah).toString(), japanese);
}
+
+ @DataProvider(name="alignedDayOfWeekInMonthTestDates")
+ Object[][] data_alignedDayOfWeekInMonth() {
+ return new Object[][] {
+ {1437, 9, 1, 1, 1},
+ {1437, 10, 1, 1, 1},
+ {1437, 10, 11, 2, 4},
+ {1437, 10, 29, 5, 1},
+ };
+ }
+
+ //-----------------------------------------------------------------------
+ // Test for aligned-week-of-month calculation based on the day-of-month
+ //-----------------------------------------------------------------------
+ @Test(dataProvider="alignedDayOfWeekInMonthTestDates")
+ public void test_alignedWeekOfMonth(int year, int month, int dom, int wom, int dowm) {
+ HijrahDate date = HijrahChronology.INSTANCE.date(year, month, dom);
+ assertEquals(date.getLong(ChronoField.ALIGNED_WEEK_OF_MONTH), wom);
+ }
+
+ //-----------------------------------------------------------------------
+ // Test for aligned-day-of-week calculation based on the day-of-month
+ //-----------------------------------------------------------------------
+ @Test(dataProvider="alignedDayOfWeekInMonthTestDates")
+ public void test_alignedDayOfWeekInMonth(int year, int month, int dom, int wom, int dowm) {
+ HijrahDate date = HijrahChronology.INSTANCE.date(year, month, dom);
+ assertEquals(date.getLong(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), dowm);
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestNarrowMonthNamesAndDayNames.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+package test.java.time.format;
+
+/*
+ * @test
+ * @bug 8146750
+ * @summary Test Narrow and NarrowStandalone month names are retrieved correctly.
+ */
+import static org.testng.Assert.assertEquals;
+
+import java.time.DayOfWeek;
+import java.time.Month;
+import java.time.format.TextStyle;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class TestNarrowMonthNamesAndDayNames {
+
+ static {
+ System.setProperty("java.locale.providers", "COMPAT");
+ }
+
+ private static final List<Month> MONTHVALUES = Arrays.asList(Month.values());
+ private static final List<DayOfWeek> DAYVALUES = Arrays.asList(DayOfWeek.values());
+ private static final List<TextStyle> TEXTSTYLELIST = Arrays.asList(TextStyle.NARROW,
+ TextStyle.NARROW_STANDALONE);
+ private static final List<Locale> LOCARR = Arrays.asList(Locale.US,
+ Locale.GERMANY,
+ Locale.FRANCE,
+ new Locale("no", "NO"));
+
+ /**
+ * Locale en_US, de_DE, fr_FR, no_NO will have same Narrow and
+ * Narrow_Standalone month Names for COMPAT Provider.
+ */
+ @DataProvider(name = "MonthNarrows")
+ public Object[][] monthNameData() {
+ return new Object[][]{{new String[]{
+ "J",
+ "F",
+ "M",
+ "A",
+ "M",
+ "J",
+ "J",
+ "A",
+ "S",
+ "O",
+ "N",
+ "D"
+ }},};
+ }
+
+ //-----------------------------------------------------------------------
+ // Check Narrow and Narrow_standalone month name values
+ //-----------------------------------------------------------------------
+ @Test(dataProvider = "MonthNarrows")
+ public void compareMonthNarrowValues(String[] monthNarrowExpected) {
+ LOCARR.forEach((loc) -> {
+ TEXTSTYLELIST.forEach((style) -> {
+ MONTHVALUES.forEach((value) -> {
+ String result = value.getDisplayName(style, loc);
+ int index = value.ordinal();
+ assertEquals(result, monthNarrowExpected[index], "Test failed"
+ + " for COMPAT Provider for locale "
+ + loc + " for style " + style.name()
+ + " with Month value " + value.name());
+ });
+ });
+ });
+ }
+
+ /**
+ * Locale en_US, de_DE, fr_FR, no_NO will have different Narrow and
+ * Narrow_Standalone Day Names for COMPAT Provider.
+ */
+ @DataProvider(name = "DayNarrows")
+ public Object[][] dayNameData() {
+ return new Object[][]{
+ {Locale.US, new String[]{"M", "T", "W", "T", "F", "S", "S"}},
+ {Locale.GERMANY, new String[]{"M", "D", "M", "D", "F", "S", "S"}},
+ {Locale.FRANCE, new String[]{"L", "M", "M", "J", "V", "S", "D"}},
+ {new Locale("no", "NO"), new String[]{"M", "T", "O", "T", "F", "L", "S"}},};
+ }
+
+ //-----------------------------------------------------------------------
+ // Check Narrow and Narrow_standalone Day name values
+ //-----------------------------------------------------------------------
+ @Test(dataProvider = "DayNarrows")
+ public void compareDayNarrowValues(Locale locale, String[] dayNarrowExpected) {
+ TEXTSTYLELIST.forEach((style) -> {
+ DAYVALUES.forEach((value) -> {
+ String result = value.getDisplayName(style, locale);
+ int index = value.ordinal();
+ assertEquals(result, dayNarrowExpected[index], "Test failed"
+ + " for COMPAT Provider for locale "
+ + locale + " for style " + style.name()
+ + " with Day value " + value.name());
+ });
+ });
+ }
+}
--- a/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Thu Oct 27 08:52:00 2016 -0700
@@ -88,6 +88,7 @@
${TESTJAVA}${FS}bin${FS}java \
${TESTVMOPTS} \
+ -Djava.security.properties=${TESTSRC}${FS}security.properties \
-classpath "${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar${PS}." \
FailOverTest
result=$?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/crypto/SecretKeyFactory/security.properties Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,6 @@
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+
+jdk.security.provider.preferred=
+jdk.jar.disabledAlgorithms=
+
--- a/jdk/test/javax/net/ssl/templates/SSLTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/javax/net/ssl/templates/SSLTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -94,12 +94,22 @@
/*
* Is the server ready to serve?
*/
- private final CountDownLatch serverCondition = new CountDownLatch(1);
+ private final CountDownLatch serverReadyCondition = new CountDownLatch(1);
/*
* Is the client ready to handshake?
*/
- private final CountDownLatch clientCondition = new CountDownLatch(1);
+ private final CountDownLatch clientReadyCondition = new CountDownLatch(1);
+
+ /*
+ * Is the server done?
+ */
+ private final CountDownLatch serverDoneCondition = new CountDownLatch(1);
+
+ /*
+ * Is the client done?
+ */
+ private final CountDownLatch clientDoneCondition = new CountDownLatch(1);
/*
* Public API.
@@ -162,6 +172,25 @@
return keystore;
}
+ // Try to accept a connection in 30 seconds.
+ public static SSLSocket accept(SSLServerSocket sslServerSocket)
+ throws IOException {
+
+ return accept(sslServerSocket, SERVER_TIMEOUT);
+ }
+
+ public static SSLSocket accept(SSLServerSocket sslServerSocket, int timeout)
+ throws IOException {
+
+ try {
+ sslServerSocket.setSoTimeout(timeout);
+ return (SSLSocket) sslServerSocket.accept();
+ } catch (SocketTimeoutException ste) {
+ sslServerSocket.close();
+ return null;
+ }
+ }
+
public SSLTest setSeparateServerThread(boolean separateServerThread) {
this.separateServerThread = separateServerThread;
return this;
@@ -202,33 +231,61 @@
}
public void signalServerReady() {
- serverCondition.countDown();
+ serverReadyCondition.countDown();
+ }
+
+ public void signalServerDone() {
+ serverDoneCondition.countDown();
}
public boolean waitForClientSignal(long timeout, TimeUnit unit)
throws InterruptedException {
- return clientCondition.await(timeout, unit);
+ return clientReadyCondition.await(timeout, unit);
}
public boolean waitForClientSignal() throws InterruptedException {
return waitForClientSignal(CLIENT_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
}
+ public boolean waitForClientDone(long timeout, TimeUnit unit)
+ throws InterruptedException {
+
+ return clientDoneCondition.await(timeout, unit);
+ }
+
+ public boolean waitForClientDone() throws InterruptedException {
+ return waitForClientDone(CLIENT_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
+ }
+
public void signalClientReady() {
- clientCondition.countDown();
+ clientReadyCondition.countDown();
+ }
+
+ public void signalClientDone() {
+ clientDoneCondition.countDown();
}
public boolean waitForServerSignal(long timeout, TimeUnit unit)
throws InterruptedException {
- return serverCondition.await(timeout, unit);
+ return serverReadyCondition.await(timeout, unit);
}
public boolean waitForServerSignal() throws InterruptedException {
return waitForServerSignal(SERVER_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
}
+ public boolean waitForServerDone(long timeout, TimeUnit unit)
+ throws InterruptedException {
+
+ return serverDoneCondition.await(timeout, unit);
+ }
+
+ public boolean waitForServerDone() throws InterruptedException {
+ return waitForServerDone(SERVER_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
+ }
+
public SSLTest setServerPeer(Peer serverPeer) {
this.serverPeer = serverPeer;
return this;
@@ -310,19 +367,14 @@
test.signalServerReady();
// Try to accept a connection in 30 seconds.
- SSLSocket sslSocket;
- try {
- sslServerSocket.setSoTimeout(SERVER_TIMEOUT);
- sslSocket = (SSLSocket) sslServerSocket.accept();
- print("Server accepted connection");
- } catch (SocketTimeoutException ste) {
- sslServerSocket.close();
-
+ SSLSocket sslSocket = accept(sslServerSocket);
+ if (sslSocket == null) {
// Ignore the test case if no connection within 30 seconds.
print("No incoming client connection in 30 seconds. "
- + "Ignore in server side.", ste);
+ + "Ignore in server side.");
return;
}
+ print("Server accepted connection");
// handle the connection
try {
@@ -353,6 +405,8 @@
sslSocket.close();
sslServerSocket.close();
}
+
+ test.signalServerDone();
}
/*
@@ -419,6 +473,8 @@
print("Run client application");
test.getClientApplication().run(sslSocket, test);
}
+
+ test.signalClientDone();
}
/*
--- a/jdk/test/javax/script/DummyScriptEngineFactory.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/javax/script/DummyScriptEngineFactory.java Thu Oct 27 08:52:00 2016 -0700
@@ -91,9 +91,10 @@
}
public String getProgram(String... statements) {
+ Objects.requireNonNull(statements);
StringBuffer buf = new StringBuffer();
- for (int i = 0; i < statements.length; i++) {
- buf.append(statements[i]);
+ for (String stat : statements) {
+ buf.append(Objects.requireNonNull(stat));
}
return buf.toString();
}
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/JarUtils.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/JarUtils.java Thu Oct 27 08:52:00 2016 -0700
@@ -24,6 +24,7 @@
package jdk.testlibrary;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
@@ -40,7 +41,8 @@
public final class JarUtils {
/**
- * Create jar file with specified files.
+ * Create jar file with specified files. If a specified file does not exist,
+ * a new jar entry will be created with the file name itself as the content.
*/
public static void createJar(String dest, String... files)
throws IOException {
@@ -54,6 +56,8 @@
jos.putNextEntry(new JarEntry(file));
try (FileInputStream fis = new FileInputStream(file)) {
fis.transferTo(jos);
+ } catch (FileNotFoundException e) {
+ jos.write(file.getBytes());
}
}
}
@@ -61,7 +65,17 @@
}
/**
- * Add specified files to existing jar file.
+ * Add or remove specified files to existing jar file. If a specified file
+ * to be updated or added does not exist, the jar entry will be created
+ * with the file name itself as the content.
+ *
+ * @param src the original jar file name
+ * @param dest the new jar file name
+ * @param files the files to update. The list is broken into 2 groups
+ * by a "-" string. The files before in the 1st group will
+ * be either updated or added. The files in the 2nd group
+ * will be removed. If no "-" exists, all files belong to
+ * the 1st group.
*/
public static void updateJar(String src, String dest, String... files)
throws IOException {
@@ -77,8 +91,11 @@
JarEntry entry = entries.nextElement();
String name = entry.getName();
boolean found = false;
+ boolean update = true;
for (String file : files) {
- if (name.equals(file)) {
+ if (file.equals("-")) {
+ update = false;
+ } else if (name.equals(file)) {
updatedFiles.add(file);
found = true;
break;
@@ -86,11 +103,18 @@
}
if (found) {
- System.out.println(String.format("Updating %s with %s",
- dest, name));
- jos.putNextEntry(new JarEntry(name));
- try (FileInputStream fis = new FileInputStream(name)) {
- fis.transferTo(jos);
+ if (update) {
+ System.out.println(String.format("Updating %s with %s",
+ dest, name));
+ jos.putNextEntry(new JarEntry(name));
+ try (FileInputStream fis = new FileInputStream(name)) {
+ fis.transferTo(jos);
+ } catch (FileNotFoundException e) {
+ jos.write(name.getBytes());
+ }
+ } else {
+ System.out.println(String.format("Removing %s from %s",
+ name, dest));
}
} else {
System.out.println(String.format("Copying %s to %s",
@@ -103,12 +127,17 @@
// append new files
for (String file : files) {
+ if (file.equals("-")) {
+ break;
+ }
if (!updatedFiles.contains(file)) {
System.out.println(String.format("Adding %s with %s",
dest, file));
jos.putNextEntry(new JarEntry(file));
try (FileInputStream fis = new FileInputStream(file)) {
fis.transferTo(jos);
+ } catch (FileNotFoundException e) {
+ jos.write(file.getBytes());
}
}
}
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/OriginServer.java Wed Oct 19 08:05:48 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * 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.
- */
-
-/*
- *
- * This is a HTTP test server used by the regression test
- * for the bug fixes: 4323990, 4413069
- */
-
-import java.io.*;
-import java.net.*;
-import javax.net.*;
-
-/*
- * OriginServer.java -- a simple server that can serve
- * Http get request in both clear and secure channel
- */
-
-public abstract class OriginServer implements Runnable {
-
- private ServerSocket server = null;
- Exception serverException = null;
- /**
- * Constructs a OriginServer based on ss and
- * obtains a response data's bytecodes using the method
- * getBytes.
- */
- protected OriginServer(ServerSocket ss) throws Exception
- {
- server = ss;
- newListener();
- if (serverException != null)
- throw serverException;
- }
-
- /**
- * Returns an array of bytes containing the bytes for
- * the data sent in the response.
- *
- * @return the bytes for the information that is being sent
- */
- public abstract byte[] getBytes();
-
- /**
- * The "listen" thread that accepts a connection to the
- * server, parses the header and sends back the response
- */
- public void run()
- {
- Socket socket;
-
- // accept a connection
- try {
- socket = server.accept();
- } catch (IOException e) {
- System.out.println("Class Server died: " + e.getMessage());
- serverException = e;
- return;
- }
- try {
- DataOutputStream out =
- new DataOutputStream(socket.getOutputStream());
- try {
- BufferedReader in =
- new BufferedReader(new InputStreamReader(
- socket.getInputStream()));
- // read the request
- readRequest(in);
- // retrieve bytecodes
- byte[] bytecodes = getBytes();
- // send bytecodes in response (assumes HTTP/1.0 or later)
- try {
- out.writeBytes("HTTP/1.0 200 OK\r\n");
- out.writeBytes("Content-Length: " + bytecodes.length +
- "\r\n");
- out.writeBytes("Content-Type: text/html\r\n\r\n");
- out.write(bytecodes);
- out.flush();
- } catch (IOException ie) {
- serverException = ie;
- return;
- }
-
- } catch (Exception e) {
- // write out error response
- out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
- out.writeBytes("Content-Type: text/html\r\n\r\n");
- out.flush();
- }
-
- } catch (IOException ex) {
- System.out.println("error writing response: " + ex.getMessage());
- serverException = ex;
-
- } finally {
- try {
- socket.close();
- } catch (IOException e) {
- serverException = e;
- }
- }
- }
-
- /**
- * Create a new thread to listen.
- */
- private void newListener()
- {
- (new Thread(this)).start();
- }
-
- /**
- * read the response, don't care for the syntax of the request-line
- * for this testing
- */
- private static void readRequest(BufferedReader in)
- throws IOException
- {
- String line = null;
- System.out.println("Server received: ");
- do {
- if (line != null)
- System.out.println(line);
- line = in.readLine();
- } while ((line.length() != 0) &&
- (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
- }
-}
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,38 @@
/*
* @test
- * @bug 4323990 4413069
+ * @bug 4323990 4413069 8160838
* @summary HttpsURLConnection doesn't send Proxy-Authorization on CONNECT
* Incorrect checking of proxy server response
* @modules java.base/sun.net.www
- * @run main/othervm ProxyAuthTest
- *
- * No way to reserve and restore java.lang.Authenticator, need to run this
- * test in othervm mode.
+ * @library /javax/net/ssl/templates
+ * @run main/othervm ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic, ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=BAsIc ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic,Digest ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Unknown,bAsIc ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes= ProxyAuthTest succeed
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Digest,NTLM,Negotiate ProxyAuthTest succeed
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=UNKNOWN,notKnown ProxyAuthTest succeed
*/
-import java.io.*;
-import java.net.*;
-import java.security.KeyStore;
-import javax.net.*;
-import javax.net.ssl.*;
-import java.security.cert.*;
+// No way to reserve and restore java.lang.Authenticator, as well as read-once
+// system properties, so this tests needs to run in othervm mode.
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.Authenticator;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.Proxy;
+import java.net.URL;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+import static java.nio.charset.StandardCharsets.US_ASCII;
/*
* ProxyAuthTest.java -- includes a simple server that can serve
@@ -56,132 +72,167 @@
static String trustStoreFile = "truststore";
static String passwd = "passphrase";
- volatile private static int serverPort = 0;
-
- /*
- * The TestServer implements a OriginServer that
- * processes HTTP requests and responses.
+ /**
+ * read the response, don't care for the syntax of the request-line
+ * for this testing
*/
- static class TestServer extends OriginServer {
- public TestServer(ServerSocket ss) throws Exception {
- super(ss);
- }
-
- /*
- * Returns an array of bytes containing the bytes for
- * the data sent in the response.
- *
- * @return bytes for the data in the response
- */
- public byte[] getBytes() {
- return "Proxy authentication for tunneling succeeded ..".
- getBytes();
- }
+ private static void readRequest(BufferedReader in) throws IOException {
+ String line = null;
+ System.out.println("Server received: ");
+ do {
+ if (line != null) {
+ System.out.println(line);
+ }
+ line = in.readLine();
+ } while ((line.length() != 0) &&
+ (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
}
/*
* Main method to create the server and the client
*/
public static void main(String args[]) throws Exception {
+ boolean expectSuccess;
+ expectSuccess = args[0].equals("succeed");
+
String keyFilename =
- System.getProperty("test.src", "./") + "/" + pathToStores +
- "/" + keyStoreFile;
+ SSLTest.TEST_SRC + "/" + pathToStores + "/" + keyStoreFile;
String trustFilename =
- System.getProperty("test.src", "./") + "/" + pathToStores +
- "/" + trustStoreFile;
+ SSLTest.TEST_SRC + "/" + pathToStores + "/" + trustStoreFile;
+
+ SSLTest.setup(keyFilename, trustFilename, passwd);
+
+ new SSLTest()
+ .setServerApplication((socket, test) -> {
+ DataOutputStream out = new DataOutputStream(
+ socket.getOutputStream());
- System.setProperty("javax.net.ssl.keyStore", keyFilename);
- System.setProperty("javax.net.ssl.keyStorePassword", passwd);
- System.setProperty("javax.net.ssl.trustStore", trustFilename);
- System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+ try {
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(socket.getInputStream()));
+
+ // read the request
+ readRequest(in);
+
+ // retrieve bytecodes
+ byte[] bytecodes =
+ "Proxy authentication for tunneling succeeded .."
+ .getBytes(US_ASCII);
- boolean useSSL = true;
- /*
- * setup the server
- */
- try {
- ServerSocketFactory ssf =
- ProxyAuthTest.getServerSocketFactory(useSSL);
- ServerSocket ss = ssf.createServerSocket(serverPort);
- serverPort = ss.getLocalPort();
- new TestServer(ss);
- } catch (Exception e) {
- System.out.println("Server side failed:" +
- e.getMessage());
- throw e;
- }
- // trigger the client
- try {
- doClientSide();
- } catch (Exception e) {
- System.out.println("Client side failed: " + e.getMessage());
- throw e;
- }
+ // send bytecodes in response (assumes HTTP/1.0 or later)
+ out.writeBytes("HTTP/1.0 200 OK\r\n");
+ out.writeBytes("Content-Length: " + bytecodes.length +
+ "\r\n");
+ out.writeBytes("Content-Type: text/html\r\n\r\n");
+ out.write(bytecodes);
+ out.flush();
+ } catch (IOException e) {
+ // write out error response
+ out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
+ out.writeBytes("Content-Type: text/html\r\n\r\n");
+ out.flush();
+ }
+ })
+ .setClientPeer(test -> {
+ try {
+ doClientSide(test);
+ if (!expectSuccess) {
+ throw new RuntimeException("Expected exception/failure "
+ + "to connect, but succeeded.");
+ }
+ } catch (IOException e) {
+ if (expectSuccess) {
+ System.out.println("Client side failed: "
+ + e.getMessage());
+ throw e;
+ }
+
+ if (! (e.getMessage().contains(
+ "Unable to tunnel through proxy") &&
+ e.getMessage().contains("407")) ) {
+
+ throw new RuntimeException(
+ "Expected exception about cannot tunnel, "
+ + "407, etc, but got", e);
+ } else {
+ // Informative
+ System.out.println("Caught expected exception: "
+ + e.getMessage());
+ }
+ }
+ })
+ .runTest();
}
- private static ServerSocketFactory getServerSocketFactory
- (boolean useSSL) throws Exception {
- if (useSSL) {
- SSLServerSocketFactory ssf = null;
- // set up key manager to do server authentication
- SSLContext ctx;
- KeyManagerFactory kmf;
- KeyStore ks;
- char[] passphrase = passwd.toCharArray();
-
- ctx = SSLContext.getInstance("TLS");
- kmf = KeyManagerFactory.getInstance("SunX509");
- ks = KeyStore.getInstance("JKS");
+ static void doClientSide(SSLTest test) throws IOException {
- ks.load(new FileInputStream(System.getProperty(
- "javax.net.ssl.keyStore")), passphrase);
- kmf.init(ks, passphrase);
- ctx.init(kmf.getKeyManagers(), null, null);
+ // Wait for server to get started.
+ //
+ // The server side takes care of the issue if the server cannot
+ // get started in 90 seconds. The client side would just ignore
+ // the test case if the serer is not ready.
+ try {
+ if (!test.waitForServerSignal()) {
+ System.out.print("The server is not ready yet in 90 seconds. "
+ + "Ignore in client side.");
+ return;
+ }
+ } catch (InterruptedException e) {
+ System.out.print("InterruptedException occured. "
+ + "Ignore in client side.");
+ return;
+ }
- ssf = ctx.getServerSocketFactory();
- return ssf;
- } else {
- return ServerSocketFactory.getDefault();
- }
- }
-
- static void doClientSide() throws Exception {
/*
* setup up a proxy with authentication information
*/
- setupProxy();
+ ProxyTunnelServer ps = setupProxy();
/*
* we want to avoid URLspoofCheck failures in cases where the cert
* DN name does not match the hostname in the URL.
*/
- HttpsURLConnection.setDefaultHostnameVerifier(
- new NameVerifier());
- URL url = new URL("https://" + "localhost:" + serverPort
- + "/index.html");
- BufferedReader in = null;
- try {
- in = new BufferedReader(new InputStreamReader(
- url.openStream()));
+ HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+
+ InetSocketAddress paddr = new InetSocketAddress(
+ "localhost", ps.getPort());
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, paddr);
+
+ URL url = new URL("https://" + "localhost:" + test.getServerPort()
+ + "/index.html");
+
+ // Signal the server, the client is ready to communicate.
+ test.signalClientReady();
+
+ HttpsURLConnection uc = (HttpsURLConnection) url.openConnection(proxy);
+ try (BufferedReader in = new BufferedReader(
+ new InputStreamReader(uc.getInputStream()))) {
+
String inputLine;
System.out.print("Client recieved from the server: ");
- while ((inputLine = in.readLine()) != null)
+ while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
- in.close();
- } catch (SSLException e) {
- if (in != null)
- in.close();
+ }
+ } catch (IOException e) {
+ // Assert that the error stream is not accessible from the failed
+ // tunnel setup.
+ if (uc.getErrorStream() != null) {
+ throw new RuntimeException("Unexpected error stream.");
+ }
+
throw e;
}
}
static class NameVerifier implements HostnameVerifier {
+
+ @Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
- static void setupProxy() throws IOException {
+ static ProxyTunnelServer setupProxy() throws IOException {
ProxyTunnelServer pserver = new ProxyTunnelServer();
/*
* register a system wide authenticator and setup the proxy for
@@ -194,16 +245,14 @@
pserver.setUserAuth("Test", "test123");
pserver.start();
- System.setProperty("https.proxyHost", "localhost");
- System.setProperty("https.proxyPort", String.valueOf(
- pserver.getPort()));
+ return pserver;
}
public static class TestAuthenticator extends Authenticator {
+ @Override
public PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication("Test",
- "test123".toCharArray());
+ return new PasswordAuthentication("Test", "test123".toCharArray());
}
}
}
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyTunnelServer.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyTunnelServer.java Thu Oct 27 08:52:00 2016 -0700
@@ -65,6 +65,7 @@
ss = (ServerSocket) ServerSocketFactory.getDefault().
createServerSocket(0);
}
+ setDaemon(true);
}
public void needUserAuth(boolean auth) {
@@ -211,6 +212,7 @@
this.sockOut = sockOut;
input = sockIn.getInputStream();
output = sockOut.getOutputStream();
+ setDaemon(true);
}
public void run() {
--- a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Thu Oct 27 08:52:00 2016 -0700
@@ -57,5 +57,6 @@
${TESTSRC}${FS}ProxyTunnelServer.java \
${TESTSRC}${FS}PostThruProxyWithAuth.java
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} ${EXTRAOPTS} \
+ -Djdk.http.auth.tunneling.disabledSchemes= \
PostThruProxyWithAuth ${HOSTNAME} ${TESTSRC}
exit
--- a/jdk/test/sun/net/www/protocol/jar/B4957695.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/sun/net/www/protocol/jar/B4957695.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
/**
* @test
* @bug 4957695
+ * @run main/othervm -Djava.io.tmpdir=. B4957695
* @summary URLJarFile.retrieve does not delete tmpFile on IOException
*/
--- a/jdk/test/sun/reflect/ReflectionFactory/NewConstructorForSerialization.java Wed Oct 19 08:05:48 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * 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 8137058
- * @summary Basic test for the unsupported newConstructorForSerialization
- * @modules jdk.unsupported
- */
-
-import java.lang.reflect.Constructor;
-import sun.reflect.ReflectionFactory;
-
-public class NewConstructorForSerialization {
-
- private static Constructor<?> getConstructor(Class<?> type)
- throws NoSuchMethodException
- {
- ReflectionFactory factory = ReflectionFactory.getReflectionFactory();
- Constructor<?> objectConstructor = type.getConstructor((Class[]) null);
-
- @SuppressWarnings("unchecked")
- Constructor<?> c = (Constructor<?>) factory
- .newConstructorForSerialization(type, objectConstructor);
- return c;
- }
-
- public static void main(String[] args) throws Exception {
- System.out.println(getConstructor(Object.class).newInstance());
- System.out.println(getConstructor(Foo.class).newInstance());
- System.out.println(getConstructor(Bar.class).newInstance());
- }
-
- static class Foo {
- public Foo() { }
- }
-
- static class Bar extends Foo {
- public Bar() { }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/reflect/ReflectionFactory/ReflectionFactoryTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,289 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.OptionalDataException;
+import java.io.Serializable;
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import sun.reflect.ReflectionFactory;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import org.testng.TestNG;
+
+/*
+ * @test
+ * @bug 8137058 8164908
+ * @run testng ReflectionFactoryTest
+ * @run testng/othervm/policy=security.policy ReflectionFactoryTest
+ * @summary Basic test for the unsupported ReflectionFactory
+ * @modules jdk.unsupported
+ */
+
+public class ReflectionFactoryTest {
+
+ // Initialized by init()
+ static ReflectionFactory factory;
+
+ @DataProvider(name = "ClassConstructors")
+ static Object[][] classConstructors() {
+ return new Object[][] {
+ {Object.class},
+ {Foo.class},
+ {Bar.class},
+ };
+ }
+
+ @BeforeClass
+ static void init() {
+ factory = ReflectionFactory.getReflectionFactory();
+ }
+
+ /**
+ * Test that the correct Constructor is selected and run.
+ * @param type type of object to create
+ * @throws NoSuchMethodException - error
+ * @throws InstantiationException - error
+ * @throws IllegalAccessException - error
+ * @throws InvocationTargetException - error
+ */
+ @Test(dataProvider="ClassConstructors")
+ static void testConstructor(Class<?> type)
+ throws NoSuchMethodException, InstantiationException,
+ IllegalAccessException, InvocationTargetException
+ {
+ @SuppressWarnings("unchecked")
+ Constructor<?> c = factory.newConstructorForSerialization(type);
+
+ Object o = c.newInstance();
+ Assert.assertEquals(o.getClass(), type, "Instance is wrong type");
+ if (o instanceof Foo) {
+ Foo foo = (Foo)o;
+ foo.check();
+ }
+ }
+
+ static class Foo {
+ private int foo;
+ public Foo() {
+ this.foo = 1;
+ }
+
+ public String toString() {
+ return "foo: " + foo;
+ }
+
+ public void check() {
+ int expectedFoo = 1;
+ Assert.assertEquals(foo, expectedFoo, "foo() constructor not run");
+ }
+ }
+
+ static class Bar extends Foo implements Serializable {
+ private int bar;
+ public Bar() {
+ this.bar = 1;
+ }
+
+ public String toString() {
+ return super.toString() + ", bar: " + bar;
+ }
+
+ public void check() {
+ super.check();
+ int expectedBar = 0;
+ Assert.assertEquals(bar, expectedBar, "bar() constructor not run");
+ }
+ }
+
+ /**
+ * Test newConstructorForExternalization returns the constructor and it can be called.
+ * @throws NoSuchMethodException - error
+ * @throws InstantiationException - error
+ * @throws IllegalAccessException - error
+ * @throws InvocationTargetException - error
+ */
+ @Test
+ static void newConstructorForExternalization()
+ throws NoSuchMethodException, InstantiationException,
+ IllegalAccessException, InvocationTargetException {
+ Constructor<?> cons = factory.newConstructorForExternalization(Ext.class);
+ Ext ext = (Ext)cons.newInstance();
+ Assert.assertEquals(ext.ext, 1, "Constructor not run");
+ }
+
+ static class Ext implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
+ int ext;
+
+ public Ext() {
+ ext = 1;
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {}
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {}
+ }
+
+ @Test
+ static void testReadWriteObjectForSerialization() throws Throwable {
+ MethodHandle readObjectMethod = factory.readObjectForSerialization(Ser.class);
+ Assert.assertNotNull(readObjectMethod, "readObjectMethod not found");
+
+ MethodHandle readObjectNoDataMethod = factory.readObjectNoDataForSerialization(Ser.class);
+ Assert.assertNotNull(readObjectNoDataMethod, "readObjectNoDataMethod not found");
+
+ MethodHandle writeObjectMethod = factory.writeObjectForSerialization(Ser.class);
+ Assert.assertNotNull(writeObjectMethod, "writeObjectMethod not found");
+
+ MethodHandle readResolveMethod = factory.readResolveForSerialization(Ser.class);
+ Assert.assertNotNull(readResolveMethod, "readResolveMethod not found");
+
+ MethodHandle writeReplaceMethod = factory.writeReplaceForSerialization(Ser.class);
+ Assert.assertNotNull(writeReplaceMethod, "writeReplaceMethod not found");
+
+ byte[] data = null;
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+ Ser ser = new Ser();
+
+ writeReplaceMethod.invoke(ser);
+ Assert.assertTrue(ser.writeReplaceCalled, "writeReplace not called");
+ Assert.assertFalse(ser.writeObjectCalled, "writeObject should not have been called");
+
+ writeObjectMethod.invoke(ser, oos);
+ Assert.assertTrue(ser.writeReplaceCalled, "writeReplace should have been called");
+ Assert.assertTrue(ser.writeObjectCalled, "writeObject not called");
+ oos.flush();
+ data = baos.toByteArray();
+ }
+
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
+ ObjectInputStream ois = new ObjectInputStream(bais)) {
+ Ser ser2 = new Ser();
+
+ readObjectMethod.invoke(ser2, ois);
+ Assert.assertTrue(ser2.readObjectCalled, "readObject not called");
+ Assert.assertFalse(ser2.readObjectNoDataCalled, "readObjectNoData should not be called");
+ Assert.assertFalse(ser2.readResolveCalled, "readResolve should not be called");
+
+ readObjectNoDataMethod.invoke(ser2, ois);
+ Assert.assertTrue(ser2.readObjectCalled, "readObject should have been called");
+ Assert.assertTrue(ser2.readObjectNoDataCalled, "readObjectNoData not called");
+ Assert.assertFalse(ser2.readResolveCalled, "readResolve should not be called");
+
+ readResolveMethod.invoke(ser2);
+ Assert.assertTrue(ser2.readObjectCalled, "readObject should have been called");
+ Assert.assertTrue(ser2.readObjectNoDataCalled, "readObjectNoData not called");
+ Assert.assertTrue(ser2.readResolveCalled, "readResolve not called");
+ }
+ }
+
+ @Test
+ static void hasStaticInitializer() {
+ boolean actual = factory.hasStaticInitializerForSerialization(Ser.class);
+ Assert.assertTrue(actual, "hasStaticInitializerForSerialization is wrong");
+ }
+
+ static class Ser implements Serializable {
+ private static final long serialVersionUID = 2L;
+ static {
+ // Define a static class initialization method
+ }
+
+ boolean readObjectCalled = false;
+ boolean readObjectNoDataCalled = false;
+ boolean writeObjectCalled = false;
+ boolean readResolveCalled = false;
+ boolean writeReplaceCalled = false;
+
+ public Ser() {}
+
+ private void readObject(ObjectInputStream ois) throws IOException {
+ Assert.assertFalse(writeObjectCalled, "readObject called too many times");
+ readObjectCalled = ois.readBoolean();
+ }
+
+ private void readObjectNoData(ObjectInputStream ois) throws IOException {
+ Assert.assertFalse(readObjectNoDataCalled, "readObjectNoData called too many times");
+ readObjectNoDataCalled = true;
+ }
+
+ private void writeObject(ObjectOutputStream oos) throws IOException {
+ Assert.assertFalse(writeObjectCalled, "writeObject called too many times");
+ writeObjectCalled = true;
+ oos.writeBoolean(writeObjectCalled);
+ }
+
+ private Object writeReplace() {
+ Assert.assertFalse(writeReplaceCalled, "writeReplace called too many times");
+ writeReplaceCalled = true;
+ return this;
+ }
+
+ private Object readResolve() {
+ Assert.assertFalse(readResolveCalled, "readResolve called too many times");
+ readResolveCalled = true;
+ return this;
+ }
+ }
+
+ /**
+ * Test the constructor of OptionalDataExceptions.
+ */
+ @Test
+ static void newOptionalDataException() {
+ OptionalDataException ode = factory.newOptionalDataExceptionForSerialization(true);
+ Assert.assertTrue(ode.eof, "eof wrong");
+ ode = factory.newOptionalDataExceptionForSerialization(false);
+ Assert.assertFalse(ode.eof, "eof wrong");
+
+ }
+
+
+
+ // Main can be used to run the tests from the command line with only testng.jar.
+ @SuppressWarnings("raw_types")
+ @Test(enabled = false)
+ public static void main(String[] args) {
+ Class<?>[] testclass = {ReflectionFactoryTest.class};
+ TestNG testng = new TestNG();
+ testng.setTestClasses(testclass);
+ testng.run();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/reflect/ReflectionFactory/security.policy Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,11 @@
+// Individual Permissions for ReflectionFactoryTest
+grant {
+ // Permissions needed to run the test
+ permission java.util.PropertyPermission "*", "read";
+ permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete,execute";
+
+ permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+ permission java.lang.RuntimePermission "accessDeclaredMembers";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
+ permission java.lang.RuntimePermission "reflectionFactoryAccess";
+};
--- a/jdk/test/sun/security/ec/TestEC.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/sun/security/ec/TestEC.java Thu Oct 27 08:52:00 2016 -0700
@@ -28,7 +28,7 @@
/**
* @test
- * @bug 6840752
+ * @bug 6840752 8168078
* @summary Provide out-of-the-box support for ECC algorithms
* @library ../pkcs11
* @library ../pkcs11/ec
@@ -37,6 +37,7 @@
* @modules jdk.crypto.pkcs11/sun.security.pkcs11.wrapper
* @compile -XDignore.symbol.file TestEC.java
* @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
+ * @run main/othervm/java.security.policy=TestEC.policy -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
*/
import java.security.NoSuchProviderException;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ec/TestEC.policy Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,3 @@
+grant codebase "file:${test.classes}/*" {
+ permission java.security.AllPermission;
+};
--- a/jdk/test/sun/security/pkcs/pkcs7/PKCS7VerifyTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/sun/security/pkcs/pkcs7/PKCS7VerifyTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,8 +27,8 @@
* @summary Read signed data in one or more PKCS7 objects from individual files,
* verify SignerInfos and certificate chain.
* @modules java.base/sun.security.pkcs
- * @run main PKCS7VerifyTest PKCS7TEST.DSA.base64
- * @run main PKCS7VerifyTest PKCS7TEST.DSA.base64 PKCS7TEST.SF
+ * @run main/othervm PKCS7VerifyTest PKCS7TEST.DSA.base64
+ * @run main/othervm PKCS7VerifyTest PKCS7TEST.DSA.base64 PKCS7TEST.SF
*/
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -36,6 +36,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.HashMap;
@@ -55,6 +56,8 @@
throw new RuntimeException("usage: java JarVerify <file1> <file2>");
}
+ Security.setProperty("jdk.jar.disabledAlgorithms", "");
+
// The command " java PKCS7VerifyTest file1 [file2] "
// treats file1 as containing the DER encoding of a PKCS7 signed data
// object. If file2 is absent, the program verifies that some signature
--- a/jdk/test/sun/security/pkcs11/PKCS11Test.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java Thu Oct 27 08:52:00 2016 -0700
@@ -47,6 +47,7 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
@@ -112,7 +113,7 @@
found = true;
break;
}
- } catch (Exception e) {
+ } catch (Exception | ServiceConfigurationError e) {
// ignore and move on to the next one
}
}
--- a/jdk/test/sun/security/tools/jarsigner/JarSigningNonAscii.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/sun/security/tools/jarsigner/JarSigningNonAscii.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,12 @@
* @bug 4924188
* @summary sign a JAR file that has entry names with non-ASCII characters.
* @modules jdk.jartool/sun.security.tools.jarsigner
+ * @run main/othervm JarSigningNonAscii
*/
import sun.security.tools.*;
import java.io.*;
+import java.security.Security;
import java.util.*;
import java.util.jar.*;
import java.security.cert.Certificate;
@@ -40,6 +42,7 @@
private static String keystore;
public static void main(String[] args) throws Exception {
+ Security.setProperty("jdk.jar.disabledAlgorithms", "");
String srcDir = System.getProperty("test.src", ".");
String destDir = System.getProperty("test.classes", ".");
--- a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Thu Oct 27 08:52:00 2016 -0700
@@ -22,25 +22,29 @@
*/
import com.sun.net.httpserver.*;
-import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.InetSocketAddress;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
+import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
-import java.util.Locale;
+import jdk.testlibrary.*;
+import jdk.testlibrary.JarUtils;
import sun.security.pkcs.ContentInfo;
import sun.security.pkcs.PKCS7;
import sun.security.pkcs.PKCS9Attribute;
@@ -52,11 +56,22 @@
import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name;
+/*
+ * @test
+ * @bug 6543842 6543440 6939248 8009636 8024302 8163304
+ * @summary checking response of timestamp
+ * @modules java.base/sun.security.pkcs
+ * java.base/sun.security.timestamp
+ * java.base/sun.security.x509
+ * java.base/sun.security.util
+ * java.base/sun.security.tools.keytool
+ * @library /lib/testlibrary
+ * @run main/timeout=600 TimestampCheck
+ */
public class TimestampCheck {
- static final String TSKS = "tsks";
- static final String JAR = "old.jar";
- static final String defaultPolicyId = "2.3.4.5";
+ static final String defaultPolicyId = "2.3.4";
+ static String host = null;
static class Handler implements HttpHandler, AutoCloseable {
@@ -75,11 +90,7 @@
t.getRequestBody().read(input);
try {
- int path = 0;
- if (t.getRequestURI().getPath().length() > 1) {
- path = Integer.parseInt(
- t.getRequestURI().getPath().substring(1));
- }
+ String path = t.getRequestURI().getPath().substring(1);
byte[] output = sign(input, path);
Headers out = t.getResponseHeaders();
out.set("Content-Type", "application/timestamp-reply");
@@ -97,24 +108,10 @@
/**
* @param input The data to sign
* @param path different cases to simulate, impl on URL path
- * 0: normal
- * 1: Missing nonce
- * 2: Different nonce
- * 3: Bad digets octets in messageImprint
- * 4: Different algorithmId in messageImprint
- * 5: whole chain in cert set
- * 6: extension is missing
- * 7: extension is non-critical
- * 8: extension does not have timestamping
- * 9: no cert in response
- * 10: normal
- * 11: always return default policy id
- * 12: normal
- * otherwise: normal
* @returns the signed
*/
- byte[] sign(byte[] input, int path) throws Exception {
- // Read TSRequest
+ byte[] sign(byte[] input, String path) throws Exception {
+
DerValue value = new DerValue(input);
System.err.println("\nIncoming Request\n===================");
System.err.println("Version: " + value.data.getInteger());
@@ -138,36 +135,33 @@
}
}
- // Write TSResponse
System.err.println("\nResponse\n===================");
- KeyStore ks = KeyStore.getInstance("JKS");
- try (FileInputStream fis = new FileInputStream(keystore)) {
- ks.load(fis, "changeit".toCharArray());
+ KeyStore ks = KeyStore.getInstance(
+ new File(keystore), "changeit".toCharArray());
+
+ String alias = "ts";
+ if (path.startsWith("bad") || path.equals("weak")) {
+ alias = "ts" + path;
}
- String alias = "ts";
- if (path == 6) alias = "tsbad1";
- if (path == 7) alias = "tsbad2";
- if (path == 8) alias = "tsbad3";
-
- if (path == 11) {
+ if (path.equals("diffpolicy")) {
policyId = new ObjectIdentifier(defaultPolicyId);
}
DerOutputStream statusInfo = new DerOutputStream();
statusInfo.putInteger(0);
- DerOutputStream token = new DerOutputStream();
AlgorithmId[] algorithms = {aid};
Certificate[] chain = ks.getCertificateChain(alias);
- X509Certificate[] signerCertificateChain = null;
+ X509Certificate[] signerCertificateChain;
X509Certificate signer = (X509Certificate)chain[0];
- if (path == 5) { // Only case 5 uses full chain
+
+ if (path.equals("fullchain")) { // Only case 5 uses full chain
signerCertificateChain = new X509Certificate[chain.length];
for (int i=0; i<chain.length; i++) {
signerCertificateChain[i] = (X509Certificate)chain[i];
}
- } else if (path == 9) {
+ } else if (path.equals("nocert")) {
signerCertificateChain = new X509Certificate[0];
} else {
signerCertificateChain = new X509Certificate[1];
@@ -179,11 +173,11 @@
tst.putInteger(1);
tst.putOID(policyId);
- if (path != 3 && path != 4) {
+ if (!path.equals("baddigest") && !path.equals("diffalg")) {
tst.putDerValue(messageImprint);
} else {
byte[] data = messageImprint.toByteArray();
- if (path == 4) {
+ if (path.equals("diffalg")) {
data[6] = (byte)0x01;
} else {
data[data.length-1] = (byte)0x01;
@@ -198,10 +192,10 @@
Calendar cal = Calendar.getInstance();
tst.putGeneralizedTime(cal.getTime());
- if (path == 2) {
+ if (path.equals("diffnonce")) {
tst.putInteger(1234);
- } else if (path == 1) {
- // do nothing
+ } else if (path.equals("nononce")) {
+ // no noce
} else {
tst.putInteger(nonce);
}
@@ -212,6 +206,8 @@
DerOutputStream tstInfo2 = new DerOutputStream();
tstInfo2.putOctetString(tstInfo.toByteArray());
+ // Always use the same algorithm at timestamp signing
+ // so it is different from the hash algorithm.
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign((PrivateKey)(ks.getKey(
alias, "changeit".toCharArray())));
@@ -229,12 +225,11 @@
SignerInfo signerInfo = new SignerInfo(
new X500Name(signer.getIssuerX500Principal().getName()),
signer.getSerialNumber(),
- aid, AlgorithmId.get("RSA"), sig.sign());
+ AlgorithmId.get("SHA-1"), AlgorithmId.get("RSA"), sig.sign());
SignerInfo[] signerInfos = {signerInfo};
- PKCS7 p7 =
- new PKCS7(algorithms, contentInfo, signerCertificateChain,
- signerInfos);
+ PKCS7 p7 = new PKCS7(algorithms, contentInfo,
+ signerCertificateChain, signerInfos);
ByteArrayOutputStream p7out = new ByteArrayOutputStream();
p7.encodeSignedData(p7out);
@@ -294,44 +289,68 @@
}
}
- public static void main(String[] args) throws Exception {
- try (Handler tsa = Handler.init(0, TSKS);) {
+ public static void main(String[] args) throws Throwable {
+
+ prepare();
+
+ try (Handler tsa = Handler.init(0, "tsks");) {
tsa.start();
int port = tsa.getPort();
-
- String cmd;
- // Use -J-Djava.security.egd=file:/dev/./urandom to speed up
- // nonce generation in timestamping request. Not avaibale on
- // Windows and defaults to thread seed generator, not too bad.
- if (System.getProperty("java.home").endsWith("jre")) {
- cmd = System.getProperty("java.home") + "/../bin/jarsigner";
- } else {
- cmd = System.getProperty("java.home") + "/bin/jarsigner";
- }
-
- cmd += " " + System.getProperty("test.tool.vm.opts")
- + " -J-Djava.security.egd=file:/dev/./urandom"
- + " -J-Duser.language=en -J-Duser.country=US"
- + " -debug -keystore " + TSKS + " -storepass changeit"
- + " -tsa http://localhost:" + port + "/%d"
- + " -signedjar new_%d.jar " + JAR + " old";
+ host = "http://localhost:" + port + "/";
if (args.length == 0) { // Run this test
- jarsigner(cmd, 0, true); // Success, normal call
- jarsigner(cmd, 1, false); // These 4 should fail
- jarsigner(cmd, 2, false);
- jarsigner(cmd, 3, false);
- jarsigner(cmd, 4, false);
- jarsigner(cmd, 5, true); // Success, 6543440 solved.
- jarsigner(cmd, 6, false); // tsbad1
- jarsigner(cmd, 7, false); // tsbad2
- jarsigner(cmd, 8, false); // tsbad3
- jarsigner(cmd, 9, false); // no cert in timestamp
- jarsigner(cmd + " -tsapolicyid 1.2.3.4", 10, true);
- checkTimestamp("new_10.jar", "1.2.3.4", "SHA-256");
- jarsigner(cmd + " -tsapolicyid 1.2.3.5", 11, false);
- jarsigner(cmd + " -tsadigestalg SHA", 12, true);
- checkTimestamp("new_12.jar", defaultPolicyId, "SHA-1");
+ sign("none")
+ .shouldContain("is not timestamped")
+ .shouldHaveExitValue(0);
+
+ sign("badku")
+ .shouldHaveExitValue(0);
+ checkBadKU("badku.jar");
+
+ sign("normal")
+ .shouldNotContain("is not timestamped")
+ .shouldHaveExitValue(0);
+
+ sign("nononce")
+ .shouldHaveExitValue(1);
+ sign("diffnonce")
+ .shouldHaveExitValue(1);
+ sign("baddigest")
+ .shouldHaveExitValue(1);
+ sign("diffalg")
+ .shouldHaveExitValue(1);
+ sign("fullchain")
+ .shouldHaveExitValue(0); // Success, 6543440 solved.
+ sign("bad1")
+ .shouldHaveExitValue(1);
+ sign("bad2")
+ .shouldHaveExitValue(1);
+ sign("bad3")
+ .shouldHaveExitValue(1);
+ sign("nocert")
+ .shouldHaveExitValue(1);
+
+ sign("policy", "-tsapolicyid", "1.2.3")
+ .shouldHaveExitValue(0);
+ checkTimestamp("policy.jar", "1.2.3", "SHA-256");
+
+ sign("diffpolicy", "-tsapolicyid", "1.2.3")
+ .shouldHaveExitValue(1);
+
+ sign("tsaalg", "-tsadigestalg", "SHA")
+ .shouldHaveExitValue(0);
+ checkTimestamp("tsaalg.jar", defaultPolicyId, "SHA-1");
+
+ sign("weak", "-digestalg", "MD5",
+ "-sigalg", "MD5withRSA", "-tsadigestalg", "MD5")
+ .shouldHaveExitValue(0)
+ .shouldMatch("MD5.*-digestalg.*risk")
+ .shouldMatch("MD5.*-tsadigestalg.*risk")
+ .shouldMatch("MD5withRSA.*-sigalg.*risk");
+ checkWeak("weak.jar");
+
+ // When .SF or .RSA is missing or invalid
+ checkMissingOrInvalidFiles("normal.jar");
} else { // Run as a standalone server
System.err.println("Press Enter to quit server");
System.in.read();
@@ -339,6 +358,95 @@
}
}
+ private static void checkMissingOrInvalidFiles(String s)
+ throws Throwable {
+ JarUtils.updateJar(s, "1.jar", "-", "META-INF/OLD.SF");
+ verify("1.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Missing signature-related file META-INF/OLD.SF");
+ JarUtils.updateJar(s, "2.jar", "-", "META-INF/OLD.RSA");
+ verify("2.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Missing block file for signature-related file META-INF/OLD.SF");
+ JarUtils.updateJar(s, "3.jar", "META-INF/OLD.SF");
+ verify("3.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Unparsable signature-related file META-INF/OLD.SF");
+ JarUtils.updateJar(s, "4.jar", "META-INF/OLD.RSA");
+ verify("4.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Unparsable signature-related file META-INF/OLD.RSA");
+ }
+
+ static OutputAnalyzer jarsigner(List<String> extra)
+ throws Throwable {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jarsigner")
+ .addVMArg("-Duser.language=en")
+ .addVMArg("-Duser.country=US")
+ .addToolArg("-keystore")
+ .addToolArg("tsks")
+ .addToolArg("-storepass")
+ .addToolArg("changeit");
+ for (String s : extra) {
+ if (s.startsWith("-J")) {
+ launcher.addVMArg(s.substring(2));
+ } else {
+ launcher.addToolArg(s);
+ }
+ }
+ return ProcessTools.executeCommand(launcher.getCommand());
+ }
+
+ static OutputAnalyzer verify(String file, String... extra)
+ throws Throwable {
+ List<String> args = new ArrayList<>();
+ args.add("-verify");
+ args.add(file);
+ args.addAll(Arrays.asList(extra));
+ return jarsigner(args);
+ }
+
+ static void checkBadKU(String file) throws Throwable {
+ verify(file)
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("re-run jarsigner with debug enabled");
+ verify(file, "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("Signed by")
+ .shouldContain("treated as unsigned")
+ .shouldContain("re-run jarsigner with debug enabled");
+ verify(file, "-J-Djava.security.debug=jar")
+ .shouldHaveExitValue(0)
+ .shouldContain("SignatureException: Key usage restricted")
+ .shouldContain("treated as unsigned")
+ .shouldContain("re-run jarsigner with debug enabled");
+ }
+
+ static void checkWeak(String file) throws Throwable {
+ verify(file)
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldMatch("weak algorithm that is now disabled.")
+ .shouldMatch("Re-run jarsigner with the -verbose option for more details");
+ verify(file, "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldMatch("weak algorithm that is now disabled by")
+ .shouldMatch("Digest algorithm: .*weak")
+ .shouldMatch("Signature algorithm: .*weak")
+ .shouldMatch("Timestamp digest algorithm: .*weak")
+ .shouldNotMatch("Timestamp signature algorithm: .*weak.*weak")
+ .shouldMatch("Timestamp signature algorithm: .*key.*weak");
+ verify(file, "-J-Djava.security.debug=jar")
+ .shouldHaveExitValue(0)
+ .shouldMatch("SignatureException:.*Disabled");
+ }
+
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
@@ -365,41 +473,62 @@
}
}
+ static int which = 0;
+
/**
- * @param cmd the command line (with a hole to plug in)
- * @param path the path in the URL, i.e, http://localhost/path
- * @param expected if this command should succeed
+ * @param extra more args given to jarsigner
*/
- static void jarsigner(String cmd, int path, boolean expected)
- throws Exception {
- System.err.println("Test " + path);
- Process p = Runtime.getRuntime().exec(String.format(Locale.ROOT,cmd, path, path));
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(p.getErrorStream()));
- while (true) {
- String s = reader.readLine();
- if (s == null) break;
- System.err.println(s);
+ static OutputAnalyzer sign(String path, String... extra)
+ throws Throwable {
+ which++;
+ System.err.println("\n>> Test #" + which + ": " + Arrays.toString(extra));
+ List<String> args = List.of("-J-Djava.security.egd=file:/dev/./urandom",
+ "-debug", "-signedjar", path + ".jar", "old.jar",
+ path.equals("badku") ? "badku" : "old");
+ args = new ArrayList<>(args);
+ if (!path.equals("none") && !path.equals("badku")) {
+ args.add("-tsa");
+ args.add(host + path);
}
+ args.addAll(Arrays.asList(extra));
+ return jarsigner(args);
+ }
- // Will not see noTimestamp warning
- boolean seeWarning = false;
- reader = new BufferedReader(
- new InputStreamReader(p.getInputStream()));
- while (true) {
- String s = reader.readLine();
- if (s == null) break;
- System.err.println(s);
- if (s.indexOf("Warning:") >= 0) {
- seeWarning = true;
- }
+ static void prepare() throws Exception {
+ jdk.testlibrary.JarUtils.createJar("old.jar", "A");
+ Files.deleteIfExists(Paths.get("tsks"));
+ keytool("-alias ca -genkeypair -ext bc -dname CN=CA");
+ keytool("-alias old -genkeypair -dname CN=old");
+ keytool("-alias badku -genkeypair -dname CN=badku");
+ keytool("-alias ts -genkeypair -dname CN=ts");
+ keytool("-alias tsweak -genkeypair -keysize 512 -dname CN=tsbad1");
+ keytool("-alias tsbad1 -genkeypair -dname CN=tsbad1");
+ keytool("-alias tsbad2 -genkeypair -dname CN=tsbad2");
+ keytool("-alias tsbad3 -genkeypair -dname CN=tsbad3");
+
+ gencert("old");
+ gencert("badku", "-ext ku:critical=keyAgreement");
+ gencert("ts", "-ext eku:critical=ts");
+ gencert("tsweak", "-ext eku:critical=ts");
+ gencert("tsbad1");
+ gencert("tsbad2", "-ext eku=ts");
+ gencert("tsbad3", "-ext eku:critical=cs");
+ }
+
+ static void gencert(String alias, String... extra) throws Exception {
+ keytool("-alias " + alias + " -certreq -file " + alias + ".req");
+ String genCmd = "-gencert -alias ca -infile " +
+ alias + ".req -outfile " + alias + ".cert";
+ for (String s : extra) {
+ genCmd += " " + s;
}
- int result = p.waitFor();
- if (expected && result != 0 || !expected && result == 0) {
- throw new Exception("Failed");
- }
- if (seeWarning) {
- throw new Exception("See warning");
- }
+ keytool(genCmd);
+ keytool("-alias " + alias + " -importcert -file " + alias + ".cert");
+ }
+
+ static void keytool(String cmd) throws Exception {
+ cmd = "-keystore tsks -storepass changeit -keypass changeit " +
+ "-keyalg rsa -validity 200 " + cmd;
+ sun.security.tools.keytool.Main.main(cmd.split(" "));
}
}
--- a/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -31,6 +31,7 @@
* @library /lib/testlibrary warnings
* @modules java.base/sun.security.pkcs
* java.base/sun.security.timestamp
+ * java.base/sun.security.tools.keytool
* java.base/sun.security.util
* java.base/sun.security.x509
* java.management
--- a/jdk/test/sun/security/tools/jarsigner/ts.sh Wed Oct 19 08:05:48 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-#
-# Copyright (c) 2007, 2013, 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 6543842 6543440 6939248 8009636 8024302
-# @summary checking response of timestamp
-# @modules java.base/sun.security.pkcs
-# java.base/sun.security.timestamp
-# java.base/sun.security.x509
-# java.base/sun.security.util
-#
-# @run shell/timeout=600 ts.sh
-
-# Run for a long time because jarsigner with timestamp needs to create a
-# 64-bit random number and it might be extremely slow on a machine with
-# not enough entropy pool
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
- Windows_* )
- FS="\\"
- ;;
- * )
- FS="/"
- ;;
-esac
-
-if [ "${TESTSRC}" = "" ] ; then
- TESTSRC="."
-fi
-if [ "${TESTJAVA}" = "" ] ; then
- JAVAC_CMD=`which javac`
- TESTJAVA=`dirname $JAVAC_CMD`/..
-fi
-
-JAR="${TESTJAVA}${FS}bin${FS}jar ${TESTTOOLVMOPTS}"
-JAVA="${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS}"
-JAVAC="${TESTJAVA}${FS}bin${FS}javac ${TESTTOOLVMOPTS} ${TESTJAVACOPTS}"
-KT="${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -keystore tsks -storepass changeit -keypass changeit -keyalg rsa -validity 200"
-
-rm tsks
-echo Nothing > A
-rm old.jar
-$JAR cvf old.jar A
-
-# ca is CA
-# old is signer for code
-# ts is signer for timestamp
-# tsbad1 has no extendedKeyUsage
-# tsbad2's extendedKeyUsage is non-critical
-# tsbad3's extendedKeyUsage has no timestamping
-
-$KT -alias ca -genkeypair -ext bc -dname CN=CA
-$KT -alias old -genkeypair -dname CN=old
-$KT -alias ts -genkeypair -dname CN=ts
-$KT -alias tsbad1 -genkeypair -dname CN=tsbad1
-$KT -alias tsbad2 -genkeypair -dname CN=tsbad2
-$KT -alias tsbad3 -genkeypair -dname CN=tsbad3
-
-$KT -alias old -certreq | \
- $KT -alias ca -gencert | \
- $KT -alias old -importcert
-$KT -alias ts -certreq | \
- $KT -alias ca -gencert -ext eku:critical=ts | \
- $KT -alias ts -importcert
-$KT -alias tsbad1 -certreq | \
- $KT -alias ca -gencert | \
- $KT -alias tsbad1 -importcert
-$KT -alias tsbad2 -certreq | \
- $KT -alias ca -gencert -ext eku=ts | \
- $KT -alias tsbad2 -importcert
-$KT -alias tsbad3 -certreq | \
- $KT -alias ca -gencert -ext eku:critical=cs | \
- $KT -alias tsbad3 -importcert
-
-EXTRAOPTS="--add-exports java.base/sun.security.pkcs=ALL-UNNAMED \
- --add-exports java.base/sun.security.timestamp=ALL-UNNAMED \
- --add-exports java.base/sun.security.x509=ALL-UNNAMED \
- --add-exports java.base/sun.security.util=ALL-UNNAMED"
-$JAVAC ${EXTRAOPTS} -d . ${TESTSRC}/TimestampCheck.java
-$JAVA ${TESTVMOPTS} ${EXTRAOPTS} "-Dtest.tool.vm.opts=${TESTTOOLVMOPTS}" TimestampCheck
-
--- a/jdk/test/tools/jlink/IntegrationTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/tools/jlink/IntegrationTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -37,14 +37,14 @@
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.JlinkConfiguration;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.ExecutableImage;
+import jdk.tools.jlink.internal.Jlink.JlinkConfiguration;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PostProcessor;
import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/JLinkToolProviderTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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.PrintWriter;
+import java.io.StringWriter;
+import java.security.AccessControlException;
+import java.util.spi.ToolProvider;
+
+/*
+ * @test
+ * @build JLinkToolProviderTest
+ * @run main/othervm/java.security.policy=toolprovider.policy JLinkToolProviderTest
+ */
+public class JLinkToolProviderTest {
+ static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+ .orElseThrow(() ->
+ new RuntimeException("jlink tool not found")
+ );
+
+ private static void checkJlinkOptions(String... options) {
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+
+ try {
+ JLINK_TOOL.run(pw, pw, options);
+ throw new AssertionError("SecurityException should have been thrown!");
+ } catch (AccessControlException ace) {
+ if (! ace.getPermission().getClass().getName().contains("JlinkPermission")) {
+ throw new AssertionError("expected JlinkPermission check failure");
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ checkJlinkOptions("--help");
+ checkJlinkOptions("--list-plugins");
+ }
+}
--- a/jdk/test/tools/jlink/SecurityTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/tools/jlink/SecurityTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -25,12 +25,12 @@
* @test
* @summary Test JlinkPermission
* @author Jean-Francois Denise
- * @modules jdk.jlink/jdk.tools.jlink
+ * @modules jdk.jlink/jdk.tools.jlink.internal
* @run main/othervm SecurityTest
*/
import java.security.AccessControlException;
-import jdk.tools.jlink.Jlink;
+import jdk.tools.jlink.internal.Jlink;
public class SecurityTest {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,340 @@
+/**
+ * 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
+ * @summary Test --no-man-pages and --no-header-files
+ * @library /lib/testlibrary
+ * @modules jdk.compiler
+ * jdk.jlink
+ * @build CompilerUtils
+ * @run testng ExcludeJmodSectionPluginTest
+ */
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.spi.ToolProvider;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+public class ExcludeJmodSectionPluginTest {
+ static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
+ .orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
+
+ static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+ .orElseThrow(() ->
+ new RuntimeException("jlink tool not found")
+ );
+
+ static final Path MODULE_PATH = Paths.get(System.getProperty("java.home"), "jmods");
+ static final Path SRC_DIR = Paths.get("src");
+ static final Path MODS_DIR = Paths.get("mods");
+ static final Path JMODS_DIR = Paths.get("jmods");
+ static final Path MAN_DIR = Paths.get("man");
+ static final Path INCLUDE_DIR = Paths.get("include");
+ static final Path IMAGES_DIR = Paths.get("images");
+
+ @BeforeTest
+ private void setup() throws Exception {
+ // build jmod files
+ JmodFileBuilder m1 = new JmodFileBuilder("m1");
+ m1.headerFile("m1a.h");
+ m1.headerFile("m1b.h");
+ m1.build();
+
+ JmodFileBuilder m2 = new JmodFileBuilder("m2");
+ m2.headerFile("m2.h");
+ m2.manPage("tool2.1");
+ m2.build();
+
+ JmodFileBuilder m3 = new JmodFileBuilder("m3");
+ m3.manPage("tool3.1");
+ m3.build();
+ }
+
+ private String imageDir(String dir) {
+ return IMAGES_DIR.resolve(dir).toString();
+ }
+
+
+ @DataProvider(name = "jlinkoptions")
+ public Object[][] jlinkoptions() {
+ // options and expected header files & man pages
+ return new Object[][] {
+ { new String [] {
+ "test1",
+ "--exclude-files=/java.base/include/**,/java.base/man/**",
+ },
+ List.of("include/m1a.h",
+ "include/m1b.h",
+ "include/m2.h",
+ "man/tool2.1",
+ "man/tool3.1")
+ },
+
+ { new String [] {
+ "test2",
+ "--no-man-pages",
+ "--no-header-files",
+ },
+ List.of()
+ },
+
+ { new String[] {
+ "test3",
+ "--no-header-files",
+ "--exclude-files=/java.base/man/**"
+ },
+ List.of("man/tool2.1",
+ "man/tool3.1") },
+
+ { new String [] {
+ "test4",
+ "--no-man-pages",
+ "--exclude-files=/java.base/include/**,/m2/include/**",
+ },
+ List.of("include/m1a.h",
+ "include/m1b.h")
+ },
+
+ { new String [] {
+ "test5",
+ "--no-header-files",
+ "--exclude-files=/java.base/man/**,/m2/man/**"
+ },
+ List.of("man/tool3.1")
+ },
+ };
+ }
+
+ @Test(dataProvider = "jlinkoptions")
+ public void test(String[] opts, List<String> expectedFiles) throws Exception {
+ if (Files.notExists(MODULE_PATH)) {
+ // exploded image
+ return;
+ }
+
+ String dir = opts[0];
+ List<String> options = new ArrayList<>();
+ for (int i = 1; i < opts.length; i++) {
+ options.add(opts[i]);
+ }
+
+ String mpath = MODULE_PATH.toString() + File.pathSeparator +
+ JMODS_DIR.toString();
+ Stream.of("--module-path", mpath,
+ "--add-modules", "m1,m2,m3",
+ "--output", imageDir(dir))
+ .forEach(options::add);
+
+ Path image = createImage(dir, options, expectedFiles);
+
+ // check if any unexpected header file or man page
+ Set<Path> extraFiles = Files.walk(image, Integer.MAX_VALUE)
+ .filter(p -> Files.isRegularFile(p))
+ .filter(p -> p.getParent().endsWith("include") ||
+ p.getParent().endsWith("man"))
+ .filter(p -> {
+ String fn = String.format("%s/%s",
+ p.getParent().getFileName().toString(),
+ p.getFileName().toString());
+ return !expectedFiles.contains(fn);
+ })
+ .collect(Collectors.toSet());
+
+ if (extraFiles.size() > 0) {
+ System.out.println("Unexpected files: " + extraFiles.toString());
+ assertTrue(extraFiles.isEmpty());
+ }
+ }
+
+ /**
+ * Test java.base's include header files
+ */
+ @Test
+ public void testJavaBase() {
+ if (Files.notExists(MODULE_PATH)) {
+ // exploded image
+ return;
+ }
+ List<String> options = List.of("--module-path",
+ MODULE_PATH.toString(),
+ "--add-modules", "java.base",
+ "--output", imageDir("base"));
+ createImage("base", options,
+ List.of("include/jni.h", "include/jvmti.h"));
+
+ }
+
+ private Path createImage(String outputDir, List<String> options,
+ List<String> expectedFiles) {
+ System.out.println("jlink " + options.toString());
+ int rc = JLINK_TOOL.run(System.out, System.out,
+ options.toArray(new String[0]));
+ assertTrue(rc == 0);
+
+ Path d = IMAGES_DIR.resolve(outputDir);
+ for (String fn : expectedFiles) {
+ Path path = d.resolve(fn);
+ if (Files.notExists(path)) {
+ throw new RuntimeException(path + " not found");
+ }
+ }
+ return d;
+ }
+
+ private void deleteDirectory(Path dir) throws IOException {
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException
+ {
+ Files.delete(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+ throws IOException
+ {
+ Files.delete(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+
+ /**
+ * Builder to create JMOD file
+ */
+ class JmodFileBuilder {
+
+ final String name;
+ final Set<String> manPages = new HashSet<>();
+ final Set<String> headerFiles = new HashSet<>();
+
+ JmodFileBuilder(String name) throws IOException {
+ this.name = name;
+
+ Path msrc = SRC_DIR.resolve(name);
+ if (Files.exists(msrc)) {
+ deleteDirectory(msrc);
+ }
+ }
+
+ JmodFileBuilder manPage(String filename) {
+ manPages.add(filename);
+ return this;
+ }
+
+ JmodFileBuilder headerFile(String filename) {
+ headerFiles.add(filename);
+ return this;
+ }
+
+ Path build() throws IOException {
+ compileModule();
+ // create man pages
+ Path mdir = MAN_DIR.resolve(name);
+ for (String filename : manPages) {
+ Files.createDirectories(mdir);
+ Files.createFile(mdir.resolve(filename));
+ }
+ // create header files
+ mdir = INCLUDE_DIR.resolve(name);
+ for (String filename : headerFiles) {
+ Files.createDirectories(mdir);
+ Files.createFile(mdir.resolve(filename));
+ }
+ return createJmodFile();
+ }
+
+ void compileModule() throws IOException {
+ Path msrc = SRC_DIR.resolve(name);
+ Files.createDirectories(msrc);
+ Path minfo = msrc.resolve("module-info.java");
+ try (BufferedWriter bw = Files.newBufferedWriter(minfo);
+ PrintWriter writer = new PrintWriter(bw)) {
+ writer.format("module %s { }%n", name);
+ }
+
+ assertTrue(CompilerUtils.compile(msrc, MODS_DIR,
+ "--module-source-path",
+ SRC_DIR.toString()));
+ }
+
+ Path createJmodFile() throws IOException {
+ Path mclasses = MODS_DIR.resolve(name);
+ Files.createDirectories(JMODS_DIR);
+ Path outfile = JMODS_DIR.resolve(name + ".jmod");
+ List<String> args = new ArrayList<>();
+ args.add("create");
+ // add classes
+ args.add("--class-path");
+ args.add(mclasses.toString());
+ // man pages
+ if (manPages.size() > 0) {
+ args.add("--man-pages");
+ args.add(MAN_DIR.resolve(name).toString());
+ }
+ // header files
+ if (headerFiles.size() > 0) {
+ args.add("--header-files");
+ args.add(INCLUDE_DIR.resolve(name).toString());
+ }
+ args.add(outfile.toString());
+
+ if (Files.exists(outfile))
+ Files.delete(outfile);
+
+ System.out.println("jmod " +
+ args.stream().collect(Collectors.joining(" ")));
+
+ int rc = JMOD_TOOL.run(System.out, System.out,
+ args.toArray(new String[args.size()]));
+ if (rc != 0) {
+ throw new AssertionError("jmod failed: rc = " + rc);
+ }
+ return outfile;
+ }
+ }
+}
--- a/jdk/test/tools/jlink/plugins/LastSorterTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/tools/jlink/plugins/LastSorterTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -37,11 +37,11 @@
import java.util.Map;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.ImagePluginStack;
+import jdk.tools.jlink.internal.Jlink;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
-import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- a/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -36,11 +36,11 @@
import java.util.Map;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.Jlink;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- a/jdk/test/tools/jlink/plugins/PrevisitorTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/jdk/test/tools/jlink/plugins/PrevisitorTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -40,13 +40,13 @@
import java.util.stream.Collectors;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/toolprovider.policy Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,2 @@
+grant {
+};
--- a/langtools/.hgtags Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/.hgtags Thu Oct 27 08:52:00 2016 -0700
@@ -383,3 +383,4 @@
90dd93e668a521642382561c47abe96ee2e065b7 jdk-9+138
17a82cb0e4b480e97021691d39917f15e3f7b653 jdk-9+139
6842e63d6c3971172214b411f29965852ca175d1 jdk-9+140
+296c875051187918f8f3f87e9432036d13013d39 jdk-9+141
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -113,7 +113,7 @@
* Internal compiler flags (no bits in the lower 16).
*****************************************/
- /** Flag is set if symbol is deprecated.
+ /** Flag is set if symbol is deprecated. See also DEPRECATED_REMOVAL.
*/
public static final int DEPRECATED = 1<<17;
@@ -293,6 +293,11 @@
*/
public static final long SYSTEM_MODULE = 1L<<53;
+ /**
+ * Flag to indicate the given symbol has been deprecated and marked for removal.
+ */
+ public static final long DEPRECATED_REMOVAL = 1L<<54;
+
/** Modifier masks.
*/
public static final int
@@ -402,7 +407,8 @@
THROWS(Flags.THROWS),
LAMBDA_METHOD(Flags.LAMBDA_METHOD),
TYPE_TRANSLATED(Flags.TYPE_TRANSLATED),
- MODULE(Flags.MODULE);
+ MODULE(Flags.MODULE),
+ DEPRECATED_REMOVAL(Flags.DEPRECATED_REMOVAL);
Flag(long flag) {
this.value = flag;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Thu Oct 27 08:52:00 2016 -0700
@@ -25,11 +25,13 @@
package com.sun.tools.javac.code;
+import java.util.Arrays;
import java.util.EnumSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Options;
@@ -81,12 +83,13 @@
}
/**
- * Returns a new Lint that has the given LintCategory suppressed.
+ * Returns a new Lint that has the given LintCategorys suppressed.
+ * @param lc one or more categories to be suppressed
*/
- public Lint suppress(LintCategory lc) {
+ public Lint suppress(LintCategory... lc) {
Lint l = new Lint(this);
- l.values.remove(lc);
- l.suppressedValues.add(lc);
+ l.values.removeAll(Arrays.asList(lc));
+ l.suppressedValues.addAll(Arrays.asList(lc));
return l;
}
@@ -100,10 +103,31 @@
protected Lint(Context context) {
// initialize values according to the lint options
Options options = Options.instance(context);
- values = EnumSet.noneOf(LintCategory.class);
- for (Map.Entry<String, LintCategory> e: map.entrySet()) {
- if (options.lint(e.getKey()))
- values.add(e.getValue());
+
+ if (options.isSet(Option.XLINT) || options.isSet(Option.XLINT_CUSTOM, "all")) {
+ // If -Xlint or -Xlint:all is given, enable all categories by default
+ values = EnumSet.allOf(LintCategory.class);
+ } else if (options.isSet(Option.XLINT_CUSTOM, "none")) {
+ // if -Xlint:none is given, disable all categories by default
+ values = EnumSet.noneOf(LintCategory.class);
+ } else {
+ // otherwise, enable on-by-default categories
+ values = EnumSet.noneOf(LintCategory.class);
+
+ Source source = Source.instance(context);
+ if (source.compareTo(Source.JDK1_9) >= 0) {
+ values.add(LintCategory.DEP_ANN);
+ }
+ values.add(LintCategory.REMOVAL);
+ }
+
+ // Look for specific overrides
+ for (LintCategory lc : LintCategory.values()) {
+ if (options.isSet(Option.XLINT_CUSTOM, lc.option)) {
+ values.add(lc);
+ } else if (options.isSet(Option.XLINT_CUSTOM, "-" + lc.option)) {
+ values.remove(lc);
+ }
}
suppressedValues = EnumSet.noneOf(LintCategory.class);
@@ -213,6 +237,11 @@
RAW("rawtypes"),
/**
+ * Warn about use of deprecated-for-removal items.
+ */
+ REMOVAL("removal"),
+
+ /**
* Warn about Serializable classes that do not provide a serial version ID.
*/
SERIAL("serial"),
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Thu Oct 27 08:52:00 2016 -0700
@@ -359,6 +359,10 @@
return (flags_field & DEPRECATED) != 0;
}
+ public boolean isDeprecatedForRemoval() {
+ return (flags_field & DEPRECATED_REMOVAL) != 0;
+ }
+
public boolean isDeprecatableViaAnnotation() {
switch (getKind()) {
case LOCAL_VARIABLE:
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -340,6 +340,13 @@
&& toAnnotate.owner.kind != MTH
&& types.isSameType(c.type, syms.deprecatedType)) {
toAnnotate.flags_field |= Flags.DEPRECATED;
+ Attribute fr = c.member(names.forRemoval);
+ if (fr instanceof Attribute.Constant) {
+ Attribute.Constant v = (Attribute.Constant) fr;
+ if (v.type == syms.booleanType && ((Integer) v.value) != 0) {
+ toAnnotate.flags_field |= Flags.DEPRECATED_REMOVAL;
+ }
+ }
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Oct 27 08:52:00 2016 -0700
@@ -2398,6 +2398,7 @@
try {
if (needsRecovery && isSerializable(pt())) {
localEnv.info.isSerializable = true;
+ localEnv.info.isLambda = true;
}
List<Type> explicitParamTypes = null;
if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
@@ -2969,7 +2970,7 @@
}
if (isTargetSerializable) {
- chk.checkElemAccessFromSerializableLambda(that);
+ chk.checkAccessFromSerializableElement(that, true);
}
}
@@ -3364,7 +3365,7 @@
}
if (env.info.isSerializable) {
- chk.checkElemAccessFromSerializableLambda(tree);
+ chk.checkAccessFromSerializableElement(tree, env.info.isLambda);
}
result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo);
@@ -3507,7 +3508,7 @@
}
if (env.info.isSerializable) {
- chk.checkElemAccessFromSerializableLambda(tree);
+ chk.checkAccessFromSerializableElement(tree, env.info.isLambda);
}
env.info.selectSuper = selectSuperPrev;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -56,10 +56,15 @@
*/
boolean selectSuper = false;
- /** Is the current target of lambda expression or method reference serializable?
+ /** Is the current target of lambda expression or method reference serializable or is this a
+ * serializable class?
*/
boolean isSerializable = false;
+ /** Is this a lambda environment?
+ */
+ boolean isLambda = false;
+
/** Is this a speculative attribution environment?
*/
boolean isSpeculative = false;
@@ -117,6 +122,7 @@
info.returnResult = returnResult;
info.defaultSuperCallSite = defaultSuperCallSite;
info.isSerializable = isSerializable;
+ info.isLambda = isLambda;
info.isSpeculative = isSpeculative;
info.isAnonymousDiamond = isAnonymousDiamond;
info.isNewClass = isNewClass;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Thu Oct 27 08:52:00 2016 -0700
@@ -87,7 +87,7 @@
private final JavaFileManager fileManager;
private final Source source;
private final Profile profile;
- private final boolean warnOnAccessToSensitiveMembers;
+ private final boolean warnOnAnyAccessToMembers;
// The set of lint options currently in effect. It is initialized
// from the context, and then is set/reset as needed by Attr as it
@@ -131,7 +131,7 @@
allowStrictMethodClashCheck = source.allowStrictMethodClashCheck();
allowPrivateSafeVarargs = source.allowPrivateSafeVarargs();
allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation();
- warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers");
+ warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers");
Target target = Target.instance(context);
syntheticNameChar = target.syntheticNameChar();
@@ -139,11 +139,14 @@
profile = Profile.instance(context);
boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
+ boolean verboseRemoval = lint.isEnabled(LintCategory.REMOVAL);
boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
boolean enforceMandatoryWarnings = true;
deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated,
enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
+ removalHandler = new MandatoryWarningHandler(log, verboseRemoval,
+ enforceMandatoryWarnings, "removal", LintCategory.REMOVAL);
uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked,
enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
sunApiHandler = new MandatoryWarningHandler(log, false,
@@ -185,6 +188,10 @@
*/
private MandatoryWarningHandler deprecationHandler;
+ /** A handler for messages about deprecated-for-removal usage.
+ */
+ private MandatoryWarningHandler removalHandler;
+
/** A handler for messages about unchecked or unsafe usage.
*/
private MandatoryWarningHandler uncheckedHandler;
@@ -218,8 +225,13 @@
* @param sym The deprecated symbol.
*/
void warnDeprecated(DiagnosticPosition pos, Symbol sym) {
- if (!lint.isSuppressed(LintCategory.DEPRECATION))
+ if (sym.isDeprecatedForRemoval()) {
+ if (!lint.isSuppressed(LintCategory.REMOVAL)) {
+ removalHandler.report(pos, "has.been.deprecated.for.removal", sym, sym.location());
+ }
+ } else if (!lint.isSuppressed(LintCategory.DEPRECATION)) {
deprecationHandler.report(pos, "has.been.deprecated", sym, sym.location());
+ }
}
/** Warn about unchecked operation.
@@ -257,6 +269,7 @@
*/
public void reportDeferredDiagnostics() {
deprecationHandler.reportDeferredDiagnostic();
+ removalHandler.reportDeferredDiagnostic();
uncheckedHandler.reportDeferredDiagnostic();
sunApiHandler.reportDeferredDiagnostic();
}
@@ -2605,8 +2618,11 @@
}
}
- void checkElemAccessFromSerializableLambda(final JCTree tree) {
- if (warnOnAccessToSensitiveMembers) {
+ void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) {
+ if (warnOnAnyAccessToMembers ||
+ (lint.isEnabled(LintCategory.SERIAL) &&
+ !lint.isSuppressed(LintCategory.SERIAL) &&
+ isLambda)) {
Symbol sym = TreeInfo.symbol(tree);
if (!sym.kind.matches(KindSelector.VAL_MTH)) {
return;
@@ -2622,9 +2638,16 @@
}
if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
- isEffectivelyNonPublic(sym)) {
- log.warning(tree.pos(),
- "access.to.sensitive.member.from.serializable.element", sym);
+ isEffectivelyNonPublic(sym)) {
+ if (isLambda) {
+ if (belongsToRestrictedPackage(sym)) {
+ log.warning(LintCategory.SERIAL, tree.pos(),
+ "access.to.member.from.serializable.lambda", sym);
+ }
+ } else {
+ log.warning(tree.pos(),
+ "access.to.member.from.serializable.element", sym);
+ }
}
}
}
@@ -2643,6 +2666,14 @@
return false;
}
+ private boolean belongsToRestrictedPackage(Symbol sym) {
+ String fullName = sym.packge().fullname.toString();
+ return fullName.startsWith("java.") ||
+ fullName.startsWith("javax.") ||
+ fullName.startsWith("sun.") ||
+ fullName.contains(".internal.");
+ }
+
/** Report a conflict between a user symbol and a synthetic symbol.
*/
private void syntheticError(DiagnosticPosition pos, Symbol sym) {
@@ -3212,9 +3243,9 @@
}
void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
- if ((s.flags() & DEPRECATED) != 0 &&
- (other.flags() & DEPRECATED) == 0 &&
- s.outermostClass() != other.outermostClass()) {
+ if ( (s.isDeprecatedForRemoval()
+ || s.isDeprecated() && !other.isDeprecated())
+ && s.outermostClass() != other.outermostClass()) {
deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
@Override
public void report() {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Thu Oct 27 08:52:00 2016 -0700
@@ -29,6 +29,7 @@
import java.util.HashMap;
+import com.sun.source.tree.LambdaExpressionTree.BodyKind;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.tree.*;
@@ -224,7 +225,7 @@
diagHandler = new Log.DiscardDiagnosticHandler(log);
}
try {
- new AliveAnalyzer().analyzeTree(env, that, make);
+ new LambdaAliveAnalyzer().analyzeTree(env, that, make);
} finally {
if (!speculative) {
log.popDiagnosticHandler(diagHandler);
@@ -241,19 +242,7 @@
//related errors, which will allow for more errors to be detected
Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
try {
- new AssignAnalyzer() {
- WriteableScope enclosedSymbols = WriteableScope.create(env.enclClass.sym);
- @Override
- public void visitVarDef(JCVariableDecl tree) {
- enclosedSymbols.enter(tree.sym);
- super.visitVarDef(tree);
- }
- @Override
- protected boolean trackable(VarSymbol sym) {
- return enclosedSymbols.includes(sym) &&
- sym.owner.kind == MTH;
- }
- }.analyzeTree(env, that);
+ new LambdaAssignAnalyzer(env).analyzeTree(env, that);
LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
flowAnalyzer.analyzeTree(env, that, make);
return flowAnalyzer.inferredThrownTypes;
@@ -1341,6 +1330,79 @@
}
/**
+ * Specialized pass that performs reachability analysis on a lambda
+ */
+ class LambdaAliveAnalyzer extends AliveAnalyzer {
+
+ boolean inLambda;
+
+ @Override
+ public void visitReturn(JCReturn tree) {
+ //ignore lambda return expression (which might not even be attributed)
+ recordExit(new PendingExit(tree));
+ }
+
+ @Override
+ public void visitLambda(JCLambda tree) {
+ if (inLambda || tree.getBodyKind() == BodyKind.EXPRESSION) {
+ return;
+ }
+ inLambda = true;
+ try {
+ super.visitLambda(tree);
+ } finally {
+ inLambda = false;
+ }
+ }
+
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ //skip
+ }
+ }
+
+ /**
+ * Specialized pass that performs DA/DU on a lambda
+ */
+ class LambdaAssignAnalyzer extends AssignAnalyzer {
+ WriteableScope enclosedSymbols;
+ boolean inLambda;
+
+ LambdaAssignAnalyzer(Env<AttrContext> env) {
+ enclosedSymbols = WriteableScope.create(env.enclClass.sym);
+ }
+
+ @Override
+ public void visitLambda(JCLambda tree) {
+ if (inLambda) {
+ return;
+ }
+ inLambda = true;
+ try {
+ super.visitLambda(tree);
+ } finally {
+ inLambda = false;
+ }
+ }
+
+ @Override
+ public void visitVarDef(JCVariableDecl tree) {
+ enclosedSymbols.enter(tree.sym);
+ super.visitVarDef(tree);
+ }
+ @Override
+ protected boolean trackable(VarSymbol sym) {
+ return enclosedSymbols.includes(sym) &&
+ sym.owner.kind == MTH;
+ }
+
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ //skip
+ }
+ }
+
+ /**
* Specialized pass that performs inference of thrown types for lambdas.
*/
class LambdaFlowAnalyzer extends FlowAnalyzer {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -103,7 +103,6 @@
private final TypeAnnotations typeAnnotations;
private final Types types;
private final JCDiagnostic.Factory diags;
- private final Source source;
private final DeferredLintHandler deferredLintHandler;
private final Lint lint;
private final TypeEnvs typeEnvs;
@@ -131,7 +130,6 @@
typeAnnotations = TypeAnnotations.instance(context);
types = Types.instance(context);
diags = JCDiagnostic.Factory.instance(context);
- source = Source.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
lint = Lint.instance(context);
typeEnvs = TypeEnvs.instance(context);
@@ -178,6 +176,7 @@
/** Complete entering a class.
* @param sym The symbol of the class to be completed.
*/
+ @Override
public void complete(Symbol sym) throws CompletionFailure {
// Suppress some (recursive) MemberEnter invocations
if (!completionEnabled) {
@@ -414,7 +413,7 @@
Type attribImportType(JCTree tree, Env<AttrContext> env) {
Assert.check(completionEnabled);
Lint prevLint = chk.setLint(allowDeprecationOnImport ?
- lint : lint.suppress(LintCategory.DEPRECATION));
+ lint : lint.suppress(LintCategory.DEPRECATION, LintCategory.REMOVAL));
try {
// To prevent deep recursion, suppress completion of some
// types.
@@ -751,12 +750,12 @@
// can attribute the annotation types and then check to see if the
// @Deprecated annotation is present.
attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
- if (hasDeprecatedAnnotation(tree.mods.annotations))
- sym.flags_field |= DEPRECATED;
+ handleDeprecatedAnnotation(tree.mods.annotations, sym);
chk.checkNonCyclicDecl(tree);
}
//where:
+ @Override
protected JCExpression clearTypeParams(JCExpression superType) {
switch (superType.getTag()) {
case TYPEAPPLY:
@@ -767,16 +766,29 @@
}
/**
- * Check if a list of annotations contains a reference to
- * java.lang.Deprecated.
+ * If a list of annotations contains a reference to java.lang.Deprecated,
+ * set the DEPRECATED flag.
+ * If the annotation is marked forRemoval=true, also set DEPRECATED_REMOVAL.
**/
- private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
+ private void handleDeprecatedAnnotation(List<JCAnnotation> annotations, Symbol sym) {
for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
JCAnnotation a = al.head;
- if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
- return true;
+ if (a.annotationType.type == syms.deprecatedType) {
+ sym.flags_field |= Flags.DEPRECATED;
+ a.args.stream()
+ .filter(e -> e.hasTag(ASSIGN))
+ .map(e -> (JCAssign) e)
+ .filter(assign -> TreeInfo.name(assign.lhs) == names.forRemoval)
+ .findFirst()
+ .ifPresent(assign -> {
+ JCExpression rhs = TreeInfo.skipParens(assign.rhs);
+ if (rhs.hasTag(LITERAL)
+ && Boolean.TRUE.equals(((JCLiteral) rhs).getValue())) {
+ sym.flags_field |= DEPRECATED_REMOVAL;
+ }
+ });
+ }
}
- return false;
}
@Override
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java Thu Oct 27 08:52:00 2016 -0700
@@ -52,8 +52,6 @@
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
-import com.sun.tools.javac.code.Lint;
-import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
@@ -85,7 +83,10 @@
log = Log.instance(context);
options = Options.instance(context);
classLoaderClass = options.get("procloader");
- locations.update(log, Lint.instance(context), FSInfo.instance(context));
+
+ // Avoid initializing Lint
+ boolean warn = options.isLintSet("path");
+ locations.update(log, warn, FSInfo.instance(context));
// Setting this option is an indication that close() should defer actually closing
// the file manager until after a specified period of inactivity.
@@ -171,14 +172,6 @@
private long lastUsedTime = System.currentTimeMillis();
protected long deferredCloseTimeout = 0;
- protected Source getSource() {
- String sourceName = options.get(Option.SOURCE);
- Source source = null;
- if (sourceName != null)
- source = Source.lookup(sourceName);
- return (source != null ? source : Source.DEFAULT);
- }
-
protected ClassLoader getClassLoader(URL[] urls) {
ClassLoader thisClassLoader = getClass().getClassLoader();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Thu Oct 27 08:52:00 2016 -0700
@@ -42,7 +42,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.ProviderNotFoundException;
-import java.nio.file.spi.FileSystemProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -63,7 +62,6 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import java.util.zip.ZipFile;
import javax.lang.model.SourceVersion;
import javax.tools.JavaFileManager;
@@ -159,10 +157,9 @@
}
}
- // could replace Lint by "boolean warn"
- void update(Log log, Lint lint, FSInfo fsInfo) {
+ void update(Log log, boolean warn, FSInfo fsInfo) {
this.log = log;
- warn = lint.isEnabled(Lint.LintCategory.PATH);
+ this.warn = warn;
this.fsInfo = fsInfo;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Oct 27 08:52:00 2016 -0700
@@ -1460,7 +1460,6 @@
ListBuffer<CompoundAnnotationProxy> proxies = new ListBuffer<>();
for (int i = 0; i<numAttributes; i++) {
CompoundAnnotationProxy proxy = readCompoundAnnotation();
-
if (proxy.type.tsym == syms.proprietaryType.tsym)
sym.flags_field |= PROPRIETARY;
else if (proxy.type.tsym == syms.profileType.tsym) {
@@ -1479,6 +1478,16 @@
target = proxy;
} else if (proxy.type.tsym == syms.repeatableType.tsym) {
repeatable = proxy;
+ } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
+ sym.flags_field |= DEPRECATED;
+ for (Pair<Name, Attribute> v : proxy.values) {
+ if (v.fst == names.forRemoval && v.snd instanceof Attribute.Constant) {
+ Attribute.Constant c = (Attribute.Constant) v.snd;
+ if (c.type == syms.booleanType && ((Integer) c.value) != 0) {
+ sym.flags_field |= DEPRECATED_REMOVAL;
+ }
+ }
+ }
}
proxies.append(proxy);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Thu Oct 27 08:52:00 2016 -0700
@@ -37,6 +37,7 @@
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.ServiceLoader;
@@ -111,7 +112,6 @@
"all",
log.localize(PrefixKind.JAVAC, "opt.Xlint.all")));
for (LintCategory lc : LintCategory.values()) {
- if (lc.hidden) continue;
log.printRawLines(WriterKind.STDOUT,
String.format(LINT_KEY_FORMAT,
lc.option,
@@ -801,8 +801,8 @@
/** The kind of choices for this option, if any. */
private final ChoiceKind choiceKind;
- /** The choices for this option, if any, and whether or not the choices are hidden. */
- private final Map<String,Boolean> choices;
+ /** The choices for this option, if any. */
+ private final Set<String> choices;
/**
* Looks up the first option matching the given argument in the full set of options.
@@ -815,7 +815,8 @@
/**
* Looks up the first option matching the given argument within a set of options.
- * @param arg the argument to be matches
+ * @param arg the argument to be matched
+ * @param options the set of possible options
* @return the first option that matches, or null if none.
*/
public static Option lookup(String arg, Set<Option> options) {
@@ -867,7 +868,7 @@
}
Option(String text, String argsNameKey, String descrKey, OptionKind kind, OptionGroup group,
- ChoiceKind choiceKind, Map<String,Boolean> choices) {
+ ChoiceKind choiceKind, Set<String> choices) {
this(text, argsNameKey, descrKey, kind, group, choiceKind, choices, ArgKind.REQUIRED);
}
@@ -875,19 +876,12 @@
OptionKind kind, OptionGroup group,
ChoiceKind choiceKind, String... choices) {
this(text, null, descrKey, kind, group, choiceKind,
- createChoices(choices), ArgKind.REQUIRED);
+ new LinkedHashSet<>(Arrays.asList(choices)), ArgKind.REQUIRED);
}
- // where
- private static Map<String,Boolean> createChoices(String... choices) {
- Map<String,Boolean> map = new LinkedHashMap<>();
- for (String c: choices)
- map.put(c, false);
- return map;
- }
private Option(String text, String argsNameKey, String descrKey,
OptionKind kind, OptionGroup group,
- ChoiceKind choiceKind, Map<String,Boolean> choices,
+ ChoiceKind choiceKind, Set<String> choices,
ArgKind argKind) {
this.names = text.trim().split("\\s+");
Assert.check(names.length >= 1);
@@ -943,10 +937,10 @@
if (choices != null) {
String arg = option.substring(name.length());
if (choiceKind == ChoiceKind.ONEOF)
- return choices.keySet().contains(arg);
+ return choices.contains(arg);
else {
for (String a: arg.split(",+")) {
- if (!choices.keySet().contains(a))
+ if (!choices.contains(a))
return false;
}
}
@@ -1016,7 +1010,7 @@
if (choices != null) {
if (choiceKind == ChoiceKind.ONEOF) {
// some clients like to see just one of option+choice set
- for (String s: choices.keySet())
+ for (String s : choices)
helper.remove(primaryName + s);
String opt = primaryName + arg;
helper.put(opt, opt);
@@ -1113,12 +1107,10 @@
if (argsNameKey == null) {
if (choices != null) {
String sep = "{";
- for (Map.Entry<String,Boolean> e: choices.entrySet()) {
- if (!e.getValue()) {
- sb.append(sep);
- sb.append(e.getKey());
- sep = ",";
- }
+ for (String choice : choices) {
+ sb.append(sep);
+ sb.append(choices);
+ sep = ",";
}
sb.append("}");
}
@@ -1163,14 +1155,14 @@
}
}
- private static Map<String,Boolean> getXLintChoices() {
- Map<String,Boolean> choices = new LinkedHashMap<>();
- choices.put("all", false);
- for (Lint.LintCategory c : Lint.LintCategory.values())
- choices.put(c.option, c.hidden);
- for (Lint.LintCategory c : Lint.LintCategory.values())
- choices.put("-" + c.option, c.hidden);
- choices.put("none", false);
+ private static Set<String> getXLintChoices() {
+ Set<String> choices = new LinkedHashSet<>();
+ choices.add("all");
+ for (Lint.LintCategory c : Lint.LintCategory.values()) {
+ choices.add(c.option);
+ choices.add("-" + c.option);
+ }
+ choices.add("none");
return choices;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Oct 27 08:52:00 2016 -0700
@@ -1321,14 +1321,31 @@
Some input files additionally use or override a deprecated API.
# 0: file name
+compiler.note.removal.filename=\
+ {0} uses or overrides a deprecated API that is marked for removal.
+
+compiler.note.removal.plural=\
+ Some input files use or override a deprecated API that is marked for removal.
+
+# The following string may appear after one of the above removal messages.
+compiler.note.removal.recompile=\
+ Recompile with -Xlint:removal for details.
+
+# 0: file name
+compiler.note.removal.filename.additional=\
+ {0} has additional uses or overrides of a deprecated API that is marked for removal.
+
+compiler.note.removal.plural.additional=\
+ Some input files additionally use or override a deprecated API that is marked for removal.
+
+# 0: file name
compiler.note.unchecked.filename=\
{0} uses unchecked or unsafe operations.
compiler.note.unchecked.plural=\
Some input files use unchecked or unsafe operations.
-# The following string may appear after one of the above deprecation
-# messages.
+# The following string may appear after one of the above unchecked messages.
compiler.note.unchecked.recompile=\
Recompile with -Xlint:unchecked for details.
@@ -1441,6 +1458,10 @@
compiler.warn.has.been.deprecated=\
{0} in {1} has been deprecated
+# 0: symbol, 1: symbol
+compiler.warn.has.been.deprecated.for.removal=\
+ {0} in {1} has been deprecated and marked for removal
+
# 0: symbol
compiler.warn.sun.proprietary=\
{0} is internal proprietary API and may be removed in a future release
@@ -1712,8 +1733,12 @@
Redundant {0} annotation. {1}
# 0: symbol
-compiler.warn.access.to.sensitive.member.from.serializable.element=\
- access to sensitive member {0} from serializable element can be publicly accessible to untrusted code
+compiler.warn.access.to.member.from.serializable.element=\
+ access to member {0} from serializable element can be publicly accessible to untrusted code
+
+# 0: symbol
+compiler.warn.access.to.member.from.serializable.lambda=\
+ access to member {0} from serializable lambda can be publicly accessible to untrusted code
#####
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties Thu Oct 27 08:52:00 2016 -0700
@@ -219,8 +219,12 @@
javac.opt.Xlint.desc.rawtypes=\
Warn about use of raw types.
+javac.opt.Xlint.desc.removal=\
+ Warn about use of API that has been marked for removal.
+
javac.opt.Xlint.desc.serial=\
- Warn about Serializable classes that do not provide a serial version ID.
+ Warn about Serializable classes that do not provide a serial version ID. \n\
+\ Also warn about access to non-public members from a serializable element.
javac.opt.Xlint.desc.static=\
Warn about accessing a static member using an instance.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -87,6 +87,7 @@
public final Name family;
public final Name finalize;
public final Name forName;
+ public final Name forRemoval;
public final Name getClass;
public final Name getClassLoader;
public final Name getComponentType;
@@ -242,6 +243,7 @@
family = fromString("family");
finalize = fromString("finalize");
forName = fromString("forName");
+ forRemoval = fromString("forRemoval");
getClass = fromString("getClass");
getClassLoader = fromString("getClassLoader");
getComponentType = fromString("getComponentType");
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Options.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Options.java Thu Oct 27 08:52:00 2016 -0700
@@ -27,7 +27,6 @@
import java.util.*;
-import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.main.Option;
import static com.sun.tools.javac.main.Option.*;
@@ -113,6 +112,18 @@
return (values.get(option.primaryName + value) != null);
}
+ /** Check if the value for a lint option has been explicitly set, either with -Xlint:opt
+ * or if all lint options have enabled and this one not disabled with -Xlint:-opt.
+ */
+ public boolean isLintSet(String s) {
+ // return true if either the specific option is enabled, or
+ // they are all enabled without the specific one being
+ // disabled
+ return
+ isSet(XLINT_CUSTOM, s) ||
+ (isSet(XLINT) || isSet(XLINT_CUSTOM, "all")) && isUnset(XLINT_CUSTOM, "-" + s);
+ }
+
/**
* Check if the value for an undocumented option has not been set.
*/
@@ -170,25 +181,4 @@
for (Runnable r: listeners)
r.run();
}
-
- /** Check for a lint suboption. */
- public boolean lint(String s) {
- // return true if either the specific option is enabled, or
- // they are all enabled without the specific one being
- // disabled
- return
- isSet(XLINT_CUSTOM, s) ||
- (isSet(XLINT) || isSet(XLINT_CUSTOM, "all") || (s.equals("dep-ann") && depAnnOnByDefault())) &&
- isUnset(XLINT_CUSTOM, "-" + s);
- }
- // where
- private boolean depAnnOnByDefault() {
- String sourceName = get(Option.SOURCE);
- Source source = null;
- if (sourceName != null)
- source = Source.lookup(sourceName);
- if (source == null)
- source = Source.DEFAULT;
- return source.compareTo(Source.JDK1_9) >= 0;
- }
}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Thu Oct 27 08:52:00 2016 -0700
@@ -353,11 +353,12 @@
protected Content getFramesJavaScript() {
HtmlTree script = HtmlTree.SCRIPT();
String scriptCode = DocletConstants.NL +
- " targetPage = \"\" + window.location.search;" + DocletConstants.NL +
- " if (targetPage != \"\" && targetPage != \"undefined\")" + DocletConstants.NL +
- " targetPage = targetPage.substring(1);" + DocletConstants.NL +
- " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + DocletConstants.NL +
- " targetPage = \"undefined\";" + DocletConstants.NL +
+ " tmpTargetPage = \"\" + window.location.search;" + DocletConstants.NL +
+ " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")" + DocletConstants.NL +
+ " tmpTargetPage = tmpTargetPage.substring(1);" + DocletConstants.NL +
+ " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))" + DocletConstants.NL +
+ " tmpTargetPage = \"undefined\";" + DocletConstants.NL +
+ " targetPage = tmpTargetPage;" + DocletConstants.NL +
" function validURL(url) {" + DocletConstants.NL +
" try {" + DocletConstants.NL +
" url = decodeURIComponent(url);" + DocletConstants.NL +
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlWriter.java Thu Oct 27 08:52:00 2016 -0700
@@ -234,11 +234,12 @@
protected Content getFramesJavaScript() {
HtmlTree scriptTree = HtmlTree.SCRIPT();
String scriptCode = "\n" +
- " targetPage = \"\" + window.location.search;\n" +
- " if (targetPage != \"\" && targetPage != \"undefined\")\n" +
- " targetPage = targetPage.substring(1);\n" +
- " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n" +
- " targetPage = \"undefined\";\n" +
+ " tmpTargetPage = \"\" + window.location.search;\n" +
+ " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n" +
+ " tmpTargetPage = tmpTargetPage.substring(1);\n" +
+ " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n" +
+ " tmpTargetPage = \"undefined\";\n" +
+ " targetPage = tmpTargetPage;\n" +
" function validURL(url) {\n" +
" try {\n" +
" url = decodeURIComponent(url);\n" +
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Thu Oct 27 08:52:00 2016 -0700
@@ -308,9 +308,7 @@
public CommentUtils cmtUtils;
/**
- * A sorted set of packages specified on the command-line merged with a
- * collection of packages that contain the classes specified on the
- * command-line.
+ * A sorted set of included packages.
*/
public SortedSet<PackageElement> packages = null;
@@ -399,10 +397,8 @@
private void initPackages() {
packages = new TreeSet<>(utils.makePackageComparator());
- packages.addAll(getSpecifiedPackages());
- for (TypeElement aClass : getSpecifiedClasses()) {
- packages.add(utils.containingPackage(aClass));
- }
+ // add all the included packages
+ packages.addAll(docEnv.getIncludedPackageElements());
}
public Set<Doclet.Option> getSupportedOptions() {
@@ -647,7 +643,7 @@
if (docencoding == null) {
docencoding = encoding;
}
- typeElementCatalog = new TypeElementCatalog(getSpecifiedClasses(), this);
+ typeElementCatalog = new TypeElementCatalog(docEnv.getIncludedTypeElements(), this);
initTagletManager(customTagStrs);
groups.stream().forEach((grp) -> {
group.checkPackageGroups(grp.value1, grp.value2);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Thu Oct 27 08:52:00 2016 -0700
@@ -587,18 +587,28 @@
}
private Set<PackageElement> computeModulePackages() throws ToolException {
- final AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
+ AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
final boolean documentAllModulePackages = (accessValue == AccessKind.PACKAGE ||
accessValue == AccessKind.PRIVATE);
+ accessValue = accessFilter.getAccessValue(ElementKind.MODULE);
+ final boolean moduleDetailedMode = (accessValue == AccessKind.PACKAGE ||
+ accessValue == AccessKind.PRIVATE);
Set<PackageElement> expandedModulePackages = new LinkedHashSet<>();
for (ModuleElement mdle : specifiedModuleElements) {
- // add all exported packages belonging to a specified module
- if (specifiedModuleElements.contains(mdle)) {
+ if (documentAllModulePackages) { // include all packages
+ List<PackageElement> packages = ElementFilter.packagesIn(mdle.getEnclosedElements());
+ expandedModulePackages.addAll(packages);
+ expandedModulePackages.addAll(getAllModulePackages(mdle));
+ } else { // selectively include required packages
List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
for (ExportsDirective export : exports) {
- expandedModulePackages.add(export.getPackage());
+ // add if fully exported or add qualified exports only if desired
+ if (export.getTargetModules() == null
+ || documentAllModulePackages || moduleDetailedMode) {
+ expandedModulePackages.add(export.getPackage());
+ }
}
}
@@ -613,27 +623,6 @@
}
}
}
-
- if (!documentAllModulePackages) {
- List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
- // check exported packages
- for (ExportsDirective export : exports) {
- List<? extends ModuleElement> targetModules = export.getTargetModules();
- if (targetModules == null) { // no qualified exports, add 'em all
- expandedModulePackages.add(export.getPackage());
- } else { // qualified export, add only if target module is being considered
- for (ModuleElement target : targetModules) {
- if (specifiedModuleElements.contains(target)) {
- expandedModulePackages.add(export.getPackage());
- }
- }
- }
- }
- } else { // add all exported and module private packages
- List<PackageElement> packages = ElementFilter.packagesIn(mdle.getEnclosedElements());
- expandedModulePackages.addAll(packages);
- expandedModulePackages.addAll(getAllModulePackages(mdle));
- }
}
return expandedModulePackages;
}
@@ -668,8 +657,7 @@
if (!mdle.isUnnamed())
imodules.add(mdle);
PackageElement pkg = toolEnv.elements.getPackageOf(klass);
- if (!pkg.isUnnamed())
- ipackages.add(pkg);
+ ipackages.add(pkg);
addAllClasses(iclasses, klass, true);
});
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ArgTokenizer.java Thu Oct 27 08:52:00 2016 -0700
@@ -30,7 +30,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
/**
@@ -78,7 +77,12 @@
while (true) {
nextToken();
if (sval != null && !isQuoted() && sval.startsWith("-")) {
- foundOption(sval);
+ // allow POSIX getopt() option format,
+ // to be consistent with command-line
+ String opt = sval.startsWith("--")
+ ? sval.substring(1)
+ : sval;
+ foundOption(opt);
} else {
break;
}
@@ -104,28 +108,13 @@
}
}
- String[] next(String... strings) {
- return next(Arrays.stream(strings));
- }
-
- String[] next(Stream<String> stream) {
- next();
- if (sval == null) {
- return null;
- }
- String[] matches = stream
- .filter(s -> s.startsWith(sval))
- .toArray(size -> new String[size]);
- return matches;
- }
-
/**
* Set the allowed options. Must be called before any options would be read
* and before calling any of the option functionality below.
*/
void allowedOptions(String... opts) {
for (String opt : opts) {
- options.put(opt, false);
+ options.putIfAbsent(opt, false);
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Thu Oct 27 08:52:00 2016 -0700
@@ -31,6 +31,7 @@
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InterruptedIOException;
import java.io.PrintStream;
import java.io.UncheckedIOException;
import java.lang.reflect.Method;
@@ -61,6 +62,8 @@
import jdk.internal.jline.console.history.MemoryHistory;
import jdk.internal.jline.extra.EditingHistory;
import jdk.internal.jshell.tool.StopDetectingInputStream.State;
+import jdk.internal.misc.Signal;
+import jdk.internal.misc.Signal.Handler;
class ConsoleIOContext extends IOContext {
@@ -170,6 +173,21 @@
bind(shortcuts + computer.shortcut, (ActionListener) evt -> fixes(computer));
}
}
+ try {
+ Signal.handle(new Signal("CONT"), new Handler() {
+ @Override public void handle(Signal sig) {
+ try {
+ in.getTerminal().reset();
+ in.redrawLine();
+ in.flush();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ });
+ } catch (IllegalArgumentException ignored) {
+ //the CONT signal does not exist on this platform
+ }
}
@Override
@@ -390,7 +408,7 @@
private int inputBytesPointer;
@Override
- public synchronized int readUserInput() {
+ public synchronized int readUserInput() throws IOException {
while (inputBytes == null || inputBytes.length <= inputBytesPointer) {
boolean prevHandleUserInterrupt = in.getHandleUserInterrupt();
History prevHistory = in.getHistory();
@@ -401,12 +419,8 @@
in.setHistory(userInputHistory);
inputBytes = (in.readLine("") + System.getProperty("line.separator")).getBytes();
inputBytesPointer = 0;
- } catch (IOException ex) {
- ex.printStackTrace();
- return -1;
} catch (UserInterruptException ex) {
- repl.state.stop();
- return -1;
+ throw new InterruptedIOException();
} finally {
in.setHistory(prevHistory);
in.setHandleUserInterrupt(prevHandleUserInterrupt);
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ExternalEditor.java Thu Oct 27 08:52:00 2016 -0700
@@ -80,7 +80,7 @@
private void setupWatch(String initialText) throws IOException {
this.watcher = FileSystems.getDefault().newWatchService();
this.dir = Files.createTempDirectory("jshelltemp");
- this.tmpfile = Files.createTempFile(dir, null, ".edit");
+ this.tmpfile = Files.createTempFile(dir, null, ".java");
Files.write(tmpfile, initialText.getBytes(Charset.forName("UTF-8")));
dir.register(watcher,
ENTRY_CREATE,
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Thu Oct 27 08:52:00 2016 -0700
@@ -28,16 +28,26 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
import java.util.function.Function;
+import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collector;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toMap;
import static jdk.internal.jshell.tool.ContinuousCompletionProvider.PERFECT_MATCHER;
@@ -114,8 +124,8 @@
return mode.getContinuationPrompt(nextId);
}
- public boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at) {
- return new Setter(messageHandler, at).setFeedback();
+ public boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at, Consumer<String> retainer) {
+ return new Setter(messageHandler, at).setFeedback(retainer);
}
public boolean setFormat(MessageHandler messageHandler, ArgTokenizer at) {
@@ -126,22 +136,14 @@
return new Setter(messageHandler, at).setTruncation();
}
- public boolean setMode(MessageHandler messageHandler, ArgTokenizer at) {
- return new Setter(messageHandler, at).setMode();
+ public boolean setMode(MessageHandler messageHandler, ArgTokenizer at, Consumer<String> retainer) {
+ return new Setter(messageHandler, at).setMode(retainer);
}
public boolean setPrompt(MessageHandler messageHandler, ArgTokenizer at) {
return new Setter(messageHandler, at).setPrompt();
}
- public String retainFeedback(MessageHandler messageHandler, ArgTokenizer at) {
- return new Setter(messageHandler, at).retainFeedback();
- }
-
- public String retainMode(MessageHandler messageHandler, ArgTokenizer at) {
- return new Setter(messageHandler, at).retainMode();
- }
-
public boolean restoreEncodedModes(MessageHandler messageHandler, String encoded) {
return new Setter(messageHandler, new ArgTokenizer("<init>", "")).restoreEncodedModes(encoded);
}
@@ -177,6 +179,15 @@
selectorMap.put(e.name().toLowerCase(Locale.US), e);
}
+ private static class SelectorSets {
+ Set<FormatCase> cc;
+ Set<FormatAction> ca;
+ Set<FormatWhen> cw;
+ Set<FormatResolve> cr;
+ Set<FormatUnresolved> cu;
+ Set<FormatErrors> ce;
+ }
+
/**
* Holds all the context of a mode mode
*/
@@ -197,12 +208,32 @@
String continuationPrompt = ">> ";
static class Setting {
+
final long enumBits;
final String format;
+
Setting(long enumBits, String format) {
this.enumBits = enumBits;
this.format = format;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Setting) {
+ Setting ing = (Setting) o;
+ return enumBits == ing.enumBits && format.equals(ing.format);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 67 * hash + (int) (this.enumBits ^ (this.enumBits >>> 32));
+ hash = 67 * hash + Objects.hashCode(this.format);
+ return hash;
+ }
}
/**
@@ -274,6 +305,25 @@
}
}
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof Mode) {
+ Mode m = (Mode) o;
+ return name.equals((m.name))
+ && commandFluff == m.commandFluff
+ && prompt.equals((m.prompt))
+ && continuationPrompt.equals((m.continuationPrompt))
+ && cases.equals((m.cases));
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name);
+ }
+
/**
* Set if this mode displays informative/confirmational messages on
* commands.
@@ -308,13 +358,17 @@
return String.join(RECORD_SEPARATOR, el);
}
- private boolean add(String field, Setting ing) {
- List<Setting> settings = cases.computeIfAbsent(field, k -> new ArrayList<>());
+ private void add(String field, Setting ing) {
+ List<Setting> settings = cases.get(field);
if (settings == null) {
- return false;
+ settings = new ArrayList<>();
+ cases.put(field, settings);
+ } else {
+ // remove obscured settings
+ long mask = ~ing.enumBits;
+ settings.removeIf(t -> (t.enumBits & mask) == 0);
}
settings.add(ing);
- return true;
}
void set(String field,
@@ -465,6 +519,37 @@
return res;
}
+ private static SelectorSets unpackEnumbits(long enumBits) {
+ class Unpacker {
+
+ SelectorSets u = new SelectorSets();
+ long b = enumBits;
+
+ <E extends Enum<E>> Set<E> unpackEnumbits(E[] values) {
+ Set<E> c = new HashSet<>();
+ for (int i = 0; i < values.length; ++i) {
+ if ((b & (1 << i)) != 0) {
+ c.add(values[i]);
+ }
+ }
+ b >>>= values.length;
+ return c;
+ }
+
+ SelectorSets unpack() {
+ // inverseof the order they were packed
+ u.ce = unpackEnumbits(FormatErrors.values());
+ u.cu = unpackEnumbits(FormatUnresolved.values());
+ u.cr = unpackEnumbits(FormatResolve.values());
+ u.cw = unpackEnumbits(FormatWhen.values());
+ u.ca = unpackEnumbits(FormatAction.values());
+ u.cc = unpackEnumbits(FormatCase.values());
+ return u;
+ }
+ }
+ return new Unpacker().unpack();
+ }
+
interface Selector<E extends Enum<E> & Selector<E>> {
SelectorCollector<E> collector(Setter.SelectorList sl);
String doc();
@@ -675,31 +760,197 @@
Setter(MessageHandler messageHandler, ArgTokenizer at) {
this.messageHandler = messageHandler;
this.at = at;
+ at.allowedOptions("-retain");
}
void fluff(String format, Object... args) {
messageHandler.fluff(format, args);
}
+ void hard(String format, Object... args) {
+ messageHandler.hard(format, args);
+ }
+
void fluffmsg(String messageKey, Object... args) {
messageHandler.fluffmsg(messageKey, args);
}
+ void hardmsg(String messageKey, Object... args) {
+ messageHandler.hardmsg(messageKey, args);
+ }
+
+ boolean showFluff() {
+ return messageHandler.showFluff();
+ }
+
void errorat(String messageKey, Object... args) {
+ if (!valid) {
+ // no spew of errors
+ return;
+ }
+ valid = false;
Object[] a2 = Arrays.copyOf(args, args.length + 2);
a2[args.length] = at.whole();
messageHandler.errormsg(messageKey, a2);
}
+ String selectorsToString(SelectorSets u) {
+ StringBuilder sb = new StringBuilder();
+ selectorToString(sb, u.cc, FormatCase.values());
+ selectorToString(sb, u.ca, FormatAction.values());
+ selectorToString(sb, u.cw, FormatWhen.values());
+ selectorToString(sb, u.cr, FormatResolve.values());
+ selectorToString(sb, u.cu, FormatUnresolved.values());
+ selectorToString(sb, u.ce, FormatErrors.values());
+ return sb.toString();
+ }
+
+ private <E extends Enum<E>> void selectorToString(StringBuilder sb, Set<E> c, E[] values) {
+ if (!c.containsAll(Arrays.asList(values))) {
+ sb.append(c.stream()
+ .sorted((x, y) -> x.ordinal() - y.ordinal())
+ .map(v -> v.name().toLowerCase(Locale.US))
+ .collect(new Collector<CharSequence, StringJoiner, String>() {
+ @Override
+ public BiConsumer<StringJoiner, CharSequence> accumulator() {
+ return StringJoiner::add;
+ }
+
+ @Override
+ public Supplier<StringJoiner> supplier() {
+ return () -> new StringJoiner(",", (sb.length() == 0)? "" : "-", "")
+ .setEmptyValue("");
+ }
+
+ @Override
+ public BinaryOperator<StringJoiner> combiner() {
+ return StringJoiner::merge;
+ }
+
+ @Override
+ public Function<StringJoiner, String> finisher() {
+ return StringJoiner::toString;
+ }
+
+ @Override
+ public Set<Characteristics> characteristics() {
+ return Collections.emptySet();
+ }
+ }));
+ }
+ }
+
+ // Show format settings -- in a predictable order, for testing...
+ void showFormatSettings(Mode sm, String f) {
+ if (sm == null) {
+ modeMap.entrySet().stream()
+ .sorted((es1, es2) -> es1.getKey().compareTo(es2.getKey()))
+ .forEach(m -> showFormatSettings(m.getValue(), f));
+ } else {
+ sm.cases.entrySet().stream()
+ .filter(ec -> (f == null)
+ ? !ec.getKey().equals(TRUNCATION_FIELD)
+ : ec.getKey().equals(f))
+ .sorted((ec1, ec2) -> ec1.getKey().compareTo(ec2.getKey()))
+ .forEach(ec -> {
+ ec.getValue().forEach(s -> {
+ hard("/set format %s %s %s %s",
+ sm.name, ec.getKey(), toStringLiteral(s.format),
+ selectorsToString(unpackEnumbits(s.enumBits)));
+
+ });
+ });
+ }
+ }
+
+ void showTruncationSettings(Mode sm) {
+ if (sm == null) {
+ modeMap.values().forEach(m -> showTruncationSettings(m));
+ } else {
+ List<Mode.Setting> trunc = sm.cases.get(TRUNCATION_FIELD);
+ if (trunc != null) {
+ trunc.forEach(s -> {
+ hard("/set truncation %s %s %s",
+ sm.name, s.format,
+ selectorsToString(unpackEnumbits(s.enumBits)));
+ });
+ }
+ }
+ }
+
+ void showPromptSettings(Mode sm) {
+ if (sm == null) {
+ modeMap.values().forEach(m -> showPromptSettings(m));
+ } else {
+ hard("/set prompt %s %s %s",
+ sm.name,
+ toStringLiteral(sm.prompt),
+ toStringLiteral(sm.continuationPrompt));
+ }
+ }
+
+ void showModeSettings(String umode, String msg) {
+ if (umode == null) {
+ modeMap.values().forEach(n -> showModeSettings(n));
+ } else {
+ Mode m;
+ String retained = retainedMap.get(umode);
+ if (retained == null) {
+ m = searchForMode(umode, msg);
+ if (m == null) {
+ return;
+ }
+ umode = m.name;
+ retained = retainedMap.get(umode);
+ } else {
+ m = modeMap.get(umode);
+ }
+ if (retained != null) {
+ Mode rm = new Mode(encodedModeIterator(retained));
+ showModeSettings(rm);
+ hard("/set mode -retain %s", umode);
+ if (m != null && !m.equals(rm)) {
+ hard("");
+ showModeSettings(m);
+ }
+ } else {
+ showModeSettings(m);
+ }
+ }
+ }
+
+ void showModeSettings(Mode sm) {
+ hard("/set mode %s %s",
+ sm.name, sm.commandFluff ? "-command" : "-quiet");
+ showPromptSettings(sm);
+ showFormatSettings(sm, null);
+ showTruncationSettings(sm);
+ }
+
+ void showFeedbackSetting() {
+ if (retainedCurrentMode != null) {
+ hard("/set feedback -retain %s", retainedCurrentMode.name);
+ }
+ if (mode != retainedCurrentMode) {
+ hard("/set feedback %s", mode.name);
+ }
+ }
+
// For /set prompt <mode> "<prompt>" "<continuation-prompt>"
boolean setPrompt() {
Mode m = nextMode();
+ String prompt = nextFormat();
+ String continuationPrompt = nextFormat();
+ checkOptionsAndRemainingInput();
+ if (valid && prompt == null) {
+ showPromptSettings(m);
+ return valid;
+ }
if (valid && m.readOnly) {
errorat("jshell.err.not.valid.with.predefined.mode", m.name);
- valid = false;
+ } else if (continuationPrompt == null) {
+ errorat("jshell.err.continuation.prompt.required");
}
- String prompt = valid ? nextFormat() : null;
- String continuationPrompt = valid ? nextFormat() : null;
if (valid) {
m.setPrompts(prompt, continuationPrompt);
} else {
@@ -714,210 +965,210 @@
*
* @return true if successful
*/
- boolean setMode() {
- at.allowedOptions("-command", "-quiet", "-delete");
- String umode = nextModeIdentifier();
- Mode om = null;
- String omode = at.next();
- if (valid && omode != null) {
- om = toMode(omode);
- }
- checkOptionsAndRemainingInput();
- boolean commandOption = at.hasOption("-command");
- boolean quietOption = at.hasOption("-quiet");
- boolean deleteOption = at.hasOption("-delete");
- // Only one (or zero) of the options can be used
- if (valid && at.optionCount() > 1) {
- errorat("jshell.err.conflicting.options");
- valid = false;
- }
- if (valid) {
- Mode m = modeMap.get(umode);
- if (m != null && m.readOnly) {
- // Cannot make changes to a the built-in modes
- errorat("jshell.err.not.valid.with.predefined.mode", m.name);
- valid = false;
- } else if (deleteOption) {
- if (m == null) {
+ boolean setMode(Consumer<String> retainer) {
+ class SetMode {
+
+ final String umode;
+ final String omode;
+ final boolean commandOption;
+ final boolean quietOption;
+ final boolean deleteOption;
+ final boolean retainOption;
+
+ SetMode() {
+ at.allowedOptions("-command", "-quiet", "-delete", "-retain");
+ umode = nextModeIdentifier();
+ omode = nextModeIdentifier();
+ checkOptionsAndRemainingInput();
+ commandOption = at.hasOption("-command");
+ quietOption = at.hasOption("-quiet");
+ deleteOption = at.hasOption("-delete");
+ retainOption = at.hasOption("-retain");
+ }
+
+ void delete() {
+ // Note: delete, for safety reasons, does NOT do name matching
+ if (commandOption || quietOption) {
+ errorat("jshell.err.conflicting.options");
+ } else if (!(retainOption ? retainedMap : modeMap).containsKey(umode)) {
// Cannot delete a mode that does not exist
errorat("jshell.err.mode.unknown", umode);
- valid = false;
- } else if (mode.name.equals(m.name)) {
+ } else if (omode != null) {
+ // old mode is for creation
+ errorat("jshell.err.unexpected.at.end", omode);
+ } else if (mode.name.equals(umode)) {
// Cannot delete the current mode out from under us
errorat("jshell.err.cannot.delete.current.mode", umode);
- valid = false;
+ } else if (retainOption && retainedCurrentMode != null &&
+ retainedCurrentMode.name.equals(umode)) {
+ // Cannot delete the retained mode or re-start will have an error
+ errorat("jshell.err.cannot.delete.retained.mode", umode);
} else {
- // Remove the mode
- modeMap.remove(umode);
+ Mode m = modeMap.get(umode);
+ if (m != null && m.readOnly) {
+ errorat("jshell.err.not.valid.with.predefined.mode", umode);
+ } else {
+ // Remove the mode
+ modeMap.remove(umode);
+ if (retainOption) {
+ // Remove the retained mode
+ retainedMap.remove(umode);
+ updateRetainedModes();
+ }
+ }
}
- } else {
- if (om != null || m == null) {
- // We are copying and existing mode and/or creating a
- // brand-new mode -- in either case create from scratch
- m = (om != null)
- ? new Mode(umode, om)
- : new Mode(umode);
- modeMap.put(umode, m);
- fluffmsg("jshell.msg.feedback.new.mode", m.name);
- // Set the current mode by name, in case we just smashed
- // the current mode
- if (umode.equals(mode.name)) {
- mode = modeMap.get(mode.name);
+ }
+
+ void retain() {
+ if (commandOption || quietOption) {
+ errorat("jshell.err.conflicting.options");
+ } else if (omode != null) {
+ // old mode is for creation
+ errorat("jshell.err.unexpected.at.end", omode);
+ } else {
+ Mode m = modeMap.get(umode);
+ if (m == null) {
+ // can only retain existing modes
+ errorat("jshell.err.mode.unknown", umode);
+ } else if (m.readOnly) {
+ errorat("jshell.err.not.valid.with.predefined.mode", umode);
+ } else {
+ // Add to local cache of retained current encodings
+ retainedMap.put(m.name, m.encode());
+ updateRetainedModes();
}
}
- if (commandOption || quietOption || om == null) {
- // set command fluff, if explicit, or wholly new
- m.setCommandFluff(!quietOption);
+ }
+
+ void updateRetainedModes() {
+ // Join all the retained encodings
+ String encoded = String.join(RECORD_SEPARATOR, retainedMap.values());
+ // Retain it
+ retainer.accept(encoded);
+ }
+
+ void create() {
+ if (commandOption && quietOption) {
+ errorat("jshell.err.conflicting.options");
+ } else if (!commandOption && !quietOption) {
+ errorat("jshell.err.mode.creation");
+ } else if (modeMap.containsKey(umode)) {
+ // Mode already exists
+ errorat("jshell.err.mode.exists", umode);
+ } else {
+ Mode om = searchForMode(omode);
+ if (valid) {
+ // We are copying an existing mode and/or creating a
+ // brand-new mode -- in either case create from scratch
+ Mode m = (om != null)
+ ? new Mode(umode, om)
+ : new Mode(umode);
+ modeMap.put(umode, m);
+ fluffmsg("jshell.msg.feedback.new.mode", m.name);
+ m.setCommandFluff(commandOption);
+ }
}
}
+
+ boolean set() {
+ if (valid && !commandOption && !quietOption && !deleteOption &&
+ omode == null && !retainOption) {
+ // Not a creation, deletion, or retain -- show mode(s)
+ showModeSettings(umode, "jshell.err.mode.creation");
+ } else if (valid && umode == null) {
+ errorat("jshell.err.missing.mode");
+ } else if (valid && deleteOption) {
+ delete();
+ } else if (valid && retainOption) {
+ retain();
+ } else if (valid) {
+ create();
+ }
+ if (!valid) {
+ fluffmsg("jshell.msg.see", "/help /set mode");
+ }
+ return valid;
+ }
}
- if (!valid) {
- fluffmsg("jshell.msg.see", "/help /set mode");
- }
- return valid;
+ return new SetMode().set();
}
- // For /set feedback <mode>
- boolean setFeedback() {
+ // For /set format <mode> <field> "<format>" <selector>...
+ boolean setFormat() {
Mode m = nextMode();
- if (valid) {
- mode = m;
- fluffmsg("jshell.msg.feedback.mode", mode.name);
+ String field = toIdentifier(next(), "jshell.err.field.name");
+ String format = nextFormat();
+ if (valid && format == null) {
+ if (field != null && m != null && !m.cases.containsKey(field)) {
+ errorat("jshell.err.field.name", field);
+ } else {
+ showFormatSettings(m, field);
+ }
} else {
- fluffmsg("jshell.msg.see", "/help /set feedback");
- printFeedbackModes();
+ installFormat(m, field, format, "/help /set format");
}
return valid;
}
- // For /set format <mode> "<format>" <selector>...
- boolean setFormat() {
- Mode m = nextMode();
- if (valid && m.readOnly) {
- errorat("jshell.err.not.valid.with.predefined.mode", m.name);
- valid = false;
- }
- String field = valid
- ? toIdentifier(at.next(), "jshell.err.missing.field", "jshell.err.field.name")
- : null;
- String format = valid ? nextFormat() : null;
- return installFormat(m, field, format, "/help /set format");
- }
-
// For /set truncation <mode> <length> <selector>...
boolean setTruncation() {
Mode m = nextMode();
- if (valid && m.readOnly) {
- errorat("jshell.err.not.valid.with.predefined.mode", m.name);
- valid = false;
- }
- String length = at.next();
+ String length = next();
if (length == null) {
- errorat("jshell.err.truncation.expected.length");
- valid = false;
+ showTruncationSettings(m);
} else {
try {
// Assure that integer format is correct
Integer.parseUnsignedInt(length);
} catch (NumberFormatException ex) {
errorat("jshell.err.truncation.length.not.integer", length);
- valid = false;
}
+ // install length into an internal format field
+ installFormat(m, TRUNCATION_FIELD, length, "/help /set truncation");
}
- // install length into an internal format field
- return installFormat(m, TRUNCATION_FIELD, length, "/help /set truncation");
- }
-
- String retainFeedback() {
- String umode = at.next();
- if (umode != null) {
- toModeIdentifier(umode);
- Mode m = valid ? toMode(umode) : null;
- if (valid && !m.readOnly && !retainedMap.containsKey(m.name)) {
- errorat("jshell.err.retained.feedback.mode.must.be.retained.or.predefined");
- valid = false;
- }
- if (valid) {
- mode = m;
- retainedCurrentMode = m;
- fluffmsg("jshell.msg.feedback.mode", mode.name);
- } else {
- fluffmsg("jshell.msg.see", "/help /retain feedback");
- return null;
- }
- }
- return mode.name;
+ return valid;
}
- /**
- * Retain (or delete from retention) a previously set mode.
- *
- * @return all retained modes encoded into a String
- */
- String retainMode() {
- at.allowedOptions("-delete");
- String umode = nextModeIdentifier();
- // -delete is the only valid option, fail for anything else
+ // For /set feedback <mode>
+ boolean setFeedback(Consumer<String> retainer) {
+ String umode = next();
checkOptionsAndRemainingInput();
- boolean deleteOption = at.hasOption("-delete");
- // Lookup the mode
- Mode m;
- if (!valid) {
- m = null;
- // Skip this stuff, we have failed already
- } else if (deleteOption) {
- // If delete, allow for deleting, from retention, a mode that
- // has been locally deleted but is retained.
- // Also require the full name.
- m = modeMap.get(umode);
- if (m == null && !retainedMap.containsKey(umode)) {
- errorat("jshell.err.mode.unknown", umode);
- valid = false;
- }
- } else {
- // For retain do normal lookup and checking
- m = toMode(umode);
- }
-
- // Built-in modes cannot be retained or deleted
- if (valid && m != null && m.readOnly) {
- errorat("jshell.err.not.valid.with.predefined.mode", umode);
- valid = false;
+ boolean retainOption = at.hasOption("-retain");
+ if (valid && umode == null && !retainOption) {
+ showFeedbackSetting();
+ hard("");
+ showFeedbackModes();
+ return true;
}
if (valid) {
- if (deleteOption) {
- if (mode.name.equals(umode)) {
- // Cannot delete the current mode out from under us
- errorat("jshell.err.cannot.delete.current.mode", umode);
- valid = false;
- } else if (retainedCurrentMode != null && retainedCurrentMode.name.equals(umode)) {
- // Cannot delete the retained mode or re-start has error
- errorat("jshell.err.cannot.delete.retained.mode", umode);
- valid = false;
- } else {
- // Delete the mode
- modeMap.remove(umode);
- retainedMap.remove(umode);
+ Mode m = umode == null
+ ? mode
+ : searchForMode(toModeIdentifier(umode));
+ if (valid && retainOption && !m.readOnly && !retainedMap.containsKey(m.name)) {
+ errorat("jshell.err.retained.feedback.mode.must.be.retained.or.predefined");
+ }
+ if (valid) {
+ if (umode != null) {
+ mode = m;
+ fluffmsg("jshell.msg.feedback.mode", mode.name);
}
- } else {
- // Retain the current encoding
- retainedMap.put(m.name, m.encode());
+ if (retainOption) {
+ retainedCurrentMode = m;
+ retainer.accept(m.name);
+ }
}
}
- if (valid) {
- // Join all the retained encodings
- return String.join(RECORD_SEPARATOR, retainedMap.values());
- } else {
- fluffmsg("jshell.msg.see", "/help /retain mode");
- return null;
+ if (!valid) {
+ fluffmsg("jshell.msg.see", "/help /set feedback");
+ return false;
}
+ return true;
}
boolean restoreEncodedModes(String allEncoded) {
try {
// Iterate over each record in each encoded mode
- String[] ms = allEncoded.split(RECORD_SEPARATOR);
- Iterator<String> itr = Arrays.asList(ms).iterator();
+ Iterator<String> itr = encodedModeIterator(allEncoded);
while (itr.hasNext()) {
// Reconstruct the encoded mode
Mode m = new Mode(itr);
@@ -934,50 +1185,60 @@
}
}
+ Iterator<String> encodedModeIterator(String encoded) {
+ String[] ms = encoded.split(RECORD_SEPARATOR);
+ return Arrays.asList(ms).iterator();
+ }
+
// install the format of a field under parsed selectors
- boolean installFormat(Mode m, String field, String format, String help) {
+ void installFormat(Mode m, String field, String format, String help) {
String slRaw;
List<SelectorList> slList = new ArrayList<>();
- while (valid && (slRaw = at.next()) != null) {
+ while (valid && (slRaw = next()) != null) {
SelectorList sl = new SelectorList();
sl.parseSelectorList(slRaw);
slList.add(sl);
}
+ checkOptionsAndRemainingInput();
if (valid) {
- if (slList.isEmpty()) {
+ if (m.readOnly) {
+ errorat("jshell.err.not.valid.with.predefined.mode", m.name);
+ } else if (slList.isEmpty()) {
// No selectors specified, then always the format
m.set(field, ALWAYS, format);
} else {
// Set the format of the field for specified selector
slList.stream()
.forEach(sl -> m.set(field,
- sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(),
- sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(),
- format));
+ sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(),
+ sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(),
+ format));
}
} else {
fluffmsg("jshell.msg.see", help);
}
- return valid;
}
void checkOptionsAndRemainingInput() {
- if (!valid) {
- return;
- }
String junk = at.remainder();
if (!junk.isEmpty()) {
errorat("jshell.err.unexpected.at.end", junk);
- valid = false;
} else {
String bad = at.badOptions();
if (!bad.isEmpty()) {
errorat("jshell.err.unknown.option", bad);
- valid = false;
}
}
}
+ String next() {
+ String s = at.next();
+ if (s == null) {
+ checkOptionsAndRemainingInput();
+ }
+ return s;
+ }
+
/**
* Check that the specified string is an identifier (Java identifier).
* If null display the missing error. If it is not an identifier,
@@ -985,45 +1246,41 @@
*
* @param id the string to check, MUST be the most recently retrieved
* token from 'at'.
- * @param missing the resource error to display if null
+ * @param missing null for no null error, otherwise the resource error to display if id is null
* @param err the resource error to display if not an identifier
* @return the identifier string, or null if null or not an identifier
*/
- String toIdentifier(String id, String missing, String err) {
- if (id == null) {
- errorat(missing);
- valid = false;
+ private String toIdentifier(String id, String err) {
+ if (!valid || id == null) {
return null;
}
if (at.isQuoted() ||
!id.codePoints().allMatch(cp -> Character.isJavaIdentifierPart(cp))) {
errorat(err, id);
- valid = false;
return null;
}
return id;
}
- String toModeIdentifier(String id) {
- return toIdentifier(id, "jshell.err.missing.mode", "jshell.err.mode.name");
+ private String toModeIdentifier(String id) {
+ return toIdentifier(id, "jshell.err.mode.name");
}
- String nextModeIdentifier() {
- return toModeIdentifier(at.next());
+ private String nextModeIdentifier() {
+ return toModeIdentifier(next());
}
- Mode nextMode() {
+ private Mode nextMode() {
String umode = nextModeIdentifier();
- return toMode(umode);
+ return searchForMode(umode);
}
- Mode toMode(String umode) {
- if (!valid) {
- return null;
- }
- if (umode == null) {
- errorat("jshell.err.missing.mode");
- valid = false;
+ private Mode searchForMode(String umode) {
+ return searchForMode(umode, null);
+ }
+
+ private Mode searchForMode(String umode, String msg) {
+ if (!valid || umode == null) {
return null;
}
Mode m = modeMap.get(umode);
@@ -1038,39 +1295,101 @@
if (matches.length == 1) {
return matches[0];
} else {
- valid = false;
+ if (msg != null) {
+ hardmsg(msg, "");
+ }
if (matches.length == 0) {
errorat("jshell.err.feedback.does.not.match.mode", umode);
} else {
errorat("jshell.err.feedback.ambiguous.mode", umode);
}
- printFeedbackModes();
+ if (showFluff()) {
+ showFeedbackModes();
+ }
return null;
}
}
- void printFeedbackModes() {
- fluffmsg("jshell.msg.feedback.mode.following");
+ void showFeedbackModes() {
+ if (!retainedMap.isEmpty()) {
+ hardmsg("jshell.msg.feedback.retained.mode.following");
+ retainedMap.keySet().stream()
+ .sorted()
+ .forEach(mk -> hard(" %s", mk));
+ }
+ hardmsg("jshell.msg.feedback.mode.following");
modeMap.keySet().stream()
- .forEach(mk -> fluff(" %s", mk));
+ .sorted()
+ .forEach(mk -> hard(" %s", mk));
+ }
+
+ // Read and test if the format string is correctly
+ private String nextFormat() {
+ return toFormat(next());
}
// Test if the format string is correctly
- final String nextFormat() {
- String format = at.next();
- if (format == null) {
- errorat("jshell.err.feedback.expected.format");
- valid = false;
+ private String toFormat(String format) {
+ if (!valid || format == null) {
return null;
}
if (!at.isQuoted()) {
errorat("jshell.err.feedback.must.be.quoted", format);
- valid = false;
- return null;
+ return null;
}
return format;
}
+ // Convert to a quoted string
+ private String toStringLiteral(String s) {
+ StringBuilder sb = new StringBuilder();
+ sb.append('"');
+ final int length = s.length();
+ for (int offset = 0; offset < length;) {
+ final int codepoint = s.codePointAt(offset);
+
+ switch (codepoint) {
+ case '\b':
+ sb.append("\\b");
+ break;
+ case '\t':
+ sb.append("\\t");
+ break;
+ case '\n':
+ sb.append("\\n");
+ break;
+ case '\f':
+ sb.append("\\f");
+ break;
+ case '\r':
+ sb.append("\\r");
+ break;
+ case '\"':
+ sb.append("\\\"");
+ break;
+ case '\'':
+ sb.append("\\'");
+ break;
+ case '\\':
+ sb.append("\\\\");
+ break;
+ default:
+ if (codepoint < 040) {
+ sb.append(String.format("\\%o", codepoint));
+ } else {
+ sb.appendCodePoint(codepoint);
+ }
+ break;
+ }
+
+ // do something with the codepoint
+ offset += Character.charCount(codepoint);
+
+ }
+ sb.append('"');
+ return sb.toString();
+ }
+
class SelectorList {
SelectorCollector<FormatCase> cases = new SelectorCollector<>(FormatCase.all);
@@ -1088,19 +1407,16 @@
Selector<?> sel = selectorMap.get(as);
if (sel == null) {
errorat("jshell.err.feedback.not.a.valid.selector", as, s);
- valid = false;
return;
}
SelectorCollector<?> collector = sel.collector(this);
if (lastCollector == null) {
if (!collector.isEmpty()) {
errorat("jshell.err.feedback.multiple.sections", as, s);
- valid = false;
return;
}
} else if (collector != lastCollector) {
errorat("jshell.err.feedback.different.selector.kinds", as, s);
- valid = false;
return;
}
collector.add(sel);
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java Thu Oct 27 08:52:00 2016 -0700
@@ -54,7 +54,7 @@
public abstract void replaceLastHistoryEntry(String source);
- public abstract int readUserInput();
+ public abstract int readUserInput() throws IOException;
class InputInterruptedException extends Exception {
private static final long serialVersionUID = 1L;
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Thu Oct 27 08:52:00 2016 -0700
@@ -133,32 +133,26 @@
final PrintStream userout;
final PrintStream usererr;
final Preferences prefs;
+ final Map<String, String> envvars;
final Locale locale;
final Feedback feedback = new Feedback();
/**
- * The constructor for the tool (used by tool launch via main and by test
- * harnesses to capture ins and outs.
- * @param in command line input -- snippets, commands and user input
- * @param cmdout command line output, feedback including errors
- * @param cmderr start-up errors and debugging info
- * @param console console control interaction
- * @param userout code execution output -- System.out.printf("hi")
- * @param usererr code execution error stream -- System.err.printf("Oops")
- * @param prefs preferences to use
- * @param locale locale to use
+ * Simple constructor for the tool used by main.
+ * @param in command line input
+ * @param out command line output, feedback including errors, user System.out
+ * @param err start-up errors and debugging info, user System.err
*/
- public JShellTool(InputStream in, PrintStream cmdout, PrintStream cmderr,
- PrintStream console,
- PrintStream userout, PrintStream usererr,
- Preferences prefs, Locale locale) {
- this(in, cmdout, cmderr, console, null, userout, usererr, prefs, locale);
+ public JShellTool(InputStream in, PrintStream out, PrintStream err) {
+ this(in, out, err, out, null, out, err,
+ Preferences.userRoot().node("tool/JShell"),
+ System.getenv(),
+ Locale.getDefault());
}
/**
- * The constructor for the tool (used by tool launch via main and by test
- * harnesses to capture ins and outs.
+ * The complete constructor for the tool (used by test harnesses).
* @param cmdin command line input -- snippets and commands
* @param cmdout command line output, feedback including errors
* @param cmderr start-up errors and debugging info
@@ -167,12 +161,13 @@
* @param userout code execution output -- System.out.printf("hi")
* @param usererr code execution error stream -- System.err.printf("Oops")
* @param prefs preferences to use
+ * @param envvars environment variable mapping to use
* @param locale locale to use
*/
public JShellTool(InputStream cmdin, PrintStream cmdout, PrintStream cmderr,
PrintStream console,
InputStream userin, PrintStream userout, PrintStream usererr,
- Preferences prefs, Locale locale) {
+ Preferences prefs, Map<String, String> envvars, Locale locale) {
this.cmdin = cmdin;
this.cmdout = cmdout;
this.cmderr = cmderr;
@@ -186,6 +181,7 @@
this.userout = userout;
this.usererr = usererr;
this.prefs = prefs;
+ this.envvars = envvars;
this.locale = locale;
}
@@ -204,12 +200,16 @@
JShell state = null;
Subscription shutdownSubscription = null;
+ static final EditorSetting BUILT_IN_EDITOR = new EditorSetting(null, false);
+
private boolean debug = false;
public boolean testPrompt = false;
private String cmdlineClasspath = null;
private String startup = null;
- private String[] editor = null;
- private boolean editorWait = false;
+ private EditorSetting editor = BUILT_IN_EDITOR;
+
+ private static final String[] EDITOR_ENV_VARS = new String[] {
+ "JSHELLEDITOR", "VISUAL", "EDITOR"};
// Commands and snippets which should be replayed
private List<String> replayableHistory;
@@ -273,7 +273,8 @@
* @param format printf format
* @param args printf args
*/
- void hard(String format, Object... args) {
+ @Override
+ public void hard(String format, Object... args) {
rawout(feedback.getPre() + format + feedback.getPost(), args);
}
@@ -288,6 +289,15 @@
}
/**
+ * Should optional informative be displayed?
+ * @return true if they should be displayed
+ */
+ @Override
+ public boolean showFluff() {
+ return feedback.shouldDisplayCommandFluff() && interactive();
+ }
+
+ /**
* Optional output
*
* @param format printf format
@@ -295,7 +305,7 @@
*/
@Override
public void fluff(String format, Object... args) {
- if (feedback.shouldDisplayCommandFluff() && interactive()) {
+ if (showFluff()) {
hard(format, args);
}
}
@@ -307,7 +317,7 @@
* @param args printf args
*/
void fluffRaw(String format, Object... args) {
- if (feedback.shouldDisplayCommandFluff() && interactive()) {
+ if (showFluff()) {
rawout(format, args);
}
}
@@ -389,7 +399,8 @@
* @param key the resource key
* @param args
*/
- void hardmsg(String key, Object... args) {
+ @Override
+ public void hardmsg(String key, Object... args) {
cmdout.println(prefix(messageFormat(key, args)));
}
@@ -428,7 +439,7 @@
*/
@Override
public void fluffmsg(String key, Object... args) {
- if (feedback.shouldDisplayCommandFluff() && interactive()) {
+ if (showFluff()) {
hardmsg(key, args);
}
}
@@ -474,10 +485,7 @@
* @throws Exception
*/
public static void main(String[] args) throws Exception {
- new JShellTool(System.in, System.out, System.err, System.out,
- System.out, System.err,
- Preferences.userRoot().node("tool/JShell"),
- Locale.getDefault())
+ new JShellTool(System.in, System.out, System.err)
.start(args);
}
@@ -501,18 +509,7 @@
}
}
- // Read retained editor setting (if any)
- String editorString = prefs.get(EDITOR_KEY, "");
- if (editorString == null || editorString.isEmpty()) {
- editor = null;
- } else {
- char waitMarker = editorString.charAt(0);
- if (waitMarker == '-' || waitMarker == '*') {
- editorWait = waitMarker == '-';
- editorString = editorString.substring(1);
- }
- editor = editorString.split(RECORD_SEPARATOR);
- }
+ configEditor();
resetState(); // Initialize
@@ -542,6 +539,23 @@
}
}
+ private EditorSetting configEditor() {
+ // Read retained editor setting (if any)
+ editor = EditorSetting.fromPrefs(prefs);
+ if (editor != null) {
+ return editor;
+ }
+ // Try getting editor setting from OS environment variables
+ for (String envvar : EDITOR_ENV_VARS) {
+ String v = envvars.get(envvar);
+ if (v != null) {
+ return editor = new EditorSetting(v.split("\\s+"), false);
+ }
+ }
+ // Default to the built-in editor
+ return editor = BUILT_IN_EDITOR;
+ }
+
/**
* Process the command line arguments.
* Set options.
@@ -681,9 +695,24 @@
}
@Override
+ public void hard(String format, Object... args) {
+ //ignore
+ }
+
+ @Override
+ public void hardmsg(String messageKey, Object... args) {
+ //ignore
+ }
+
+ @Override
public void errormsg(String messageKey, Object... args) {
startmsg(messageKey, args);
}
+
+ @Override
+ public boolean showFluff() {
+ return false;
+ }
}
private void resetState() {
@@ -745,7 +774,7 @@
startUpRun(getResourceString("startup.feedback"));
// These predefined modes are read-only
feedback.markModesReadOnly();
- // Restore user defined modes retained on previous run with /retain mode
+ // Restore user defined modes retained on previous run with /set mode -retain
String encoded = prefs.get(MODE_KEY, null);
if (encoded != null && !encoded.isEmpty()) {
if (!feedback.restoreEncodedModes(initmh, encoded)) {
@@ -755,7 +784,7 @@
}
if (commandLineFeedbackMode != null) {
// The feedback mode to use was specified on the command line, use it
- if (!feedback.setFeedback(initmh, new ArgTokenizer("--feedback", commandLineFeedbackMode))) {
+ if (!setFeedback(initmh, new ArgTokenizer("--feedback", commandLineFeedbackMode))) {
regenerateOnDeath = false;
}
commandLineFeedbackMode = null;
@@ -763,8 +792,8 @@
String fb = prefs.get(FEEDBACK_KEY, null);
if (fb != null) {
// Restore the feedback mode to use that was retained
- // on a previous run with /retain feedback
- feedback.retainFeedback(initmh, new ArgTokenizer("/retain feedback", fb));
+ // on a previous run with /set feedback -retain
+ setFeedback(initmh, new ArgTokenizer("previous retain feedback", "-retain " + fb));
}
}
}
@@ -1227,14 +1256,6 @@
"editor", fileCompletions(Files::isExecutable),
"start", FILE_COMPLETION_PROVIDER),
STARTSWITH_MATCHER)));
- registerCommand(new Command("/retain",
- arg -> cmdRetain(arg),
- new ContinuousCompletionProvider(Map.of(
- "feedback", feedback.modeCompletions(),
- "mode", feedback.modeCompletions(),
- "editor", fileCompletions(Files::isExecutable),
- "start", FILE_COMPLETION_PROVIDER),
- STARTSWITH_MATCHER)));
registerCommand(new Command("/?",
"help.quest",
arg -> cmdHelp(arg),
@@ -1293,9 +1314,6 @@
private static final String[] SET_SUBCOMMANDS = new String[]{
"format", "truncation", "feedback", "mode", "prompt", "editor", "start"};
- private static final String[] RETAIN_SUBCOMMANDS = new String[]{
- "feedback", "mode", "editor", "start"};
-
final boolean cmdSet(String arg) {
String cmd = "/set";
ArgTokenizer at = new ArgTokenizer(cmd, arg.trim());
@@ -1304,95 +1322,61 @@
return false;
}
switch (which) {
+ case "_retain": {
+ errormsg("jshell.err.setting.to.retain.must.be.specified", at.whole());
+ return false;
+ }
+ case "_blank": {
+ // show top-level settings
+ new SetEditor().set();
+ showSetStart();
+ setFeedback(this, at); // no args so shows feedback setting
+ hardmsg("jshell.msg.set.show.mode.settings");
+ return true;
+ }
case "format":
return feedback.setFormat(this, at);
case "truncation":
return feedback.setTruncation(this, at);
case "feedback":
- return feedback.setFeedback(this, at);
+ return setFeedback(this, at);
case "mode":
- return feedback.setMode(this, at);
+ return feedback.setMode(this, at,
+ retained -> prefs.put(MODE_KEY, retained));
case "prompt":
return feedback.setPrompt(this, at);
case "editor":
- return setEditor(at, true);
+ return new SetEditor(at).set();
case "start":
- return setStart(cmd, at, true);
+ return setStart(at);
default:
errormsg("jshell.err.arg", cmd, at.val());
return false;
}
}
- final boolean cmdRetain(String arg) {
- String cmd = "/retain";
- ArgTokenizer at = new ArgTokenizer(cmd, arg.trim());
- String which = subCommand(cmd, at, RETAIN_SUBCOMMANDS);
- if (which == null) {
- return false;
- }
- switch (which) {
- case "feedback": {
- String fb = feedback.retainFeedback(this, at);
- if (fb != null) {
- // If a feedback mode has been set now, or in the past, retain it
- prefs.put(FEEDBACK_KEY, fb);
- return true;
- }
- return false;
- }
- case "mode":
- String retained = feedback.retainMode(this, at);
- if (retained != null) {
- // Retain this mode and all previously retained modes
- prefs.put(MODE_KEY, retained);
- return true;
- }
- return false;
- case "editor":
- if (!setEditor(at, false)) {
- return false;
- }
- // retain editor setting
- prefs.put(EDITOR_KEY, (editor == null)
- ? ""
- : (editorWait? "-" : "*") + String.join(RECORD_SEPARATOR, editor));
- return true;
- case "start": {
- if (!setStart(cmd, at, false)) {
- return false;
- }
- // retain startup setting
- prefs.put(STARTUP_KEY, startup);
- return true;
- }
- default:
- errormsg("jshell.err.arg", cmd, at.val());
- return false;
- }
+ boolean setFeedback(MessageHandler messageHandler, ArgTokenizer at) {
+ return feedback.setFeedback(messageHandler, at,
+ fb -> prefs.put(FEEDBACK_KEY, fb));
}
- // Print the help doc for the specified sub-command
- boolean printSubCommandHelp(String cmd, ArgTokenizer at, String helpPrefix, String[] subs) {
- String which = subCommand(cmd, at, subs);
- if (which == null) {
- return false;
+ // Find which, if any, sub-command matches.
+ // Return null on error
+ String subCommand(String cmd, ArgTokenizer at, String[] subs) {
+ at.allowedOptions("-retain");
+ String sub = at.next();
+ if (sub == null) {
+ // No sub-command was given
+ return at.hasOption("-retain")
+ ? "_retain"
+ : "_blank";
}
- hardrb(helpPrefix + which);
- return true;
- }
-
- // Find which, if any, sub-command matches
- String subCommand(String cmd, ArgTokenizer at, String[] subs) {
- String[] matches = at.next(subs);
- if (matches == null) {
- // No sub-command was given
- errormsg("jshell.err.sub.arg", cmd);
- return null;
- }
+ String[] matches = Arrays.stream(subs)
+ .filter(s -> s.startsWith(sub))
+ .toArray(size -> new String[size]);
if (matches.length == 0) {
// There are no matching sub-commands
- errormsg("jshell.err.arg", cmd, at.val());
+ errormsg("jshell.err.arg", cmd, sub);
fluffmsg("jshell.msg.use.one.of", Arrays.stream(subs)
.collect(Collectors.joining(", "))
);
@@ -1400,7 +1384,7 @@
}
if (matches.length > 1) {
// More than one sub-command matches the initial characters provided
- errormsg("jshell.err.sub.ambiguous", cmd, at.val());
+ errormsg("jshell.err.sub.ambiguous", cmd, sub);
fluffmsg("jshell.msg.use.one.of", Arrays.stream(matches)
.collect(Collectors.joining(", "))
);
@@ -1409,67 +1393,232 @@
return matches[0];
}
- // The sub-command: /set editor <editor-command-line>>
- boolean setEditor(ArgTokenizer at, boolean argsRequired) {
- at.allowedOptions("-default", "-wait");
- String prog = at.next();
- List<String> ed = new ArrayList<>();
- while (at.val() != null) {
- ed.add(at.val());
- at.nextToken();
+ static class EditorSetting {
+
+ static String BUILT_IN_REP = "-default";
+ static char WAIT_PREFIX = '-';
+ static char NORMAL_PREFIX = '*';
+
+ final String[] cmd;
+ final boolean wait;
+
+ EditorSetting(String[] cmd, boolean wait) {
+ this.wait = wait;
+ this.cmd = cmd;
+ }
+
+ // returns null if not stored in preferences
+ static EditorSetting fromPrefs(Preferences prefs) {
+ // Read retained editor setting (if any)
+ String editorString = prefs.get(EDITOR_KEY, "");
+ if (editorString == null || editorString.isEmpty()) {
+ return null;
+ } else if (editorString.equals(BUILT_IN_REP)) {
+ return BUILT_IN_EDITOR;
+ } else {
+ boolean wait = false;
+ char waitMarker = editorString.charAt(0);
+ if (waitMarker == WAIT_PREFIX || waitMarker == NORMAL_PREFIX) {
+ wait = waitMarker == WAIT_PREFIX;
+ editorString = editorString.substring(1);
+ }
+ String[] cmd = editorString.split(RECORD_SEPARATOR);
+ return new EditorSetting(cmd, wait);
+ }
+ }
+
+ static void removePrefs(Preferences prefs) {
+ prefs.remove(EDITOR_KEY);
+ }
+
+ void toPrefs(Preferences prefs) {
+ prefs.put(EDITOR_KEY, (this == BUILT_IN_EDITOR)
+ ? BUILT_IN_REP
+ : (wait ? WAIT_PREFIX : NORMAL_PREFIX) + String.join(RECORD_SEPARATOR, cmd));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof EditorSetting) {
+ EditorSetting ed = (EditorSetting) o;
+ return Arrays.equals(cmd, ed.cmd) && wait == ed.wait;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 71 * hash + Arrays.deepHashCode(this.cmd);
+ hash = 71 * hash + (this.wait ? 1 : 0);
+ return hash;
}
+ }
+
+ class SetEditor {
+
+ private final ArgTokenizer at;
+ private final String[] command;
+ private final boolean hasCommand;
+ private final boolean defaultOption;
+ private final boolean deleteOption;
+ private final boolean waitOption;
+ private final boolean retainOption;
+ private final int primaryOptionCount;
+
+ SetEditor(ArgTokenizer at) {
+ at.allowedOptions("-default", "-wait", "-retain", "-delete");
+ String prog = at.next();
+ List<String> ed = new ArrayList<>();
+ while (at.val() != null) {
+ ed.add(at.val());
+ at.nextToken(); // so that options are not interpreted as jshell options
+ }
+ this.at = at;
+ this.command = ed.toArray(new String[ed.size()]);
+ this.hasCommand = command.length > 0;
+ this.defaultOption = at.hasOption("-default");
+ this.deleteOption = at.hasOption("-delete");
+ this.waitOption = at.hasOption("-wait");
+ this.retainOption = at.hasOption("-retain");
+ this.primaryOptionCount = (hasCommand? 1 : 0) + (defaultOption? 1 : 0) + (deleteOption? 1 : 0);
+ }
+
+ SetEditor() {
+ this(new ArgTokenizer("", ""));
+ }
+
+ boolean set() {
+ if (!check()) {
+ return false;
+ }
+ if (primaryOptionCount == 0 && !retainOption) {
+ // No settings or -retain, so this is a query
+ EditorSetting retained = EditorSetting.fromPrefs(prefs);
+ if (retained != null) {
+ // retained editor is set
+ hard("/set editor -retain %s", format(retained));
+ }
+ if (retained == null || !retained.equals(editor)) {
+ // editor is not retained or retained is different from set
+ hard("/set editor %s", format(editor));
+ }
+ return true;
+ }
+ if (retainOption && deleteOption) {
+ EditorSetting.removePrefs(prefs);
+ }
+ install();
+ if (retainOption && !deleteOption) {
+ editor.toPrefs(prefs);
+ fluffmsg("jshell.msg.set.editor.retain", format(editor));
+ }
+ return true;
+ }
+
+ private boolean check() {
+ if (!checkOptionsAndRemainingInput(at)) {
+ return false;
+ }
+ if (primaryOptionCount > 1) {
+ errormsg("jshell.err.default.option.or.program", at.whole());
+ return false;
+ }
+ if (waitOption && !hasCommand) {
+ errormsg("jshell.err.wait.applies.to.external.editor", at.whole());
+ return false;
+ }
+ return true;
+ }
+
+ private void install() {
+ if (hasCommand) {
+ editor = new EditorSetting(command, waitOption);
+ } else if (defaultOption) {
+ editor = BUILT_IN_EDITOR;
+ } else if (deleteOption) {
+ configEditor();
+ } else {
+ return;
+ }
+ fluffmsg("jshell.msg.set.editor.set", format(editor));
+ }
+
+ private String format(EditorSetting ed) {
+ if (ed == BUILT_IN_EDITOR) {
+ return "-default";
+ } else {
+ Stream<String> elems = Arrays.stream(ed.cmd);
+ if (ed.wait) {
+ elems = Stream.concat(Stream.of("-wait"), elems);
+ }
+ return elems.collect(joining(" "));
+ }
+ }
+ }
+
+ // The sub-command: /set start <start-file>
+ boolean setStart(ArgTokenizer at) {
+ at.allowedOptions("-default", "-none", "-retain");
+ String fn = at.next();
if (!checkOptionsAndRemainingInput(at)) {
return false;
}
boolean defaultOption = at.hasOption("-default");
- boolean waitOption = at.hasOption("-wait");
- if (prog != null) {
- if (defaultOption) {
- errormsg("jshell.err.default.option.or.program", at.whole());
+ boolean noneOption = at.hasOption("-none");
+ boolean retainOption = at.hasOption("-retain");
+ boolean hasFile = fn != null;
+
+ int argCount = (defaultOption ? 1 : 0) + (noneOption ? 1 : 0) + (hasFile ? 1 : 0);
+ if (argCount > 1) {
+ errormsg("jshell.err.option.or.filename", at.whole());
+ return false;
+ }
+ if (argCount == 0 && !retainOption) {
+ // no options or filename, show current setting
+ showSetStart();
+ return true;
+ }
+ if (hasFile) {
+ String init = readFile(fn, "/set start");
+ if (init == null) {
return false;
}
- editor = ed.toArray(new String[ed.size()]);
- editorWait = waitOption;
- fluffmsg("jshell.msg.set.editor.set", prog);
+ startup = init;
} else if (defaultOption) {
- if (waitOption) {
- errormsg("jshell.err.wait.applies.to.external.editor", at.whole());
- return false;
- }
- editor = null;
- } else if (argsRequired) {
- errormsg("jshell.err.set.editor.arg");
- return false;
+ startup = DEFAULT_STARTUP;
+ } else if (noneOption) {
+ startup = "";
+ }
+ if (retainOption) {
+ // retain startup setting
+ prefs.put(STARTUP_KEY, startup);
}
return true;
}
- // The sub-command: /set start <start-file>
- boolean setStart(String cmd, ArgTokenizer at, boolean argsRequired) {
- at.allowedOptions("-default", "-none");
- String fn = at.next();
- if (!checkOptionsAndRemainingInput(at)) {
- return false;
+ void showSetStart() {
+ String retained = prefs.get(STARTUP_KEY, null);
+ if (retained != null) {
+ showSetStart(true, retained);
}
- int argCount = at.optionCount() + ((fn != null) ? 1 : 0);
- if (argCount > 1 || argsRequired && argCount == 0) {
- errormsg("jshell.err.option.or.filename", at.whole());
- return false;
+ if (retained == null || !startup.equals(retained)) {
+ showSetStart(false, startup);
}
- if (fn != null) {
- String init = readFile(fn, cmd + " start");
- if (init == null) {
- return false;
- } else {
- startup = init;
- return true;
- }
- } else if (at.hasOption("-default")) {
- startup = DEFAULT_STARTUP;
- } else if (at.hasOption("-none")) {
- startup = "";
+ }
+
+ void showSetStart(boolean isRetained, String start) {
+ String cmd = "/set start" + (isRetained ? " -retain " : " ");
+ String stset;
+ if (start.equals(DEFAULT_STARTUP)) {
+ stset = cmd + "-default";
+ } else if (start.isEmpty()) {
+ stset = cmd + "-none";
+ } else {
+ stset = prefix("startup.jsh:\n" + start + "\n" + cmd + "startup.jsh", "");
}
- return true;
+ hard(stset);
}
boolean cmdClasspath(String arg) {
@@ -1559,17 +1708,18 @@
Command[] matches = commands.values().stream()
.filter(c -> c.command.startsWith(subject))
.toArray(size -> new Command[size]);
- at.mark();
- String sub = at.next();
- if (sub != null && matches.length == 1) {
+ if (matches.length == 1) {
String cmd = matches[0].command;
- switch (cmd) {
- case "/set":
- at.rewind();
- return printSubCommandHelp(cmd, at, "help.set.", SET_SUBCOMMANDS);
- case "/retain":
- at.rewind();
- return printSubCommandHelp(cmd, at, "help.retain.", RETAIN_SUBCOMMANDS);
+ if (cmd.equals("/set")) {
+ // Print the help doc for the specified sub-command
+ String which = subCommand(cmd, at, SET_SUBCOMMANDS);
+ if (which == null) {
+ return false;
+ }
+ if (!which.equals("_blank")) {
+ hardrb("help.set." + which);
+ return true;
+ }
}
}
if (matches.length > 0) {
@@ -1813,7 +1963,7 @@
String src = sb.toString();
Consumer<String> saveHandler = new SaveHandler(src, srcSet);
Consumer<String> errorHandler = s -> hard("Edit Error: %s", s);
- if (editor == null) {
+ if (editor == BUILT_IN_EDITOR) {
try {
EditPad.edit(errorHandler, src, saveHandler);
} catch (RuntimeException ex) {
@@ -1822,8 +1972,8 @@
return false;
}
} else {
- ExternalEditor.edit(editor, errorHandler, src, saveHandler, input,
- editorWait, this::hardrb);
+ ExternalEditor.edit(editor.cmd, errorHandler, src, saveHandler, input,
+ editor.wait, this::hardrb);
}
return true;
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/MessageHandler.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/MessageHandler.java Thu Oct 27 08:52:00 2016 -0700
@@ -37,5 +37,11 @@
void fluffmsg(String messageKey, Object... args);
+ void hard(String format, Object... args);
+
+ void hardmsg(String messageKey, Object... args);
+
void errormsg(String messageKey, Object... args);
+
+ boolean showFluff();
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Thu Oct 27 08:52:00 2016 -0700
@@ -52,12 +52,17 @@
jshell.err.no.such.command.or.snippet.id = No such command or snippet id: {0}
jshell.err.command.ambiguous = Command: ''{0}'' is ambiguous: {1}
-jshell.err.set.editor.arg = The ''/set editor'' command requires a path argument
jshell.msg.set.editor.set = Editor set to: {0}
+jshell.msg.set.editor.retain = Editor setting retained: {0}
jshell.err.cant.launch.editor = Cannot launch editor -- unexpected exception: {0}
jshell.msg.try.set.editor = Try /set editor to use external editor.
jshell.msg.press.return.to.leave.edit.mode = Press return to leave edit mode.
-jshell.err.wait.applies.to.external.editor = -wait applies to external editors, cannot be used with -default
+jshell.err.wait.applies.to.external.editor = -wait applies to external editors
+
+jshell.err.setting.to.retain.must.be.specified = The setting to retain must be specified -- {0}
+jshell.msg.set.show.mode.settings = \nTo show mode settings use ''/set prompt'', ''/set truncation'', ...\n\
+or use ''/set mode'' followed by the feedback mode name.
+jshell.err.continuation.prompt.required = Continuation prompt required -- {0}
jshell.msg.try.command.without.args = Try ''{0}'' without arguments.
jshell.msg.no.active = There are no active definitions.
@@ -104,12 +109,10 @@
jshell.err.mode.name = Expected a feedback mode name: {0}
jshell.err.missing.mode = Missing the feedback mode -- {0}
jshell.err.field.name = Expected a field name: {0} -- {1}
-jshell.err.missing.field = Missing the field name -- {0}
jshell.err.mode.unknown = No feedback mode named: {0} -- {1}
jshell.err.feedback.does.not.match.mode = Does not match any current feedback mode: {0} -- {1}
jshell.err.feedback.ambiguous.mode = Matches more then one current feedback mode: {0} -- {1}
-jshell.err.feedback.expected.format = Expected format missing -- {0}
jshell.err.feedback.must.be.quoted = Format ''{0}'' must be quoted -- {1}
jshell.err.feedback.not.a.valid.selector = Not a valid selector ''{0}'' in ''{1}'' -- {2}
jshell.err.feedback.multiple.sections = Selector kind in multiple sections of selector list ''{0}'' in ''{1}'' -- {2}
@@ -117,22 +120,25 @@
jshell.msg.feedback.new.mode = Created new feedback mode: {0}
jshell.msg.feedback.mode = Feedback mode: {0}
-jshell.msg.feedback.mode.following = The feedback mode should be one of the following:
+jshell.msg.feedback.mode.following = Available feedback modes:
+jshell.msg.feedback.retained.mode.following = Retained feedback modes:
+jshell.err.mode.creation = To create a new mode either the -command or the -quiet option must be used -- {0}
+jshell.err.mode.exists = Mode to be created already exists: {0} -- {1}
jshell.err.truncation.expected.length = Expected truncation length -- {0}
jshell.err.truncation.length.not.integer = Truncation length must be an integer: {0} -- {1}
jshell.err.not.valid.with.predefined.mode = Not valid with a predefined mode: {0} -- {1}
jshell.err.retained.feedback.mode.must.be.retained.or.predefined = \
-''/retain feedback <mode>'' requires that <mode> is predefined or has been retained with ''/retain mode'' -- {0}
+''/set feedback -retain <mode>'' requires that <mode> is predefined or has been retained with ''/set mode -retain'' -- {0}
jshell.err.unknown.option = Unknown option: {0} -- {1}
-jshell.err.default.option.or.program = Specify -default option or program, not both -- {0}
-jshell.err.option.or.filename = Specify either one option or a startup file name -- {0}
+jshell.err.default.option.or.program = Specify -default option, -delete option, or program -- {0}
+jshell.err.option.or.filename = Specify no more than one of -default, -none, or a startup file name -- {0}
jshell.err.unexpected.at.end = Unexpected arguments at end of command: {0} -- {1}
jshell.err.conflicting.options = Conflicting options -- {0}
jshell.err.cannot.delete.current.mode = The current feedback mode ''{0}'' cannot be deleted, use ''/set feedback'' first -- {1}
-jshell.err.cannot.delete.retained.mode = The retained feedback mode ''{0}'' cannot be deleted, use ''/retain feedback'' first -- {1}
+jshell.err.cannot.delete.retained.mode = The retained feedback mode ''{0}'' cannot be deleted, use ''/set feedback -retain'' first -- {1}
jshell.err.may.not.specify.options.and.snippets = Options and snippets must not both be used: {0}
jshell.err.no.such.snippets = No such snippet: {0}
jshell.err.the.snippet.cannot.be.used.with.this.command = This command does not accept the snippet ''{0}'' : {1}
@@ -374,36 +380,20 @@
The contents of the specified <file> become the default start-up snippets and commands.\n\n\
/set feedback <mode>\n\t\
Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\
-/set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\t\
+/set mode <mode> [<old-mode>] -command|-quiet|-delete\n\t\
Create or update a user-defined feedback mode, optionally copying from an existing mode.\n\n\
/set prompt <mode> "<prompt>" "<continuation-prompt>"\n\t\
Set the displayed prompts for a given feedback mode.\n\n\
/set truncation <mode> <length> <selector>...\n\t\
- Set the maximum length of a displayed value\n\
+ Set the maximum length of a displayed value.\n\n\
/set format <mode> <field> "<format>" <selector>...\n\t\
- Configure a feedback mode by setting the format of a field when the selector matchs.\n\n\
+ Configure a feedback mode by setting the format of a field when the selector matches.\n\n\
+/set\n\t\
+ Show editor, start, and feedback settings as /set commands.\n\t\
+ To show the settings of any of the above, omit the set value.\n\n\
To get more information about one of these forms, use /help with the form specified.\n\
For example: /help /set format
-help.retain.summary = retain jshell configuration information for subsequent sessions
-help.retain.args = editor|start|feedback|mode
-help.retain =\
-Retain jshell configuration information for future invocations of the jshell tool,\n\
-including: the external editor to use, the start-up definitions to use, the\n\
-configuration of a feedback mode, or the feedback mode to use.\n\
-\n\
-/retain editor [<command> <optional-arg>...]\n\t\
- Specify the command to launch for the /edit command.\n\t\
- The <command> is an operating system dependent string.\n\n\
-/retain start [<file>]\n\t\
- The contents of the specified <file> become the default start-up snippets and commands.\n\n\
-/retain feedback [<mode>]\n\t\
- Set the feedback mode describing displayed feedback for entered snippets and commands.\n\n\
-/retain mode <mode>\n\t\
- Create a user-defined feedback mode, optionally copying from an existing mode.\n\n\
-To get more information about one of these forms, use /help with the form specified.\n\
-For example: /help /retain feedback
-
help.quest.summary = get information about jshell
help.quest.args = [<command>|<subject>]
help.quest =\
@@ -467,11 +457,24 @@
possible fully qualified names based on the content of the specified classpath.\n\t\t\
The "<fix-shortcut>" is either Alt-F1 or Alt-Enter, depending on the platform.
+help.set._retain = \
+The '-retain' option saves a setting so that it is used in future sessions.\n\
+The -retain option can be used on the following forms of /set:\n\n\t\
+/set editor -retain\n\t\
+/set start -retain\n\t\
+/set feedback -retain\n\t\
+/set mode -retain\n\n\
+See these commands for more detail -- for example /help /set editor
+
help.set.format = \
-Set the format for reporting a snippet event.\n\
+Set the format for reporting a snippet event:\n\
\n\t\
/set format <mode> <field> "<format>" <selector>...\n\
\n\
+Show the format settings:\n\
+\n\t\
+/set format [<mode> [<field>]]\n\
+\n\
Where <mode> is the name of a previously defined feedback mode -- see '/help /set mode'.\n\
Where <field> is the name of context-specific format to define.\n\
Where <format> is a quoted string which will be the value of the field if one of\n\
@@ -541,13 +544,24 @@
/set format myformat action 'Update replaced' replaced-update\n\t\
/set format myformat display '{pre}{action} class {name}{post}' class-ok\n\t\
/set format myformat display '{pre}{action} variable {name}, reset to null{post}' replaced-vardecl,varinit-ok-update\n\n\
-Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n
+Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n\
+\n\
+The form without <format> shows the current format settings.\n\
+When the <mode> is specified only the format settings for that mode are shown.\n\
+When both the <mode> and <field> are specified only the format settings for that\n\
+mode and field are shown. Example:\n\t\
+/set format myformat\n\
+shows the format settings for the mode myformat\n
help.set.truncation = \
-Set the max length a displayed value.\n\
+Set the max length of a displayed value:\n\
\n\t\
/set truncation <mode> <length> <selector>...\n\
\n\
+Show the current truncation settings:\n\
+\n\t\
+/set truncation [<mode>]\n\
+\n\
Where <mode> is the name of a previously defined feedback mode -- see '/help /set mode'.\n\
Where <length> is an unsigned integer representing a maximum length.\n\
Where <selector> is only needed if you wish to fine-tune value truncation length\n\
@@ -571,63 +585,151 @@
/set trunc mymode 80\n\t\
/set truncation mymode 45 expression\n\t\
/set truncation mymode 0 vardecl-modified,replaced\n\n\
-Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n
+Note that subsequent selectors for a field may overwrite some or all of previous used selectors -- last one wins\n\
+\n\
+The form without <length> shows the truncation settings.\n\
+When the <mode> is specified only the truncation settings for that mode are shown.\n\
+Example:\n\t\
+/set truncation myformat\n\
+shows the truncation settings for the mode myformat\n
help.set.feedback = \
-Set the feedback mode describing displayed feedback for entered snippets and commands.\n\
+Set the feedback mode describing displayed feedback for entered snippets and commands:\n\
+\n\t\
+/set feedback [-retain] <mode>\n\
+\n\
+Retain the current feedback mode for future sessions:\n\
\n\t\
-/set feedback <mode>\n\
+/set feedback -retain\n\
+\n\
+Show the feedback mode and list available modes:\n\
+\n\t\
+/set feedback\n\
\n\
Where <mode> is the name of a previously defined feedback mode.\n\
You may use just enough letters to make it unique.\n\
User-defined modes can be added, see '/help /set mode'\n\
-Currently defined feedback modes:\n
+\n\
+When the -retain option is used, the setting will be used in this and future\n\
+runs of the jshell tool.\n\
+\n\
+The form without <mode> or -retain displays the current feedback mode and available modes.\n
help.set.mode = \
-Create a user-defined feedback mode, optionally copying from an existing mode.\n\
+Create a user-defined feedback mode, optionally copying from an existing mode:\n\
\n\t\
/set mode <mode> [<old-mode>] [-command|-quiet|-delete]\n\
+Retain a user-defined feedback mode for future sessions:\n\
+\n\t\
+/set mode -retain <mode>\n\
+\n\
+Delete a user-defined feedback mode:\n\
+\n\t\
+/set mode -delete [-retain] <mode>\n\
+\n\
+Show feedback mode settings:\n\
+\n\t\
+/set mode [<mode>]\n\
\n\
Where <new-mode> is the name of a mode you wish to create.\n\
Where <old-mode> is the name of a previously defined feedback mode.\n\
If <old-mode> is present, its settings are copied to the new mode.\n\
'-command' vs '-quiet' determines if informative/verifying command feedback is displayed.\n\
\n\
-Once the new mode is created, use '/set format' and '/set prompt' to configure it.\n\
-Use '/set feedback' to use the new mode.\n\
+Once the new mode is created, use '/set format', '/set prompt' and '/set truncation'\n\
+to configure it. Use '/set feedback' to use the new mode.\n\
+\n\
+When the -retain option is used, the mode (including its component prompt, format,\n\
+and truncation settings) will be used in this and future runs of the jshell tool.\n\
+When both -retain and -delete are used, the mode is deleted from the current\n\
+and future sessions.\n\
+\n\
+The form without options shows the mode settings.\n\
+When the <mode> is specified only the mode settings for that mode are shown.\n\
+Note: the settings for the mode include the settings for prompt, format, and\n\
+truncation -- so these are displayed as well.\n\
+Example:\n\t\
+/set mode myformat\n\
+shows the mode, prompt, format, and truncation settings for the mode myformat\n
help.set.prompt = \
-Set the prompts. Both the normal prompt and the continuation-prompt must be set.\n\
+Set the prompts. Both the normal prompt and the continuation-prompt must be set:\n\
\n\t\
/set prompt <mode> \"<prompt>\" \"<continuation-prompt>\"\n\
\n\
+Show the normal prompt and the continuation-prompts:\n\
+\n\t\
+/set prompt [<mode>]\n\
+\n\
Where <mode> is the name of a previously defined feedback mode.\n\
Where <prompt> and <continuation-prompt> are quoted strings printed as input prompts;\n\
Both may optionally contain '%s' which will be substituted with the next snippet id --\n\
note that what is entered may not be assigned that id, for example it may be an error or command.\n\
-The continuation-prompt is used on the second and subsequent lines of a multi-line snippet.\n
+The continuation-prompt is used on the second and subsequent lines of a multi-line snippet.\n\
+\n\
+The form without <prompt> shows the currently set prompts.\n\
+When the <mode> is specified only the prompts for that mode are shown.\n\
+Example:\n\t\
+/set prompt myformat\n\
+shows the prompts set for the mode myformat\n
help.set.editor =\
-Specify the command to launch for the /edit command.\n\
+Specify the command to launch for the /edit command:\n\
+\n\t\
+/set editor [-retain] [-wait] <command>\n\
+\n\t\
+/set editor [-retain] -default\n\
\n\t\
-/set editor [-wait] <command>|-default\n\
+/set editor [-retain] -delete\n\
+\n\
+Retain the current editor setting for future sessions:\n\
+\n\t\
+/set editor -retain\n\
+\n\
+Show the command to launch for the /edit command:\n\
+\n\t\
+/set editor\n\
\n\
The <command> is an operating system dependent string.\n\
The <command> may include space-separated arguments (such as flags)\n\n\
If the -default option is specified, the built-in default editor will be used.\n\n\
-Otherwise an external editor should be specified in <command>. When <command>\n\
+If the -delete option is specified, previous settings are ignored -- the editor\n\
+settings are initialized as when starting the jshell tool. Specifically, if there\n\
+is a retained setting it is used (unless both -retain and -delete are specified --\n\
+which deletes the retained setting), if one of these environment variables is set\n\
+it will be used: JSHELLEDITOR, VISUAL, or EDITOR (in that order). Otherwise the\n\
+built-in default editor will be used.\n\n\
+If <command> is specified, it will be used as the external editor. The <command>\n\
+consists of the program and zero or more program arguments. When <command>\n\
is used, the temporary file to edit will be appended as the last argument.\n\
Normally, edit mode will last until the external editor exits. Some external editors\n\
will exit immediately (for example, if the edit window exists) either external editor\n\
flags should be used to prevent immediate exit, or the -wait option should be used to\n\
prompt the user to indicate when edit mode should end.\n\n\
Note: while in edit mode no command inputs are seen. After leaving edit mode changes\n\
-to the edited snippets are not seen.
+to the edited snippets are not seen.\n\
+\n\
+When the -retain option is used, the setting will be used in this and future\n\
+runs of the jshell tool.\n\
+\n\
+The form without <command> or options shows the editor setting.\n
help.set.start =\
-Set the start-up configuration -- a sequence of snippets and commands read at start-up.\n\
+Set the start-up configuration -- a sequence of snippets and commands read at start-up:\n\
+\n\t\
+/set start [-retain] <file>\n\
+\n\t\
+/set start [-retain] -default\n\
\n\t\
-/set start <file>|-default|-none\n\
+/set start [-retain] -none\n\
+\n\
+Retain the start-up configuration for future sessions:\n\
+\n\t\
+/set start -retain\n\
+\n\
+Show the start-up setting:\n\
+\n\t\
+/set start\n\
\n\
The contents of the specified <file> become the start-up snippets and commands used\n\
when the /reset or /reload commands are used in this session.\n\
@@ -637,59 +739,14 @@
or commands will be used.\n\
This command is good for testing the start-up settings. To retain them for future\n\
runs of the jshell tool use the command:\n\t\
-/retain start\n
-
-help.retain.feedback = \
-Retain which feedback mode to use for displayed feedback for entered snippets and commands.\n\
-This feedback mode will be used in this and future sessions of the jshell tool.\n\
-\n\t\
-/retain feedback [<mode>]\n\
-\n\
-Where <mode> is the name of a previously defined feedback mode.\n\
-You may use just enough letters to make it unique.\n\
-If the <mode> is not specified, this command retains the current mode (as set\n\
-with the most recent /set feedback or /retain feedback command.)\n\
-
-help.retain.mode = \
-Retain the existence and configuration of a user-defined feedback mode.\n\
-This mode will be available in this and future sessions of the jshell tool.
-\n\t\
-/retain mode <mode>\n\
+/set start -retain\n\
\n\
-Where <mode> is the name of a mode you wish to retain.\n\
-The <mode> must previously have been created with /set mode and\n\
-configured as desired with /set prompt, /set format, and /set truncation.\n
-
-help.retain.editor =\
-Retain the command to launch for the /edit command. This command will be invoked when\n\
-the /edit command is used in this and future sessions of the jshell tool.\n\
-\n\t\
-/retain editor [<command>|-default]\n\
+When the -retain option is used, the setting will be used in this and future\n\
+runs of the jshell tool.\n\
\n\
-If <command> is specified, it is an operating system dependent string which\n\
-may include space-separated arguments (such as flags). When /edit is used, the\n\
-temporary file to edit will be appended as the last argument.\n\
-If instead the -default option is specified, the built-in default editor will be used.\n\
-If neither is specified, the editor set in the last /set editor or /retain editor\n\
-command will be used.\n\
-The editor will be retained and used in this and future runs of the jshell tool.
-
-help.retain.start =\
-Retain the start-up configuration -- a sequence of snippets and commands read\n\
-at start-up.\n\
-\n\t\
-/retain start [<file>|-default|-none]\n\
-\n\
-If <file> is specified, the contents of the specified <file> become the\n\
-start-up snippets\n\
-and commands.\n\
-If instead the -default option is specified, the predefined start-up snippets\n\
-will be the start-up.\n\
-If the -none option is used, the start-up will be empty -- no start-up snippets\n\
-or commands will be used.\n\
-If none of these is specified, the start-up is the last specified in a\n\
-''/set start'' or ''/retain start'' command.\n\
-The start-up will be retained and used when the jshell tool is started or reset
+The form without <file> or options shows the start-up setting.\n\
+Note: if the start-up was last set from a file, this is shown with the\n\
+contents of the file followed by a 'set start' command.
startup.feedback = \
/set mode verbose -command \n\
@@ -773,6 +830,8 @@
\n\
/set mode silent -quiet \n\
/set prompt silent '-> ' '>> ' \n\
+/set truncation silent 80\n\
+/set truncation silent 1000 varvalue,expression\n\
/set format silent pre '| ' \n\
/set format silent post '%n' \n\
/set format silent errorpre '| ' \n\
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Thu Oct 27 08:52:00 2016 -0700
@@ -28,6 +28,7 @@
import jdk.jshell.spi.ExecutionControl;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.io.InterruptedIOException;
import java.io.PrintStream;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -167,6 +168,10 @@
* user input cannot use {@code System.in} as the input stream for
* the remote process.
* <p>
+ * The {@code read} method of the {@code InputStream} may throw the {@link InterruptedIOException}
+ * to signal the user canceled the input. The currently running snippet will be automatically
+ * {@link JShell#stop() stopped}.
+ * <p>
* The default, if this is not set, is to provide an empty input stream
* -- {@code new ByteArrayInputStream(new byte[0])}.
*
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/PipeInputStream.java Thu Oct 27 08:52:00 2016 -0700
@@ -42,7 +42,7 @@
@Override
public synchronized int read() throws IOException {
- if (start == end) {
+ if (start == end && !closed) {
inputNeeded();
}
while (start == end) {
@@ -62,6 +62,32 @@
}
}
+ @Override
+ public synchronized int read(byte[] b, int off, int len) throws IOException {
+ if (b == null) {
+ throw new NullPointerException();
+ } else if (off < 0 || len < 0 || len > b.length - off) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return 0;
+ }
+
+ int c = read();
+ if (c == -1) {
+ return -1;
+ }
+ b[off] = (byte)c;
+
+ int totalRead = 1;
+ while (totalRead < len && start != end) {
+ int r = read();
+ if (r == (-1))
+ break;
+ b[off + totalRead++] = (byte) r;
+ }
+ return totalRead;
+ }
+
protected void inputNeeded() throws IOException {}
private synchronized void write(int b) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java Thu Oct 27 08:52:00 2016 -0700
@@ -28,6 +28,7 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.InterruptedIOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
@@ -42,6 +43,7 @@
import com.sun.jdi.VirtualMachine;
import jdk.jshell.spi.ExecutionControl;
+import jdk.jshell.spi.ExecutionControl.ExecutionControlException;
/**
@@ -54,6 +56,10 @@
*/
public class Util {
+ private static final int TAG_DATA = 0;
+ private static final int TAG_CLOSED = 1;
+ private static final int TAG_EXCEPTION = 2;
+
// never instanciated
private Util() {}
@@ -131,6 +137,25 @@
inputSignal.write('1');
inputSignal.flush();
}
+ @Override
+ public synchronized int read() throws IOException {
+ int tag = super.read();
+ switch (tag) {
+ case TAG_DATA: return super.read();
+ case TAG_CLOSED: close(); return -1;
+ case TAG_EXCEPTION:
+ int len = (super.read() << 0) + (super.read() << 8) + (super.read() << 16) + (super.read() << 24);
+ byte[] message = new byte[len];
+ for (int i = 0; i < len; i++) {
+ message[i] = (byte) super.read();
+ }
+ throw new IOException(new String(message, "UTF-8"));
+ case -1:
+ return -1;
+ default:
+ throw new IOException("Internal error: unrecognized message tag: " + tag);
+ }
+ }
};
inputs.put(e.getKey(), inputPipe.createOutput());
e.getValue().accept(inputPipe);
@@ -163,6 +188,7 @@
public static ExecutionControl remoteInputOutput(InputStream input, OutputStream output,
Map<String, OutputStream> outputStreamMap, Map<String, InputStream> inputStreamMap,
BiFunction<ObjectInput, ObjectOutput, ExecutionControl> factory) throws IOException {
+ ExecutionControl[] result = new ExecutionControl[1];
Map<String, OutputStream> augmentedStreamMap = new HashMap<>(outputStreamMap);
ObjectOutput commandOut = new ObjectOutputStream(Util.multiplexingOutputStream("$command", output));
for (Entry<String, InputStream> e : inputStreamMap.entrySet()) {
@@ -172,7 +198,28 @@
@Override
public void write(int b) throws IOException {
//value ignored, just a trigger to read from the input
- inTarget.write(in.read());
+ try {
+ int r = in.read();
+ if (r == (-1)) {
+ inTarget.write(TAG_CLOSED);
+ } else {
+ inTarget.write(new byte[] {TAG_DATA, (byte) r});
+ }
+ } catch (InterruptedIOException exc) {
+ try {
+ result[0].stop();
+ } catch (ExecutionControlException ex) {
+ debug(ex, "$" + e.getKey() + "-input-requested.write");
+ }
+ } catch (IOException exc) {
+ byte[] message = exc.getMessage().getBytes("UTF-8");
+ inTarget.write(TAG_EXCEPTION);
+ inTarget.write((message.length >> 0) & 0xFF);
+ inTarget.write((message.length >> 8) & 0xFF);
+ inTarget.write((message.length >> 16) & 0xFF);
+ inTarget.write((message.length >> 24) & 0xFF);
+ inTarget.write(message);
+ }
}
});
}
@@ -180,7 +227,7 @@
OutputStream commandInTarget = commandIn.createOutput();
augmentedStreamMap.put("$command", commandInTarget);
new DemultiplexInput(input, augmentedStreamMap, Arrays.asList(commandInTarget)).start();
- return factory.apply(new ObjectInputStream(commandIn), commandOut);
+ return result[0] = factory.apply(new ObjectInputStream(commandIn), commandOut);
}
/**
@@ -198,4 +245,13 @@
}
}
+ /**
+ * Log a serious unexpected internal exception.
+ *
+ * @param ex the exception
+ * @param where a description of the context of the exception
+ */
+ private static void debug(Throwable ex, String where) {
+ // Reserved for future logging
+ }
}
--- a/langtools/test/Makefile Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/Makefile Thu Oct 27 08:52:00 2016 -0700
@@ -157,11 +157,6 @@
-refvmoptions:-Xbootclasspath/p:$(TESTBOOTCLASSPATH)
endif
-ifeq ($(ARCH_DATA_MODEL),32)
- # Set the GC options for test vms
- JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
- JTREG_OPTIONS += $(JTREG_GC_OPTION)
-endif
# Set the max memory for jtreg target test JVMs
JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx768m
JTREG_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION)
@@ -256,6 +251,17 @@
JCK_COMPILER_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-compiler
JCK_RUNTIME_OUTPUT_DIR = $(ABS_TEST_OUTPUT_DIR)/jck-runtime-Xcompile
+# Is the test JVM 32-bit?
+DATA_MODEL := \
+ $(shell $(JT_JAVA)/bin/java -XshowSettings:properties -version 2>&1 | \
+ grep 'sun\.arch\.data\.model' | \
+ awk '{print $$3}')
+ifeq ($(DATA_MODEL), 32)
+ # Set the GC options for test vms having a smaller address space
+ JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC
+ JTREG_OPTIONS += $(JTREG_GC_OPTION)
+endif
+
# Default make rule -- warning, may take a while
all: $(JPRT_CLEAN) jtreg-tests jck-compiler-tests jck-runtime-tests $(JPRT_ARCHIVE_BUNDLE) all-summary
@echo "Testing completed successfully"
--- a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java Thu Oct 27 08:52:00 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756
+ * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8151921
* @summary Verify that the output has the right javascript.
* @author jamieh
* @library ../lib
@@ -54,11 +54,12 @@
checkOutput("index.html", true,
"<script type=\"text/javascript\">\n"
- + " targetPage = \"\" + window.location.search;\n"
- + " if (targetPage != \"\" && targetPage != \"undefined\")\n"
- + " targetPage = targetPage.substring(1);\n"
- + " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n"
- + " targetPage = \"undefined\";\n"
+ + " tmpTargetPage = \"\" + window.location.search;\n"
+ + " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n"
+ + " tmpTargetPage = tmpTargetPage.substring(1);\n"
+ + " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n"
+ + " tmpTargetPage = \"undefined\";\n"
+ + " targetPage = tmpTargetPage;\n"
+ " function validURL(url) {\n"
+ " try {\n"
+ " url = decodeURIComponent(url);\n"
--- a/langtools/test/jdk/javadoc/doclet/testJavascript/TestJavascript.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/javadoc/doclet/testJavascript/TestJavascript.java Thu Oct 27 08:52:00 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985
+ * @bug 4665566 4855876 7025314 8012375 8015997 8016328 8024756 8148985 8151921
* @summary Verify that the output has the right javascript.
* @author jamieh
* @library ../lib
@@ -54,11 +54,12 @@
checkOutput("index.html", true,
"<script type=\"text/javascript\">\n"
- + " targetPage = \"\" + window.location.search;\n"
- + " if (targetPage != \"\" && targetPage != \"undefined\")\n"
- + " targetPage = targetPage.substring(1);\n"
- + " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))\n"
- + " targetPage = \"undefined\";\n"
+ + " tmpTargetPage = \"\" + window.location.search;\n"
+ + " if (tmpTargetPage != \"\" && tmpTargetPage != \"undefined\")\n"
+ + " tmpTargetPage = tmpTargetPage.substring(1);\n"
+ + " if (tmpTargetPage.indexOf(\":\") != -1 || (tmpTargetPage != \"\" && !validURL(tmpTargetPage)))\n"
+ + " tmpTargetPage = \"undefined\";\n"
+ + " targetPage = tmpTargetPage;\n"
+ " function validURL(url) {\n"
+ " try {\n"
+ " url = decodeURIComponent(url);\n"
--- a/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java Thu Oct 27 08:52:00 2016 -0700
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 8159305
+ * @bug 8159305 8167383
* @summary Tests elements filtering options
* @modules
* jdk.javadoc/jdk.javadoc.internal.api
@@ -73,6 +73,10 @@
"--module", "m1", "--show-module-contents", "api");
checkModuleMode("API");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkPackagesNotIncluded("pro", "pqe");
}
@Test
@@ -81,6 +85,10 @@
"--module", "m1", "--show-module-contents", "all");
checkModuleMode("ALL");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub", "pqe");
+ checkPackagesNotIncluded("pro");
}
@Test
@@ -92,6 +100,7 @@
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
+ checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
}
@@ -102,9 +111,10 @@
"--show-packages", "all");
checkModulesSpecified("m1");
checkModulesIncluded("m1");
- checkPackagesIncluded("pub", "pro");
+ checkPackagesIncluded("pub", "pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested",
+ "pqe.A", "pqe.A.ProtectedNested", "pqe.A.PublicNested",
"pro.A", "pro.A.ProtectedNested", "pro.A.PublicNested");
}
@@ -221,6 +231,7 @@
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
+ checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.PublicNested");
checkMembers(Visibility.PUBLIC);
@@ -235,6 +246,7 @@
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
+ checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
checkMembers(Visibility.PROTECTED);
@@ -250,6 +262,7 @@
checkModulesSpecified("m1");
checkModulesIncluded("m1");
checkPackagesIncluded("pub");
+ checkPackagesNotIncluded("pqe", "pro");
checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
checkMembers(Visibility.PROTECTED);
@@ -264,10 +277,10 @@
checkModuleMode("ALL");
checkModulesSpecified("m1");
checkModulesIncluded("m1");
- checkPackagesIncluded("pub");
- checkPackagesIncluded("pro");
+ checkPackagesIncluded("pub", "pqe", "pro");
checkTypesIncluded("pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested",
"pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
+ "pqe.A", "pqe.A.Nested", "pqe.A.ProtectedNested", "pqe.A.PublicNested",
"pro.B", "pro.B.Nested", "pro.B.ProtectedNested", "pro.B.PublicNested",
"pro.A", "pro.A.Nested", "pro.A.ProtectedNested", "pro.A.PublicNested");
@@ -283,12 +296,13 @@
checkModuleMode("ALL");
checkModulesSpecified("m1");
checkModulesIncluded("m1");
- checkPackagesIncluded("pub");
- checkPackagesIncluded("pro");
+ checkPackagesIncluded("pub", "pqe", "pro");
checkTypesIncluded("pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
"pub.B.PublicNested",
"pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
"pub.A.PublicNested",
+ "pqe.A", "pqe.A.PrivateNested", "pqe.A.Nested", "pqe.A.ProtectedNested",
+ "pqe.A.PublicNested",
"pro.B", "pro.B.PrivateNested", "pro.B.Nested", "pro.B.ProtectedNested",
"pro.B.PublicNested",
"pro.A", "pro.A.PrivateNested", "pro.A.Nested", "pro.A.ProtectedNested",
@@ -365,8 +379,17 @@
.classes(createClass("pub", "B", false))
.classes(createClass("pro", "A", true))
.classes(createClass("pro", "B", false))
+ .classes(createClass("pqe", "A", true))
.exports("pub")
+ .exportsTo("pqe", "m2")
.write(src);
+
+ ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
+ mb2.comment("The second module")
+ .classes(createClass("m2pub", "A", true))
+ .requires("m1")
+ .write(src);
+
return src.toString();
}
--- a/langtools/test/jdk/javadoc/tool/modules/Modules.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/javadoc/tool/modules/Modules.java Thu Oct 27 08:52:00 2016 -0700
@@ -222,7 +222,10 @@
.classes("package pkg2; /** @see pkg1.A */ public class B { }")
.write(src);
+ Path out = base.resolve("out-1");
+ Files.createDirectories(out);
String log = new JavadocTask(tb)
+ .outdir(out)
.options("--module-source-path", src.toString(),
"--module-path", modulePath.toString(),
"--module", "m2")
@@ -233,7 +236,10 @@
throw new Exception("Error not found");
}
+ out = base.resolve("out-2");
+ Files.createDirectories(out);
new JavadocTask(tb)
+ .outdir(out)
.options("--module-source-path", src.toString(),
"--module-path", modulePath.toString(),
"--add-modules", "m1",
--- a/langtools/test/jdk/jshell/CommandCompletionTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/CommandCompletionTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -54,7 +54,7 @@
public void testCommand() {
assertCompletion("/deb|", false);
- assertCompletion("/re|", false, "/reload ", "/reset ", "/retain ");
+ assertCompletion("/re|", false, "/reload ", "/reset ");
assertCompletion("/h|", false, "/help ", "/history ");
}
@@ -195,34 +195,6 @@
);
}
- public void testRetain() throws IOException {
- List<String> p1 = listFiles(Paths.get(""));
- FileSystems.getDefault().getRootDirectories().forEach(s -> p1.add(s.toString()));
- Collections.sort(p1);
-
- String[] modes = {"concise ", "normal ", "silent ", "verbose "};
- test(false, new String[] {"--no-startup"},
- a -> assertCompletion(a, "/ret|", false, "/retain "),
- a -> assertCompletion(a, "/retain |", false, "editor ", "feedback ", "mode ", "start "),
-
- // /retain editor
- a -> assertCompletion(a, "/retain e|", false, "editor "),
- a -> assertCompletion(a, "/retain editor |", false, p1.toArray(new String[p1.size()])),
-
- // /retain feedback
- a -> assertCompletion(a, "/retain fe|", false, "feedback "),
- a -> assertCompletion(a, "/retain fe |", false, modes),
-
- // /retain mode
- a -> assertCompletion(a, "/retain mo|", false, "mode "),
- a -> assertCompletion(a, "/retain mo |", false, modes),
-
- // /retain start
- a -> assertCompletion(a, "/retain st|", false, "start "),
- a -> assertCompletion(a, "/retain st |", false, p1.toArray(new String[p1.size()]))
- );
- }
-
private void createIfNeeded(Path file) throws IOException {
if (!Files.exists(file))
Files.createFile(file);
--- a/langtools/test/jdk/jshell/ExternalEditorTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/ExternalEditorTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -193,7 +193,6 @@
@Test
public void setUnknownEditor() {
test(
- a -> assertCommand(a, "/set editor", "| The '/set editor' command requires a path argument"),
a -> assertCommand(a, "/set editor UNKNOWN", "| Editor set to: UNKNOWN"),
a -> assertCommand(a, "int a;", null),
a -> assertCommandOutputStartsWith(a, "/ed 1",
--- a/langtools/test/jdk/jshell/KullaTesting.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/KullaTesting.java Thu Oct 27 08:52:00 2016 -0700
@@ -21,7 +21,10 @@
* questions.
*/
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.io.PrintStream;
import java.io.StringWriter;
import java.lang.reflect.Method;
@@ -83,7 +86,7 @@
private SourceCodeAnalysis analysis = null;
private JShell state = null;
- private TestingInputStream inStream = null;
+ private InputStream inStream = null;
private ByteArrayOutputStream outStream = null;
private ByteArrayOutputStream errStream = null;
@@ -106,7 +109,11 @@
}
public void setInput(String s) {
- inStream.setInput(s);
+ setInput(new ByteArrayInputStream(s.getBytes()));
+ }
+
+ public void setInput(InputStream in) {
+ inStream = in;
}
public String getOutput() {
@@ -159,11 +166,27 @@
}
public void setUp(Consumer<JShell.Builder> bc) {
- inStream = new TestingInputStream();
+ InputStream in = new InputStream() {
+ @Override
+ public int read() throws IOException {
+ assertNotNull(inStream);
+ return inStream.read();
+ }
+ @Override
+ public int read(byte[] b) throws IOException {
+ assertNotNull(inStream);
+ return inStream.read(b);
+ }
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ assertNotNull(inStream);
+ return inStream.read(b, off, len);
+ }
+ };
outStream = new ByteArrayOutputStream();
errStream = new ByteArrayOutputStream();
JShell.Builder builder = JShell.builder()
- .in(inStream)
+ .in(in)
.out(new PrintStream(outStream))
.err(new PrintStream(errStream));
bc.accept(builder);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/PipeInputStreamTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,71 @@
+/*
+ * 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 8167461
+ * @summary Verify PipeInputStream works.
+ * @modules jdk.compiler/com.sun.tools.javac.util
+ * jdk.jshell
+ * @run testng PipeInputStreamTest
+ */
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.testng.annotations.Test;
+
+import com.sun.tools.javac.util.Pair;
+
+import static org.testng.Assert.*;
+
+@Test
+public class PipeInputStreamTest {
+
+ public void testReadArrayNotBlocking() throws Exception {
+ Pair<InputStream, OutputStream> streams = createPipeStream();
+ InputStream in = streams.fst;
+ OutputStream out = streams.snd;
+ out.write('a');
+ byte[] data = new byte[12];
+ assertEquals(in.read(data), 1);
+ assertEquals(data[0], 'a');
+ out.write('a'); out.write('b'); out.write('c');
+ assertEquals(in.read(data), 3);
+ assertEquals(data[0], 'a');
+ assertEquals(data[1], 'b');
+ assertEquals(data[2], 'c');
+ }
+
+ private Pair<InputStream, OutputStream> createPipeStream() throws Exception {
+ Class<?> pipeStreamClass = Class.forName("jdk.jshell.execution.PipeInputStream");
+ Constructor<?> c = pipeStreamClass.getDeclaredConstructor();
+ c.setAccessible(true);
+ Object pipeStream = c.newInstance();
+ Method createOutputStream = pipeStreamClass.getDeclaredMethod("createOutput");
+ createOutputStream.setAccessible(true);
+ return Pair.of((InputStream) pipeStream, (OutputStream) createOutputStream.invoke(pipeStream));
+ }
+
+}
--- a/langtools/test/jdk/jshell/ReplToolTesting.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/ReplToolTesting.java Thu Oct 27 08:52:00 2016 -0700
@@ -93,6 +93,7 @@
private Map<String, ImportInfo> imports;
private boolean isDefaultStartUp = true;
private Preferences prefs;
+ private Map<String, String> envvars;
public JShellTool repl = null;
@@ -232,6 +233,11 @@
@BeforeMethod
public void setUp() {
prefs = new MemoryPreferences();
+ envvars = new HashMap<>();
+ }
+
+ protected void setEnvVar(String name, String value) {
+ envvars.put(name, value);
}
public void testRaw(Locale locale, String[] args, ReplTest... tests) {
@@ -247,9 +253,11 @@
new PrintStream(cmdout),
new PrintStream(cmderr),
new PrintStream(console),
+ userin,
new PrintStream(userout),
new PrintStream(usererr),
prefs,
+ envvars,
locale);
repl.testPrompt = true;
try {
@@ -462,7 +470,8 @@
private List<String> computeCompletions(String code, boolean isSmart) {
JShellTool js = this.repl != null ? this.repl
- : new JShellTool(null, null, null, null, null, null, prefs, Locale.ROOT);
+ : new JShellTool(null, null, null, null, null, null, null,
+ prefs, envvars, Locale.ROOT);
int cursor = code.indexOf('|');
code = code.replace("|", "");
assertTrue(cursor > -1, "'|' not found: " + code);
--- a/langtools/test/jdk/jshell/StartOptionTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/StartOptionTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -37,6 +37,7 @@
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
+import java.util.HashMap;
import java.util.Locale;
import java.util.function.Consumer;
@@ -63,9 +64,11 @@
new PrintStream(cmdout),
new PrintStream(cmderr),
new PrintStream(console),
+ null,
new PrintStream(userout),
new PrintStream(usererr),
new ReplToolTesting.MemoryPreferences(),
+ new HashMap<>(),
Locale.ROOT);
}
--- a/langtools/test/jdk/jshell/ToolBasicTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/ToolBasicTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -431,12 +431,12 @@
(a) -> assertMethod(a, "void f() {}", "()V", "f"),
(a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
(a) -> assertCommand(a, "/save " + startUpFile.toString(), null),
- (a) -> assertCommand(a, "/retain start " + startUpFile.toString(), null)
+ (a) -> assertCommand(a, "/set start -retain " + startUpFile.toString(), null)
);
Path unknown = compiler.getPath("UNKNOWN");
test(
- (a) -> assertCommandOutputStartsWith(a, "/retain start " + unknown.toString(),
- "| File '" + unknown + "' for '/retain start' is not found.")
+ (a) -> assertCommandOutputStartsWith(a, "/set start -retain " + unknown.toString(),
+ "| File '" + unknown + "' for '/set start' is not found.")
);
test(false, new String[0],
(a) -> {
--- a/langtools/test/jdk/jshell/ToolCommandOptionTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/ToolCommandOptionTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8157395 8157393 8157517 8158738 8167128
+ * @bug 8157395 8157393 8157517 8158738 8167128 8163840 8167637
* @summary Tests of jshell comand options, and undoing operations
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build ToolCommandOptionTest ReplToolTesting
@@ -124,50 +124,118 @@
(a) -> assertCommand(a, "/set editor -furball -mattress",
"| Unknown option: -furball -mattress -- /set editor -furball -mattress"),
(a) -> assertCommand(a, "/set editor -default prog",
- "| Specify -default option or program, not both -- /set editor -default prog"),
+ "| Specify -default option, -delete option, or program -- /set editor -default prog"),
(a) -> assertCommand(a, "/set editor prog",
"| Editor set to: prog"),
(a) -> assertCommand(a, "/set editor prog -default",
- "| Editor set to: prog"),
+ "| Editor set to: prog -default"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor prog -default"),
(a) -> assertCommand(a, "/se ed prog -furball",
- "| Editor set to: prog"),
+ "| Editor set to: prog -furball"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor prog -furball"),
+ (a) -> assertCommand(a, "/se ed -delete",
+ "| Editor set to: -default"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -default"),
(a) -> assertCommand(a, "/set editor prog arg1 -furball arg3 -default arg4",
- "| Editor set to: prog"),
+ "| Editor set to: prog arg1 -furball arg3 -default arg4"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor prog arg1 -furball arg3 -default arg4"),
(a) -> assertCommand(a, "/set editor -default",
- ""),
+ "| Editor set to: -default"),
(a) -> assertCommand(a, "/se edi -def",
- ""),
+ "| Editor set to: -default"),
(a) -> assertCommand(a, "/set editor",
- "| The '/set editor' command requires a path argument")
+ "| /set editor -default")
);
}
public void retainEditorTest() {
test(
- (a) -> assertCommand(a, "/retain editor -furball",
- "| Unknown option: -furball -- /retain editor -furball"),
- (a) -> assertCommand(a, "/retain editor -furball prog",
- "| Unknown option: -furball -- /retain editor -furball prog"),
- (a) -> assertCommand(a, "/retain editor -furball -mattress",
- "| Unknown option: -furball -mattress -- /retain editor -furball -mattress"),
- (a) -> assertCommand(a, "/retain editor -default prog",
- "| Specify -default option or program, not both -- /retain editor -default prog"),
- (a) -> assertCommand(a, "/retain editor -default -wait",
- "| -wait applies to external editors, cannot be used with -default"),
- (a) -> assertCommand(a, "/retain editor prog",
+ (a) -> assertCommand(a, "/set editor -retain -furball",
+ "| Unknown option: -furball -- /set editor -retain -furball"),
+ (a) -> assertCommand(a, "/set editor -retain -furball prog",
+ "| Unknown option: -furball -- /set editor -retain -furball prog"),
+ (a) -> assertCommand(a, "/set editor -retain -furball -mattress",
+ "| Unknown option: -furball -mattress -- /set editor -retain -furball -mattress"),
+ (a) -> assertCommand(a, "/set editor -retain -default prog",
+ "| Specify -default option, -delete option, or program -- /set editor -retain -default prog"),
+ (a) -> assertCommand(a, "/set editor -retain -wait",
+ "| -wait applies to external editors"),
+ (a) -> assertCommand(a, "/set editor -retain -default -wait",
+ "| -wait applies to external editors"),
+ (a) -> assertCommand(a, "/set editor -retain prog",
+ "| Editor set to: prog\n" +
+ "| Editor setting retained: prog"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain prog"),
+ (a) -> assertCommand(a, "/se ed other",
+ "| Editor set to: other"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain prog\n" +
+ "| /set editor other"),
+ (a) -> assertCommand(a, "/se ed -delete",
"| Editor set to: prog"),
- (a) -> assertCommand(a, "/retain editor prog -default",
- "| Editor set to: prog"),
- (a) -> assertCommand(a, "/ret ed prog -furball",
- "| Editor set to: prog"),
- (a) -> assertCommand(a, "/retain editor prog arg1 -furball arg3 -default arg4",
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain prog"),
+ (a) -> assertCommand(a, "/set editor -retain prog -default",
+ "| Editor set to: prog -default\n" +
+ "| Editor setting retained: prog -default"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain prog -default"),
+ (a) -> assertCommand(a, "/se ed -retain prog -furball",
+ "| Editor set to: prog -furball\n" +
+ "| Editor setting retained: prog -furball"),
+ (a) -> assertCommand(a, "/set editor -retain prog arg1 -furball arg3 -default arg4",
+ "| Editor set to: prog arg1 -furball arg3 -default arg4\n" +
+ "| Editor setting retained: prog arg1 -furball arg3 -default arg4"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain prog arg1 -furball arg3 -default arg4"),
+ (a) -> assertCommand(a, "/set editor -retain -default",
+ "| Editor set to: -default\n" +
+ "| Editor setting retained: -default"),
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain -default"),
+ (a) -> assertCommand(a, "/se e -ret -def",
+ "| Editor set to: -default\n" +
+ "| Editor setting retained: -default"),
+ (a) -> assertCommand(a, "/set editor -retain",
+ "| Editor setting retained: -default")
+ );
+ }
+
+ public void setEditorEnvTest() {
+ setEnvVar("EDITOR", "best one");
+ setEditorEnvSubtest();
+ setEnvVar("EDITOR", "not this");
+ setEnvVar("VISUAL", "best one");
+ setEditorEnvSubtest();
+ setEnvVar("VISUAL", "not this");
+ setEnvVar("JSHELLEDITOR", "best one");
+ setEditorEnvSubtest();
+ }
+
+ private void setEditorEnvSubtest() {
+ test(
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor best one"),
+ (a) -> assertCommand(a, "/set editor prog",
"| Editor set to: prog"),
- (a) -> assertCommand(a, "/retain editor -default",
- ""),
- (a) -> assertCommand(a, "/reta edi -def",
- ""),
- (a) -> assertCommand(a, "/retain editor",
- "")
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor prog"),
+ (a) -> assertCommand(a, "/set editor -delete",
+ "| Editor set to: best one"),
+ (a) -> assertCommand(a, "/set editor -retain stored editor",
+ "| Editor set to: stored editor\n" +
+ "| Editor setting retained: stored editor")
+ );
+ test(
+ (a) -> assertCommand(a, "/set editor",
+ "| /set editor -retain stored editor"),
+ (a) -> assertCommand(a, "/set editor -delete -retain",
+ "| Editor set to: best one")
);
}
@@ -182,45 +250,56 @@
(a) -> assertCommand(a, "/set start -furball -mattress",
"| Unknown option: -furball -mattress -- /set start -furball -mattress"),
(a) -> assertCommand(a, "/set start foo -default",
- "| Specify either one option or a startup file name -- /set start foo -default"),
+ "| Specify no more than one of -default, -none, or a startup file name -- /set start foo -default"),
(a) -> assertCommand(a, "/set start frfg",
"| File 'frfg' for '/set start' is not found."),
(a) -> assertCommand(a, "/set start -default",
""),
+ (a) -> assertCommand(a, "/set start",
+ "| /set start -default"),
(a) -> assertCommand(a, "/se sta -no",
""),
(a) -> assertCommand(a, "/set start",
- "| Specify either one option or a startup file name -- /set start")
+ "| /set start -none")
);
}
public void retainStartTest() {
test(
- (a) -> assertCommand(a, "/retain start -furball",
- "| Unknown option: -furball -- /retain start -furball"),
- (a) -> assertCommand(a, "/retain start -furball pyle",
- "| Unknown option: -furball -- /retain start -furball pyle"),
- (a) -> assertCommand(a, "/ret st pyle -furball",
- "| Unknown option: -furball -- /retain st pyle -furball"),
- (a) -> assertCommand(a, "/retain start -furball -mattress",
- "| Unknown option: -furball -mattress -- /retain start -furball -mattress"),
- (a) -> assertCommand(a, "/retain start foo -default",
- "| Specify either one option or a startup file name -- /retain start foo -default"),
- (a) -> assertCommand(a, "/retain start frfg",
- "| File 'frfg' for '/retain start' is not found."),
- (a) -> assertCommand(a, "/retain start -default",
+ (a) -> assertCommand(a, "/set start -retain -furball",
+ "| Unknown option: -furball -- /set start -retain -furball"),
+ (a) -> assertCommand(a, "/set start -retain -furball pyle",
+ "| Unknown option: -furball -- /set start -retain -furball pyle"),
+ (a) -> assertCommand(a, "/se st -re pyle -furball",
+ "| Unknown option: -furball -- /set st -re pyle -furball"),
+ (a) -> assertCommand(a, "/set start -retain -furball -mattress",
+ "| Unknown option: -furball -mattress -- /set start -retain -furball -mattress"),
+ (a) -> assertCommand(a, "/set start -retain foo -default",
+ "| Specify no more than one of -default, -none, or a startup file name -- /set start -retain foo -default"),
+ (a) -> assertCommand(a, "/set start -retain -default foo",
+ "| Specify no more than one of -default, -none, or a startup file name -- /set start -retain -default foo"),
+ (a) -> assertCommand(a, "/set start -retain frfg",
+ "| File 'frfg' for '/set start' is not found."),
+ (a) -> assertCommand(a, "/set start -retain -default",
""),
- (a) -> assertCommand(a, "/ret sta -no",
+ (a) -> assertCommand(a, "/set start",
+ "| /set start -retain -default"),
+ (a) -> assertCommand(a, "/set sta -no",
""),
- (a) -> assertCommand(a, "/retain start",
- "")
+ (a) -> assertCommand(a, "/set start",
+ "| /set start -retain -default\n" +
+ "| /set start -none"),
+ (a) -> assertCommand(a, "/se st -ret",
+ ""),
+ (a) -> assertCommand(a, "/se sta",
+ "| /set start -retain -none")
);
}
public void setModeTest() {
test(
- (a) -> assertCommandOutputStartsWith(a, "/set mode",
- "| Missing the feedback mode"),
+ (a) -> assertCommandOutputContains(a, "/set mode",
+ "| /set format verbose unresolved"),
(a) -> assertCommandOutputStartsWith(a, "/set mode *",
"| Expected a feedback mode name: *"),
(a) -> assertCommandOutputStartsWith(a, "/set mode -quiet",
@@ -229,11 +308,13 @@
"| Expected a feedback mode name: *"),
(a) -> assertCommandOutputStartsWith(a, "/set mode amode normal thing",
"| Unexpected arguments at end of command: thing"),
- (a) -> assertCommand(a, "/set mode mymode",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
+ "| To create a new mode either the -command or the -quiet option must be used"),
+ (a) -> assertCommand(a, "/set mode mymode -command",
"| Created new feedback mode: mymode"),
(a) -> assertCommand(a, "/set mode mymode -delete",
""),
- (a) -> assertCommand(a, "/set mode mymode normal",
+ (a) -> assertCommand(a, "/set mode mymode normal -command",
"| Created new feedback mode: mymode"),
(a) -> assertCommand(a, "/set mode -del mymode",
""),
@@ -245,18 +326,33 @@
"| Conflicting options"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode -d",
"| No feedback mode named: mymode"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode normal",
- "| Not valid with a predefined mode: normal"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode normal -c",
+ "| Mode to be created already exists: normal"),
(a) -> assertCommand(a, "/se mo -c mymode",
"| Created new feedback mode: mymode"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
+ "| /set mode mymode -command"),
(a) -> assertCommand(a, "/set feedback mymode",
"| Feedback mode: mymode"),
+ (a) -> assertCommand(a, "/se fe",
+ "| /set feedback mymode\n" +
+ "| \n" +
+ "| Available feedback modes:\n" +
+ "| concise\n" +
+ "| mymode\n" +
+ "| normal\n" +
+ "| silent\n" +
+ "| verbose"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
"| The current feedback mode 'mymode' cannot be deleted"),
(a) -> assertCommand(a, "/set feedback no",
"| Feedback mode: normal"),
(a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
""),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode",
+ "| To create a new mode either the -command or the -quiet option must be used -- \n" +
+ "| Does not match any current feedback mode: mymode -- /set mode mymode\n" +
+ "| Available feedback modes:"),
(a) -> assertCommandCheckOutput(a, "/set feedback",
(s) -> assertFalse(s.contains("mymode"), "Didn't delete: " + s))
);
@@ -272,8 +368,20 @@
""),
(a) -> assertCommand(a, "45",
"blurb"),
- (a) -> assertCommand(a, "/set mode mymode normal",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode normal",
+ "| To create a new mode either the -command or the -quiet option must be used"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -command normal",
+ "| Mode to be created already exists: mymode"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode mymode -delete",
+ "| The current feedback mode 'mymode' cannot be deleted, use '/set feedback' first"),
+ (a) -> assertCommand(a, "/set feedback normal",
+ "| Feedback mode: normal"),
+ (a) -> assertCommand(a, "/set mode mymode -delete",
+ ""),
+ (a) -> assertCommand(a, "/set mode mymode -command normal",
"| Created new feedback mode: mymode"),
+ (a) -> assertCommand(a, "/set feedback mymode",
+ "| Feedback mode: mymode"),
(a) -> assertCommandOutputContains(a, "45",
" ==> 45")
);
@@ -281,67 +389,89 @@
public void retainModeTest() {
test(
- (a) -> assertCommandOutputStartsWith(a, "/retain mode",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain",
"| Missing the feedback mode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode *",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain *",
"| Expected a feedback mode name: *"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode amode normal",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain amode normal",
"| Unexpected arguments at end of command: normal"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode mymode",
- "| Does not match any current feedback mode: mymode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode mymode -delete",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode",
"| No feedback mode named: mymode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode -d mymode",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain mymode -delete",
+ "| No feedback mode named: mymode"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain -d mymode",
"| No feedback mode named: mymode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode normal",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain normal",
"| Not valid with a predefined mode: normal"),
- (a) -> assertCommand(a, "/set mode mymode verbose",
+ (a) -> assertCommand(a, "/set mode mymode verbose -command",
"| Created new feedback mode: mymode"),
- (a) -> assertCommand(a, "/retain mode mymode",
+ (a) -> assertCommand(a, "/set mode -retain mymode",
""),
(a) -> assertCommand(a, "/set mode mymode -delete",
""),
- (a) -> assertCommand(a, "/retain mode mymode -delete",
+ (a) -> assertCommand(a, "/set mode -retain mymode -delete",
""),
- (a) -> assertCommand(a, "/set mode kmode normal",
+ (a) -> assertCommand(a, "/set mode kmode normal -command",
"| Created new feedback mode: kmode"),
- (a) -> assertCommand(a, "/retain mode kmode",
+ (a) -> assertCommand(a, "/set mode -retain kmode",
""),
(a) -> assertCommand(a, "/set mode kmode -delete",
""),
- (a) -> assertCommand(a, "/set mode tmode normal",
+ (a) -> assertCommand(a, "/set mode tmode normal -command",
"| Created new feedback mode: tmode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain feedback tmode",
- "| '/retain feedback <mode>' requires that <mode> is predefined or has been retained with '/retain mode'"),
+ (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain tmode",
+ "| '/set feedback -retain <mode>' requires that <mode> is predefined or has been retained with '/set mode -retain'"),
(a) -> assertCommand(a, "/set format tmode display 'YES'",
""),
(a) -> assertCommand(a, "/set feedback tmode",
"| Feedback mode: tmode"),
(a) -> assertCommand(a, "45",
"YES"),
- (a) -> assertCommand(a, "/retain mode tmode",
+ (a) -> assertCommand(a, "/set mode -retain tmode",
""),
- (a) -> assertCommand(a, "/retain feedback tmode",
+ (a) -> assertCommand(a, "/set feedback -retain tmode",
"| Feedback mode: tmode"),
(a) -> assertCommand(a, "/set format tmode display 'blurb'",
""),
+ (a) -> assertCommand(a, "/set format tmode display",
+ "| /set format tmode display \"blurb\""),
+ (a) -> assertCommandOutputContains(a, "/set mode tmode",
+ "| /set format tmode display \"YES\""),
(a) -> assertCommand(a, "45",
"blurb")
);
test(
+ (a) -> assertCommand(a, "/set format tmode display",
+ "| /set format tmode display \"YES\""),
+ (a) -> assertCommandOutputContains(a, "/set mode tmode",
+ "| /set format tmode display \"YES\""),
(a) -> assertCommand(a, "45",
"YES"),
(a) -> assertCommand(a, "/set feedback kmode",
"| Feedback mode: kmode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete",
+ (a) -> assertCommand(a, "/set feedback",
+ "| /set feedback -retain tmode\n" +
+ "| /set feedback kmode\n" +
+ "| \n" +
+ "| Retained feedback modes:\n" +
+ "| kmode\n" +
+ "| tmode\n" +
+ "| Available feedback modes:\n" +
+ "| concise\n" +
+ "| kmode\n" +
+ "| normal\n" +
+ "| silent\n" +
+ "| tmode\n" +
+ "| verbose"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete",
"| The current feedback mode 'kmode' cannot be deleted"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode tmode -delete",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain tmode -delete",
"| The retained feedback mode 'tmode' cannot be deleted"),
- (a) -> assertCommand(a, "/retain feedback normal",
+ (a) -> assertCommand(a, "/set feedback -retain normal",
"| Feedback mode: normal"),
- (a) -> assertCommand(a, "/retain mode tmode -delete",
+ (a) -> assertCommand(a, "/set mode -retain tmode -delete",
""),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode kmode -delete",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain kmode -delete",
"")
);
test(
--- a/langtools/test/jdk/jshell/ToolFormatTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/ToolFormatTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261
+ * @bug 8148316 8148317 8151755 8152246 8153551 8154812 8157261 8163840
* @summary Tests for output customization
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -33,10 +33,17 @@
* @build KullaTesting TestingInputStream toolbox.ToolBox Compiler
* @run testng ToolFormatTest
*/
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
@Test
public class ToolFormatTest extends ReplToolTesting {
@@ -81,6 +88,58 @@
}
}
+ public void testSetFormatOverride() {
+ test(
+ (a) -> assertCommand(a, "/set mode tm -c", "| Created new feedback mode: tm"),
+ (a) -> assertCommand(a, "/se fo tm x \"aaa\"", ""),
+ (a) -> assertCommand(a, "/se fo tm x \"bbb\" class,method-added", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"bbb\" class,method-added"),
+ (a) -> assertCommand(a, "/se fo tm x \"ccc\" class,method-added,modified", ""),
+ (a) -> assertCommand(a, "/se fo tm x \"ddd\" class,method-added", ""),
+ (a) -> assertCommand(a, "/se fo tm x \"eee\" method-added", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"ccc\" class,method-added,modified\n" +
+ "| /set format tm x \"ddd\" class,method-added\n" +
+ "| /set format tm x \"eee\" method-added"),
+ (a) -> assertCommand(a, "/se fo tm x \"EEE\" method-added,replaced", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"ccc\" class,method-added,modified\n" +
+ "| /set format tm x \"ddd\" class,method-added\n" +
+ "| /set format tm x \"EEE\" method-added,replaced"),
+ (a) -> assertCommand(a, "/se fo tm x \"fff\" method-added,replaced-ok", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"ccc\" class,method-added,modified\n" +
+ "| /set format tm x \"ddd\" class,method-added\n" +
+ "| /set format tm x \"EEE\" method-added,replaced\n" +
+ "| /set format tm x \"fff\" method-added,replaced-ok"),
+ (a) -> assertCommand(a, "/se fo tm x \"ggg\" method-ok", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"ccc\" class,method-added,modified\n" +
+ "| /set format tm x \"ddd\" class,method-added\n" +
+ "| /set format tm x \"EEE\" method-added,replaced\n" +
+ "| /set format tm x \"ggg\" method-ok"),
+ (a) -> assertCommand(a, "/se fo tm x \"hhh\" method", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"ccc\" class,method-added,modified\n" +
+ "| /set format tm x \"ddd\" class,method-added\n" +
+ "| /set format tm x \"hhh\" method"),
+ (a) -> assertCommand(a, "/se fo tm x \"iii\" method,class", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"aaa\" \n" +
+ "| /set format tm x \"iii\" class,method"),
+ (a) -> assertCommand(a, "/se fo tm x \"jjj\"", ""),
+ (a) -> assertCommand(a, "/se fo tm x",
+ "| /set format tm x \"jjj\"")
+ );
+ }
+
public void testSetFormatSelector() {
List<ReplTest> tests = new ArrayList<>();
tests.add((a) -> assertCommandOutputStartsWith(a, "/set mode ate -quiet",
@@ -167,8 +226,14 @@
(a) -> assertCommandOutputStartsWith(a, "/set feedback test", ""),
(a) -> assertCommand(a, "/set format test display '{type}:{value}' primary", ""),
(a) -> assertCommand(a, "/set truncation test 20", ""),
+ (a) -> assertCommand(a, "/set truncation test", "| /set truncation test 20"),
+ (a) -> assertCommandOutputContains(a, "/set truncation", "/set truncation test 20"),
(a) -> assertCommand(a, "/set trunc test 10 varvalue", ""),
(a) -> assertCommand(a, "/set trunc test 3 assignment", ""),
+ (a) -> assertCommandOutputContains(a, "/set truncation",
+ "/set truncation test 10 varvalue"),
+ (a) -> assertCommandOutputContains(a, "/set truncation test",
+ "/set truncation test 10 varvalue"),
(a) -> assertCommand(a, "String r = s", "String:\"ABACABADABACABA ..."),
(a) -> assertCommand(a, "r", "String:\"ABACA ..."),
(a) -> assertCommand(a, "r=s", "String:\"AB")
@@ -201,6 +266,45 @@
);
}
+ public void testPrompt() {
+ test(
+ (a) -> assertCommand(a, "/set mode tp -quiet", "| Created new feedback mode: tp"),
+ (a) -> assertCommand(a, "/set prompt tp 'aaa' 'bbb'", ""),
+ (a) -> assertCommand(a, "/set prompt tp",
+ "| /set prompt tp \"aaa\" \"bbb\""),
+ (a) -> assertCommandOutputContains(a, "/set prompt",
+ "| /set prompt tp \"aaa\" \"bbb\""),
+ (a) -> assertCommand(a, "/set mode -retain tp", ""),
+ (a) -> assertCommand(a, "/set prompt tp 'ccc' 'ddd'", ""),
+ (a) -> assertCommand(a, "/set prompt tp",
+ "| /set prompt tp \"ccc\" \"ddd\""),
+ (a) -> assertCommandCheckOutput(a, "/set mode tp",
+ (s) -> {
+ try {
+ BufferedReader rdr = new BufferedReader(new StringReader(s));
+ assertEquals(rdr.readLine(), "| /set mode tp -quiet",
+ "| /set mode tp -quiet");
+ assertEquals(rdr.readLine(), "| /set prompt tp \"aaa\" \"bbb\"",
+ "| /set prompt tp \"aaa\" \"bbb\"");
+ String l = rdr.readLine();
+ while (l.startsWith("| /set format tp ")) {
+ l = rdr.readLine();
+ }
+ assertEquals(l, "| /set mode -retain tp",
+ "| /set mode -retain tp");
+ assertEquals(rdr.readLine(), "| ",
+ "| ");
+ assertEquals(rdr.readLine(), "| /set mode tp -quiet",
+ "| /set mode tp -quiet");
+ assertEquals(rdr.readLine(), "| /set prompt tp \"ccc\" \"ddd\"",
+ "| /set prompt tp \"ccc\" \"ddd\"");
+ } catch (IOException ex) {
+ fail("threw " + ex);
+ }
+ })
+ );
+ }
+
public void testShowFeedbackModes() {
test(
(a) -> assertCommandOutputContains(a, "/set feedback", "normal")
@@ -216,7 +320,8 @@
(a) -> assertCommand(a, "/se fee nmq2", ""),
(a) -> assertCommand(a, "/set mode nmc -command normal", ""),
(a) -> assertCommandOutputStartsWith(a, "/set feedback nmc", "| Feedback mode: nmc"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode nm", "| Created new feedback mode: nm"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode nm -command",
+ "| Created new feedback mode: nm"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback nm", "| Feedback mode: nm"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback normal", "| Feedback mode: normal")
);
@@ -231,37 +336,35 @@
test(
(a) -> assertCommandOutputStartsWith(a, "/set mode tee -command foo",
"| Does not match any current feedback mode: foo"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode tee flurb",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode tee -quiet flurb",
"| Does not match any current feedback mode: flurb"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode tee",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -command tee",
"| Created new feedback mode: tee"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode verbose",
- "| Not valid with a predefined mode: verbose"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode verbose -command",
+ "| Mode to be created already exists: verbose"),
(a) -> assertCommandOutputStartsWith(a, "/set mode te -command normal",
"| Created new feedback mode: te"),
(a) -> assertCommand(a, "/set format te errorpre 'ERROR: '", ""),
(a) -> assertCommandOutputStartsWith(a, "/set feedback te",
""),
- (a) -> assertCommandOutputStartsWith(a, "/set ",
- "ERROR: The '/set' command requires a sub-command"),
(a) -> assertCommandOutputStartsWith(a, "/set xyz",
"ERROR: Invalid '/set' argument: xyz"),
(a) -> assertCommandOutputStartsWith(a, "/set f",
"ERROR: Ambiguous sub-command argument to '/set': f"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback",
- "ERROR: Missing the feedback mode"),
+ "| /set feedback te"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback xyz",
"ERROR: Does not match any current feedback mode"),
- (a) -> assertCommandOutputStartsWith(a, "/set format",
- "ERROR: Missing the feedback mode"),
+ (a) -> assertCommandOutputStartsWith(a, "/set feed",
+ "| /set feedback te"),
(a) -> assertCommandOutputStartsWith(a, "/set format xyz",
"ERROR: Does not match any current feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set format t",
"ERROR: Matches more then one current feedback mode: t"),
- (a) -> assertCommandOutputStartsWith(a, "/set format te",
- "ERROR: Missing the field name"),
+ (a) -> assertCommandOutputStartsWith(a, "/set format qqq",
+ "ERROR: Does not match any current feedback mode: qqq"),
(a) -> assertCommandOutputStartsWith(a, "/set format te fld",
- "ERROR: Expected format missing"),
+ "ERROR: Expected a field name:"),
(a) -> assertCommandOutputStartsWith(a, "/set format te fld aaa",
"ERROR: Format 'aaa' must be quoted"),
(a) -> assertCommandOutputStartsWith(a, "/set format te fld 'aaa' frog",
@@ -274,30 +377,28 @@
"ERROR: Different selector kinds in same sections of"),
(a) -> assertCommandOutputStartsWith(a, "/set trunc te 20x",
"ERROR: Truncation length must be an integer: 20x"),
- (a) -> assertCommandOutputStartsWith(a, "/set trunc te",
- "ERROR: Expected truncation length"),
+ (a) -> assertCommandOutputStartsWith(a, "/set trunc qaz",
+ "ERROR: Does not match any current feedback mode: qaz -- /set trunc qaz"),
(a) -> assertCommandOutputStartsWith(a, "/set truncation te 111 import,added",
"ERROR: Different selector kinds in same sections of"),
- (a) -> assertCommandOutputStartsWith(a, "/set mode",
+ (a) -> assertCommandOutputContains(a, "/set mode",
+ "| /set truncation verbose"),
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -command",
"ERROR: Missing the feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set mode x -quiet y",
"ERROR: Does not match any current feedback mode"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt",
- "ERROR: Missing the feedback mode"),
+ "| /set prompt"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te",
- "ERROR: Expected format missing"),
+ "| /set prompt te "),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa xyz",
"ERROR: Format 'aaa' must be quoted"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa' xyz",
"ERROR: Format 'xyz' must be quoted"),
- (a) -> assertCommandOutputStartsWith(a, "/set prompt",
- "ERROR: Missing the feedback mode"),
- (a) -> assertCommandOutputStartsWith(a, "/set prompt te",
- "ERROR: Expected format missing"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te aaa",
"ERROR: Format 'aaa' must be quoted"),
(a) -> assertCommandOutputStartsWith(a, "/set prompt te 'aaa'",
- "ERROR: Expected format missing"),
+ "ERROR: Continuation prompt required"),
(a) -> assertCommandOutputStartsWith(a, "/set feedback normal",
"| Feedback mode: normal")
);
--- a/langtools/test/jdk/jshell/ToolLocaleMessageTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/ToolLocaleMessageTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -106,10 +106,11 @@
(a) -> assertCommandOK(a, "/set feedback test", "test"),
(a) -> assertCommandFail(a, "/list zebra"),
- (a) -> assertCommandFail(a, "/set editor", "/set editor"),
+ (a) -> assertCommandFail(a, "/set editor -rot", "/set editor -rot"),
(a) -> assertCommandFail(a, "/set snowball", "/set", "snowball"),
- (a) -> assertCommandFail(a, "/set", "/set", "/help"),
- (a) -> assertCommandFail(a, "/set f", "feedback"),
+ (a) -> assertCommandOK(a, "/set", "| /set feedback test", "verbose"),
+ (a) -> assertCommandFail(a, "/set f", "/set"),
+ (a) -> assertCommandOK(a, "/set fe", "| /set feedback test"),
(a) -> assertCommandFail(a, "/classpath", "/classpath"),
(a) -> assertCommandFail(a, "/help rabbits", "rabbits"),
(a) -> assertCommandFail(a, "/drop"),
@@ -164,27 +165,20 @@
(a) -> assertCommandOK(a, "/set format te errorpre 'ERROR: '"),
(a) -> assertCommandOK(a, "/set feedback te"),
- (a) -> assertCommandFail(a, "/set "),
(a) -> assertCommandFail(a, "/set xyz", "xyz"),
(a) -> assertCommandFail(a, "/set f", "/set", "f"),
- (a) -> assertCommandFail(a, "/set feedback"),
(a) -> assertCommandFail(a, "/set feedback xyz"),
- (a) -> assertCommandFail(a, "/set format"),
(a) -> assertCommandFail(a, "/set format xyz"),
(a) -> assertCommandFail(a, "/set format t"),
- (a) -> assertCommandFail(a, "/set format te"),
(a) -> assertCommandFail(a, "/set format te fld"),
(a) -> assertCommandFail(a, "/set format te fld aaa", "aaa"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' frog"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' import-frog"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' import-import"),
(a) -> assertCommandFail(a, "/set format te fld 'aaa' import,added"),
- (a) -> assertCommandFail(a, "/set mode"),
(a) -> assertCommandFail(a, "/set mode x xyz"),
(a) -> assertCommandFail(a, "/set mode x -quiet y"),
(a) -> assertCommandFail(a, "/set mode tee -command foo", "foo"),
- (a) -> assertCommandFail(a, "/set prompt"),
- (a) -> assertCommandFail(a, "/set prompt te"),
(a) -> assertCommandFail(a, "/set prompt te aaa xyz", "aaa"),
(a) -> assertCommandFail(a, "/set prompt te 'aaa' xyz", "xyz"),
(a) -> assertCommandFail(a, "/set prompt te aaa"),
--- a/langtools/test/jdk/jshell/ToolRetainTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/ToolRetainTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8157200
+ * @bug 8157200 8163840
* @summary Tests of what information is retained across jshell tool runs
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build ToolRetainTest ReplToolTesting
@@ -41,10 +41,12 @@
(a) -> assertCommand(a, "/set feedback trm", ""),
(a) -> assertCommand(a, "/set format trm display '{name}:{value}'", ""),
(a) -> assertCommand(a, "int x = 45", "x:45"),
- (a) -> assertCommand(a, "/retain mode trm", ""),
+ (a) -> assertCommand(a, "/set mode -retain trm", ""),
(a) -> assertCommand(a, "/exit", "")
);
test(
+ (a) -> assertCommandOutputContains(a, "/set mode trm",
+ "/set format trm display \"{name}:{value}\""),
(a) -> assertCommand(a, "/set feedback trm", ""),
(a) -> assertCommand(a, "int x = 45", "x:45")
);
@@ -53,21 +55,25 @@
public void testRetain2Mode() {
test(
(a) -> assertCommand(a, "/set mode trm1 -quiet", "| Created new feedback mode: trm1"),
- (a) -> assertCommand(a, "/retain mode trm1", ""),
- (a) -> assertCommand(a, "/retain feedback trm1", ""),
+ (a) -> assertCommand(a, "/set mode -retain trm1", ""),
+ (a) -> assertCommand(a, "/set feedback -retain trm1", ""),
(a) -> assertCommand(a, "/set format trm1 display '{name}:{value}'", ""),
(a) -> assertCommand(a, "int x = 66", "x:66"),
- (a) -> assertCommand(a, "/retain mode trm1", ""),
+ (a) -> assertCommand(a, "/set mode -retain trm1", ""),
(a) -> assertCommand(a, "/exit", "")
);
test(
(a) -> assertCommand(a, "/set mode trm2 -quiet", ""),
(a) -> assertCommand(a, "/set format trm2 display '{name}={value}'", ""),
(a) -> assertCommand(a, "int x = 45", "x:45"),
- (a) -> assertCommand(a, "/retain mode trm2", ""),
+ (a) -> assertCommand(a, "/set mode -retain trm2", ""),
(a) -> assertCommand(a, "/exit", "")
);
test(
+ (a) -> assertCommandOutputContains(a, "/set mode trm1",
+ "/set format trm1 display \"{name}:{value}\""),
+ (a) -> assertCommand(a, "/set format trm2 display",
+ "| /set format trm2 display \"{name}={value}\""),
(a) -> assertCommand(a, "int x = 99", "x:99"),
(a) -> assertCommand(a, "/set feedback trm2", ""),
(a) -> assertCommand(a, "int z = 77", "z=77")
@@ -76,31 +82,48 @@
public void testRetainFeedback() {
test(
- (a) -> assertCommand(a, "/retain feedback verbose", "| Feedback mode: verbose"),
+ (a) -> assertCommand(a, "/set feedback -retain verbose", "| Feedback mode: verbose"),
(a) -> assertCommand(a, "/exit", "")
);
test(
+ (a) -> assertCommandOutputStartsWith(a, "/set feedback",
+ "| /set feedback -retain verbose\n" +
+ "| \n" +
+ "| "),
(a) -> assertCommandOutputContains(a, "int h =8", "| created variable h : int")
);
}
public void testRetainFeedbackBlank() {
+ String feedbackOut =
+ "| /set feedback -retain verbose\n" +
+ "| \n" +
+ "| Available feedback modes:\n" +
+ "| concise\n" +
+ "| normal\n" +
+ "| silent\n" +
+ "| verbose";
test(
(a) -> assertCommand(a, "/set feedback verbose", "| Feedback mode: verbose"),
- (a) -> assertCommand(a, "/retain feedback", ""),
+ (a) -> assertCommand(a, "/set feedback -retain", ""),
+ (a) -> assertCommand(a, "/set feedback", feedbackOut),
(a) -> assertCommand(a, "/exit", "")
);
test(
+ (a) -> assertCommand(a, "/set feedback", feedbackOut),
(a) -> assertCommandOutputContains(a, "int qw = 5", "| created variable qw : int")
);
}
public void testRetainEditor() {
test(
- (a) -> assertCommand(a, "/retain editor nonexistent", "| Editor set to: nonexistent"),
+ (a) -> assertCommand(a, "/set editor -retain nonexistent",
+ "| Editor set to: nonexistent\n" +
+ "| Editor setting retained: nonexistent"),
(a) -> assertCommand(a, "/exit", "")
);
test(
+ (a) -> assertCommand(a, "/set editor", "| /set editor -retain nonexistent"),
(a) -> assertCommandOutputContains(a, "int h =8", ""),
(a) -> assertCommandOutputContains(a, "/edit h", "Edit Error:")
);
@@ -109,7 +132,7 @@
public void testRetainEditorBlank() {
test(
(a) -> assertCommand(a, "/set editor nonexistent", "| Editor set to: nonexistent"),
- (a) -> assertCommand(a, "/retain editor", ""),
+ (a) -> assertCommand(a, "/set editor -retain", "| Editor setting retained: nonexistent"),
(a) -> assertCommand(a, "/exit", "")
);
test(
@@ -120,22 +143,25 @@
public void testRetainModeNeg() {
test(
- (a) -> assertCommandOutputStartsWith(a, "/retain mode verbose",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain verbose",
"| Not valid with a predefined mode"),
- (a) -> assertCommandOutputStartsWith(a, "/retain mode ????",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode -retain ????",
"| Expected a feedback mode name: ????")
);
}
public void testRetainFeedbackNeg() {
test(
- (a) -> assertCommandOutputStartsWith(a, "/retain feedback babble1",
+ (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain babble1",
"| Does not match any current feedback mode"),
- (a) -> assertCommand(a, "/set mode trfn",
+ (a) -> assertCommandOutputStartsWith(a, "/set mode trfn",
+ "| To create a new mode either the -command or the -quiet option must be used -- \n" +
+ "| Does not match any current feedback mode: trfn -- /set mode trfn"),
+ (a) -> assertCommand(a, "/set mode trfn -command",
"| Created new feedback mode: trfn"),
- (a) -> assertCommandOutputContains(a, "/retain feedback trfn",
+ (a) -> assertCommandOutputContains(a, "/set feedback -retain trfn",
"is predefined or has been retained"),
- (a) -> assertCommandOutputStartsWith(a, "/retain feedback !!!!",
+ (a) -> assertCommandOutputStartsWith(a, "/set feedback -retain !!!!",
"| Expected a feedback mode name: !!!!")
);
}
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -193,8 +193,8 @@
"| '/save' requires a filename argument."),
(a) -> assertCommand(a, "/open",
"| '/open' requires a filename argument."),
- (a) -> assertCommand(a, "/set start",
- "| Specify either one option or a startup file name -- /set start")
+ (a) -> assertCommandOutputStartsWith(a, "/drop",
+ "| In the /drop argument, please specify an import, variable, method, or class to drop.")
);
}
--- a/langtools/test/jdk/jshell/UserInputTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/jdk/jshell/UserInputTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -23,12 +23,15 @@
/*
* @test
- * @bug 8131023
+ * @bug 8131023 8167461
* @summary Verify that the user's code can read System.in
* @build KullaTesting TestingInputStream
* @run testng UserInputTest
*/
+import java.io.IOException;
+import java.io.InputStream;
+
import org.testng.annotations.Test;
@Test
@@ -37,8 +40,61 @@
public void testReadInput() {
setInput("AB\n");
assertEval("System.in.read()", "65");
- setInput("BC\n");
- assertEval("System.in.read()", "66");
+ setInput("CD\n");
+ assertEval("System.in.read()", "67");
+ }
+
+ public void testScanner() {
+ assertEval("import java.util.Scanner;");
+ assertEval("Scanner s = new Scanner(System.in);");
+ setInput("12\n");
+ assertEval("s.nextInt();", "12");
}
+ public void testClose() {
+ setInput(new InputStream() {
+ private final byte[] data = new byte[] {0, 1, 2};
+ private int cursor;
+ @Override public int read() throws IOException {
+ if (cursor < data.length) {
+ return data[cursor++];
+ } else {
+ return -1;
+ }
+ }
+ });
+ assertEval("int read;", "0");
+ assertEval("System.in.read();", "0");
+ assertEval("System.in.read();", "1");
+ assertEval("System.in.read();", "2");
+ assertEval("System.in.read();", "-1");
+ assertEval("System.in.read();", "-1");
+ assertEval("System.in.read();", "-1");
+ }
+
+ public void testException() {
+ setInput(new InputStream() {
+ private final int[] data = new int[] {0, 1, -2, 2};
+ private int cursor;
+ @Override public int read() throws IOException {
+ if (cursor < data.length) {
+ int d = data[cursor++];
+ if (d == (-2)) {
+ throw new IOException("Crashed");
+ }
+ return d;
+ } else {
+ return -1;
+ }
+ }
+ });
+ assertEval("int read;", "0");
+ assertEval("System.in.read();", "0");
+ assertEval("System.in.read();", "1");
+ assertEval("java.io.IOException e;");
+ assertEval("try { System.in.read(); } catch (java.io.IOException exc) { e = exc; }");
+ assertEval("e", "java.io.IOException: Crashed");
+ assertEval("System.in.read();", "2");
+ assertEval("System.in.read();", "-1");
+ }
}
--- a/langtools/test/tools/javac/Paths/MineField.sh Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/javac/Paths/MineField.sh Thu Oct 27 08:52:00 2016 -0700
@@ -109,9 +109,15 @@
echo 'public class Main {public static void main(String[] a) {Lib.f();}}' > Main.java
# Create a jar file that is good enough to put on the javac boot class path (i.e. contains java.lang.**)
-Sys "$jimage" extract --dir modules ${TESTJAVA}/lib/modules
-Sys "$jar" cf java-lang.jar -C modules/java.base java/lang
-Sys rm -rf modules
+if [ -r ${TESTJAVA}/lib/modules ]; then
+ Sys "$jimage" extract --dir modules ${TESTJAVA}/lib/modules
+ Sys "$jar" cf java-lang.jar -C modules/java.base java/lang
+ Sys rm -rf modules
+elif [ -d ${TESTJAVA}/modules ]; then
+ Sys "$jar" cf java-lang.jar -C ${TESTJAVA}/modules/java.base java/lang
+else
+ echo 'cannot create java-lang.jar' ; exit 1
+fi
#----------------------------------------------------------------
# Verify that javac class search order is the same as java's
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableElementTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,241 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8029102
+ * @summary Enhance compiler warnings for Lambda
+ * Checks that the warning for accessing non public members of a class is
+ * fired correctly.
+ * @compile/fail/ref=WarnSerializableElementTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToMembers WarnSerializableElementTest.java
+ */
+
+import java.io.Serializable;
+
+public class WarnSerializableElementTest {
+
+ void warnLambda() throws Exception {
+ SAM t3 = (SAM & Serializable)WarnSerializableElementTest::packageClassMethod;
+ SAM t4 = (SAM & Serializable)WarnSerializableElementTest::protectedClassMethod;
+ SAM t5 = (SAM & Serializable)WarnSerializableElementTest::privateClassMethod;
+
+ WarnSerializableElementTest test = new WarnSerializableElementTest();
+ SAM t6 = (SAM & Serializable)test::packageInstanceMethod;
+ SAM t7 = (SAM & Serializable)test::protectedInstanceMethod;
+ SAM t8 = (SAM & Serializable)test::privateInstanceMethod;
+
+ SAM t9 = (SAM & Serializable) c -> {
+
+ WarnSerializableElementTest.staticPackageField = "";
+ WarnSerializableElementTest.staticProtectedField = "";
+ WarnSerializableElementTest.staticPrivateField = "";
+
+ packageField = "";
+ protectedField = "";
+ privateField = "";
+
+ WarnSerializableElementTest.packageClassMethod(null);
+ WarnSerializableElementTest.protectedClassMethod(null);
+ WarnSerializableElementTest.privateClassMethod(null);
+
+ packageInstanceMethod(null);
+ protectedInstanceMethod(null);
+ privateInstanceMethod(null);
+
+ PrivateClass.effectivelyNonPublicStaticField = "";
+ PrivateClass.effectivelyNonPublicClassMethod();
+
+ PrivateClass p = new PrivateClass();
+ p.effectivelyNonPublicInstanceField = "";
+ p.effectivelyNonPublicInstanceMethod();
+
+ return null;
+ };
+ }
+
+ private void warnAnoInnerClass() throws Exception {
+ new SerializableDesc() {
+ public void m(Object param) throws Exception {
+ WarnSerializableElementTest.staticPackageField = "";
+ WarnSerializableElementTest.staticProtectedField = "";
+ WarnSerializableElementTest.staticPrivateField = "";
+
+ packageField = "";
+ protectedField = "";
+ privateField = "";
+
+ WarnSerializableElementTest.packageClassMethod(null);
+ WarnSerializableElementTest.protectedClassMethod(null);
+ WarnSerializableElementTest.privateClassMethod(null);
+
+ packageInstanceMethod(null);
+ protectedInstanceMethod(null);
+ privateInstanceMethod(null);
+
+ PrivateClass.effectivelyNonPublicStaticField = "";
+ PrivateClass.effectivelyNonPublicClassMethod();
+
+ PrivateClass p = new PrivateClass();
+ p.effectivelyNonPublicInstanceField = "";
+ p.effectivelyNonPublicInstanceMethod();
+ }
+ };
+ }
+
+ void dontWarnLambda() throws Exception {
+ SAM t1 = (SAM & Serializable)WarnSerializableElementTest::publicClassMethod;
+
+ WarnSerializableElementTest test = new WarnSerializableElementTest();
+ SAM t2 = (SAM & Serializable)test::publicInstanceMethod;
+
+ int[] buffer = {0};
+
+ SAM t3 = (SAM & Serializable) param -> {
+ Object localVar;
+ localVar = null;
+ param = null;
+
+ WarnSerializableElementTest.staticPublicField = "";
+ publicField = "";
+ WarnSerializableElementTest.publicClassMethod(null);
+ publicInstanceMethod(null);
+
+ PublicClass.effectivelyPublicStaticField = "";
+ PublicClass.effectivelyPublicClassMethod();
+
+ PublicClass p = new PublicClass();
+ p.effectivelyPublicInstanceField = "";
+ p.effectivelyPublicInstanceMethod();
+
+ int l = buffer.length;
+
+ return null;
+ };
+ }
+
+ private void dontWarnAnoInnerClass() throws Exception {
+ final int[] buffer = {0};
+ new SerializableDesc() {
+ public void m(Object param) throws Exception {
+ Object localVar;
+ localVar = null;
+ param = null;
+
+ WarnSerializableElementTest.staticPublicField = "";
+ publicField = "";
+ WarnSerializableElementTest.publicClassMethod(null);
+ publicInstanceMethod(null);
+
+ PublicClass.effectivelyPublicStaticField = "";
+ PublicClass.effectivelyPublicClassMethod();
+
+ PublicClass p = new PublicClass();
+ p.effectivelyPublicInstanceField = "";
+ p.effectivelyPublicInstanceMethod();
+
+ int l = buffer.length;
+ }
+ };
+ }
+
+ enum WarnEnum {
+ A {
+ public void m() throws Exception {
+ WarnSerializableElementTest.staticPackageField = "";
+ WarnSerializableElementTest.staticProtectedField = "";
+ WarnSerializableElementTest.staticPrivateField = "";
+
+ WarnSerializableElementTest test =
+ new WarnSerializableElementTest();
+
+ test.packageField = "";
+ test.protectedField = "";
+ test.privateField = "";
+
+ WarnSerializableElementTest.packageClassMethod(null);
+ WarnSerializableElementTest.protectedClassMethod(null);
+ WarnSerializableElementTest.privateClassMethod(null);
+
+ test.packageInstanceMethod(null);
+ test.protectedInstanceMethod(null);
+ test.privateInstanceMethod(null);
+
+ PrivateClass.effectivelyNonPublicStaticField = "";
+ PrivateClass.effectivelyNonPublicClassMethod();
+
+ PrivateClass p = new PrivateClass();
+ p.effectivelyNonPublicInstanceField = "";
+ p.effectivelyNonPublicInstanceMethod();
+ }
+ };
+
+ public void m() throws Exception {}
+ }
+
+ static String staticPackageField;
+ static private String staticPrivateField;
+ static protected String staticProtectedField;
+ static public String staticPublicField;
+
+ String packageField;
+ private String privateField;
+ protected String protectedField;
+ public String publicField;
+
+ static Object packageClassMethod(String s) {
+ return null;
+ }
+
+ static private Object privateClassMethod(String s) {
+ return null;
+ }
+
+ static protected Object protectedClassMethod(String s) {
+ return null;
+ }
+
+ static public Object publicClassMethod(String s) {
+ return null;
+ }
+
+ Object packageInstanceMethod(String s) {
+ return null;
+ }
+
+ protected Object protectedInstanceMethod(String s) {
+ return null;
+ }
+
+ private Object privateInstanceMethod(String s) {
+ return null;
+ }
+
+ public Object publicInstanceMethod(String s) {
+ return null;
+ }
+
+ interface SAM {
+ Object apply(String s) throws Exception;
+ }
+
+ interface SAM2 {
+ Object apply(String arg1, String arg2);
+ }
+
+ class SerializableDesc implements Serializable {
+ public void m(Object param) throws Exception {}
+ }
+
+ static private class PrivateClass {
+ static public String effectivelyNonPublicStaticField;
+ public String effectivelyNonPublicInstanceField;
+
+ static public void effectivelyNonPublicClassMethod() {}
+ public void effectivelyNonPublicInstanceMethod() {}
+ }
+
+ static public class PublicClass {
+ static public String effectivelyPublicStaticField;
+ public String effectivelyPublicInstanceField;
+
+ static public void effectivelyPublicClassMethod() {}
+ public void effectivelyPublicInstanceMethod() {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableElementTest.out Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,35 @@
+WarnSerializableElementTest.java:56:44: compiler.warn.access.to.member.from.serializable.element: staticPackageField
+WarnSerializableElementTest.java:57:44: compiler.warn.access.to.member.from.serializable.element: staticProtectedField
+WarnSerializableElementTest.java:58:44: compiler.warn.access.to.member.from.serializable.element: staticPrivateField
+WarnSerializableElementTest.java:60:17: compiler.warn.access.to.member.from.serializable.element: packageField
+WarnSerializableElementTest.java:61:17: compiler.warn.access.to.member.from.serializable.element: protectedField
+WarnSerializableElementTest.java:62:17: compiler.warn.access.to.member.from.serializable.element: privateField
+WarnSerializableElementTest.java:64:44: compiler.warn.access.to.member.from.serializable.element: packageClassMethod(java.lang.String)
+WarnSerializableElementTest.java:65:44: compiler.warn.access.to.member.from.serializable.element: protectedClassMethod(java.lang.String)
+WarnSerializableElementTest.java:66:44: compiler.warn.access.to.member.from.serializable.element: privateClassMethod(java.lang.String)
+WarnSerializableElementTest.java:68:17: compiler.warn.access.to.member.from.serializable.element: packageInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:69:17: compiler.warn.access.to.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:70:17: compiler.warn.access.to.member.from.serializable.element: privateInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:72:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicStaticField
+WarnSerializableElementTest.java:73:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicClassMethod()
+WarnSerializableElementTest.java:76:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceField
+WarnSerializableElementTest.java:77:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
+WarnSerializableElementTest.java:141:44: compiler.warn.access.to.member.from.serializable.element: staticPackageField
+WarnSerializableElementTest.java:142:44: compiler.warn.access.to.member.from.serializable.element: staticProtectedField
+WarnSerializableElementTest.java:143:44: compiler.warn.access.to.member.from.serializable.element: staticPrivateField
+WarnSerializableElementTest.java:148:21: compiler.warn.access.to.member.from.serializable.element: packageField
+WarnSerializableElementTest.java:149:21: compiler.warn.access.to.member.from.serializable.element: protectedField
+WarnSerializableElementTest.java:150:21: compiler.warn.access.to.member.from.serializable.element: privateField
+WarnSerializableElementTest.java:152:44: compiler.warn.access.to.member.from.serializable.element: packageClassMethod(java.lang.String)
+WarnSerializableElementTest.java:153:44: compiler.warn.access.to.member.from.serializable.element: protectedClassMethod(java.lang.String)
+WarnSerializableElementTest.java:154:44: compiler.warn.access.to.member.from.serializable.element: privateClassMethod(java.lang.String)
+WarnSerializableElementTest.java:156:21: compiler.warn.access.to.member.from.serializable.element: packageInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:157:21: compiler.warn.access.to.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:158:21: compiler.warn.access.to.member.from.serializable.element: privateInstanceMethod(java.lang.String)
+WarnSerializableElementTest.java:160:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicStaticField
+WarnSerializableElementTest.java:161:29: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicClassMethod()
+WarnSerializableElementTest.java:164:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceField
+WarnSerializableElementTest.java:165:18: compiler.warn.access.to.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
+- compiler.err.warnings.and.werror
+1 error
+32 warnings
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.java Wed Oct 19 08:05:48 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @bug 8029102
- * @summary Enhance compiler warnings for Lambda
- * Checks that the warning for accessing non public members of a class is
- * fired correctly.
- * @compile/fail/ref=WarnSerializableLambdaTest.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTest.java
- */
-
-import java.io.Serializable;
-
-public class WarnSerializableLambdaTest {
-
- void warnLambda() throws Exception {
- SAM t3 = (SAM & Serializable)WarnSerializableLambdaTest::packageClassMethod;
- SAM t4 = (SAM & Serializable)WarnSerializableLambdaTest::protectedClassMethod;
- SAM t5 = (SAM & Serializable)WarnSerializableLambdaTest::privateClassMethod;
-
- WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
- SAM t6 = (SAM & Serializable)test::packageInstanceMethod;
- SAM t7 = (SAM & Serializable)test::protectedInstanceMethod;
- SAM t8 = (SAM & Serializable)test::privateInstanceMethod;
-
- SAM t9 = (SAM & Serializable) c -> {
-
- WarnSerializableLambdaTest.staticPackageField = "";
- WarnSerializableLambdaTest.staticProtectedField = "";
- WarnSerializableLambdaTest.staticPrivateField = "";
-
- packageField = "";
- protectedField = "";
- privateField = "";
-
- WarnSerializableLambdaTest.packageClassMethod(null);
- WarnSerializableLambdaTest.protectedClassMethod(null);
- WarnSerializableLambdaTest.privateClassMethod(null);
-
- packageInstanceMethod(null);
- protectedInstanceMethod(null);
- privateInstanceMethod(null);
-
- PrivateClass.effectivelyNonPublicStaticField = "";
- PrivateClass.effectivelyNonPublicClassMethod();
-
- PrivateClass p = new PrivateClass();
- p.effectivelyNonPublicInstanceField = "";
- p.effectivelyNonPublicInstanceMethod();
-
- return null;
- };
- }
-
- private void warnAnoInnerClass() throws Exception {
- new SerializableDesc() {
- public void m(Object param) throws Exception {
- WarnSerializableLambdaTest.staticPackageField = "";
- WarnSerializableLambdaTest.staticProtectedField = "";
- WarnSerializableLambdaTest.staticPrivateField = "";
-
- packageField = "";
- protectedField = "";
- privateField = "";
-
- WarnSerializableLambdaTest.packageClassMethod(null);
- WarnSerializableLambdaTest.protectedClassMethod(null);
- WarnSerializableLambdaTest.privateClassMethod(null);
-
- packageInstanceMethod(null);
- protectedInstanceMethod(null);
- privateInstanceMethod(null);
-
- PrivateClass.effectivelyNonPublicStaticField = "";
- PrivateClass.effectivelyNonPublicClassMethod();
-
- PrivateClass p = new PrivateClass();
- p.effectivelyNonPublicInstanceField = "";
- p.effectivelyNonPublicInstanceMethod();
- }
- };
- }
-
- void dontWarnLambda() throws Exception {
- SAM t1 = (SAM & Serializable)WarnSerializableLambdaTest::publicClassMethod;
-
- WarnSerializableLambdaTest test = new WarnSerializableLambdaTest();
- SAM t2 = (SAM & Serializable)test::publicInstanceMethod;
-
- int[] buffer = {0};
-
- SAM t3 = (SAM & Serializable) param -> {
- Object localVar;
- localVar = null;
- param = null;
-
- WarnSerializableLambdaTest.staticPublicField = "";
- publicField = "";
- WarnSerializableLambdaTest.publicClassMethod(null);
- publicInstanceMethod(null);
-
- PublicClass.effectivelyPublicStaticField = "";
- PublicClass.effectivelyPublicClassMethod();
-
- PublicClass p = new PublicClass();
- p.effectivelyPublicInstanceField = "";
- p.effectivelyPublicInstanceMethod();
-
- int l = buffer.length;
-
- return null;
- };
- }
-
- private void dontWarnAnoInnerClass() throws Exception {
- final int[] buffer = {0};
- new SerializableDesc() {
- public void m(Object param) throws Exception {
- Object localVar;
- localVar = null;
- param = null;
-
- WarnSerializableLambdaTest.staticPublicField = "";
- publicField = "";
- WarnSerializableLambdaTest.publicClassMethod(null);
- publicInstanceMethod(null);
-
- PublicClass.effectivelyPublicStaticField = "";
- PublicClass.effectivelyPublicClassMethod();
-
- PublicClass p = new PublicClass();
- p.effectivelyPublicInstanceField = "";
- p.effectivelyPublicInstanceMethod();
-
- int l = buffer.length;
- }
- };
- }
-
- enum WarnEnum {
- A {
- public void m() throws Exception {
- WarnSerializableLambdaTest.staticPackageField = "";
- WarnSerializableLambdaTest.staticProtectedField = "";
- WarnSerializableLambdaTest.staticPrivateField = "";
-
- WarnSerializableLambdaTest test =
- new WarnSerializableLambdaTest();
-
- test.packageField = "";
- test.protectedField = "";
- test.privateField = "";
-
- WarnSerializableLambdaTest.packageClassMethod(null);
- WarnSerializableLambdaTest.protectedClassMethod(null);
- WarnSerializableLambdaTest.privateClassMethod(null);
-
- test.packageInstanceMethod(null);
- test.protectedInstanceMethod(null);
- test.privateInstanceMethod(null);
-
- PrivateClass.effectivelyNonPublicStaticField = "";
- PrivateClass.effectivelyNonPublicClassMethod();
-
- PrivateClass p = new PrivateClass();
- p.effectivelyNonPublicInstanceField = "";
- p.effectivelyNonPublicInstanceMethod();
- }
- };
-
- public void m() throws Exception {}
- }
-
- static String staticPackageField;
- static private String staticPrivateField;
- static protected String staticProtectedField;
- static public String staticPublicField;
-
- String packageField;
- private String privateField;
- protected String protectedField;
- public String publicField;
-
- static Object packageClassMethod(String s) {
- return null;
- }
-
- static private Object privateClassMethod(String s) {
- return null;
- }
-
- static protected Object protectedClassMethod(String s) {
- return null;
- }
-
- static public Object publicClassMethod(String s) {
- return null;
- }
-
- Object packageInstanceMethod(String s) {
- return null;
- }
-
- protected Object protectedInstanceMethod(String s) {
- return null;
- }
-
- private Object privateInstanceMethod(String s) {
- return null;
- }
-
- public Object publicInstanceMethod(String s) {
- return null;
- }
-
- interface SAM {
- Object apply(String s) throws Exception;
- }
-
- interface SAM2 {
- Object apply(String arg1, String arg2);
- }
-
- class SerializableDesc implements Serializable {
- public void m(Object param) throws Exception {}
- }
-
- static private class PrivateClass {
- static public String effectivelyNonPublicStaticField;
- public String effectivelyNonPublicInstanceField;
-
- static public void effectivelyNonPublicClassMethod() {}
- public void effectivelyNonPublicInstanceMethod() {}
- }
-
- static public class PublicClass {
- static public String effectivelyPublicStaticField;
- public String effectivelyPublicInstanceField;
-
- static public void effectivelyPublicClassMethod() {}
- public void effectivelyPublicInstanceMethod() {}
- }
-}
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTest.out Wed Oct 19 08:05:48 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-WarnSerializableLambdaTest.java:15:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:16:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:17:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:20:38: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:21:38: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:22:38: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:26:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
-WarnSerializableLambdaTest.java:27:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
-WarnSerializableLambdaTest.java:28:39: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
-WarnSerializableLambdaTest.java:30:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
-WarnSerializableLambdaTest.java:31:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
-WarnSerializableLambdaTest.java:32:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
-WarnSerializableLambdaTest.java:34:39: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:35:39: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:36:39: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:38:13: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:39:13: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:40:13: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:42:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
-WarnSerializableLambdaTest.java:43:25: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
-WarnSerializableLambdaTest.java:46:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
-WarnSerializableLambdaTest.java:47:14: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
-WarnSerializableLambdaTest.java:56:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
-WarnSerializableLambdaTest.java:57:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
-WarnSerializableLambdaTest.java:58:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
-WarnSerializableLambdaTest.java:60:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
-WarnSerializableLambdaTest.java:61:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
-WarnSerializableLambdaTest.java:62:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
-WarnSerializableLambdaTest.java:64:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:65:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:66:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:68:17: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:69:17: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:70:17: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:72:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
-WarnSerializableLambdaTest.java:73:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
-WarnSerializableLambdaTest.java:76:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
-WarnSerializableLambdaTest.java:77:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
-WarnSerializableLambdaTest.java:141:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPackageField
-WarnSerializableLambdaTest.java:142:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticProtectedField
-WarnSerializableLambdaTest.java:143:43: compiler.warn.access.to.sensitive.member.from.serializable.element: staticPrivateField
-WarnSerializableLambdaTest.java:148:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageField
-WarnSerializableLambdaTest.java:149:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedField
-WarnSerializableLambdaTest.java:150:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateField
-WarnSerializableLambdaTest.java:152:43: compiler.warn.access.to.sensitive.member.from.serializable.element: packageClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:153:43: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:154:43: compiler.warn.access.to.sensitive.member.from.serializable.element: privateClassMethod(java.lang.String)
-WarnSerializableLambdaTest.java:156:21: compiler.warn.access.to.sensitive.member.from.serializable.element: packageInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:157:21: compiler.warn.access.to.sensitive.member.from.serializable.element: protectedInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:158:21: compiler.warn.access.to.sensitive.member.from.serializable.element: privateInstanceMethod(java.lang.String)
-WarnSerializableLambdaTest.java:160:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicStaticField
-WarnSerializableLambdaTest.java:161:29: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicClassMethod()
-WarnSerializableLambdaTest.java:164:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceField
-WarnSerializableLambdaTest.java:165:18: compiler.warn.access.to.sensitive.member.from.serializable.element: effectivelyNonPublicInstanceMethod()
-- compiler.err.warnings.and.werror
-1 error
-54 warnings
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.java Thu Oct 27 08:52:00 2016 -0700
@@ -4,7 +4,7 @@
* @summary Enhance compiler warnings for Lambda
* Checks that the warning for accessing non public members of a class is
* fired correctly.
- * @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToSensitiveMembers WarnSerializableLambdaTestb.java
+ * @compile/fail/ref=WarnSerializableLambdaTestb.out -XDrawDiagnostics -Werror -XDwarnOnAccessToMembers WarnSerializableLambdaTestb.java
*/
import java.io.Serializable;
--- a/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestb.out Thu Oct 27 08:52:00 2016 -0700
@@ -1,7 +1,5 @@
-WarnSerializableLambdaTestb.java:14:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
-WarnSerializableLambdaTestb.java:18:69: compiler.warn.access.to.sensitive.member.from.serializable.element: test()
-WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.sensitive.member.from.serializable.element: j
-WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.sensitive.member.from.serializable.element: r
+WarnSerializableLambdaTestb.java:36:40: compiler.warn.access.to.member.from.serializable.element: j
+WarnSerializableLambdaTestb.java:50:25: compiler.warn.access.to.member.from.serializable.element: r
- compiler.err.warnings.and.werror
1 error
-4 warnings
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8026721
+ * @summary Enhance Lambda serialization
+ * Checks that the warning for accessing non public members of a class is fired correctly.
+ * @compile -Xlint:serial -Werror WarnSerializableLambdaTestc.java
+ */
+
+import javax.tools.SimpleJavaFileObject;
+import java.io.Serializable;
+
+public class WarnSerializableLambdaTestc {
+ public interface SerializableIntf<T> extends Serializable {
+ String get(T o);
+ }
+
+ private void dontWarn() {
+ SerializableIntf<SimpleJavaFileObject> s = SimpleJavaFileObject::getName;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8029102/WarnSerializableLambdaTestc.out Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,4 @@
+WarnSerializableLambdaTestc.java:18:52: compiler.warn.access.to.member.from.serializable.lambda
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- a/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/javac/api/ToolProvider/ToolProviderTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -21,8 +21,11 @@
* questions.
*/
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Objects;
import javax.tools.ToolProvider;
-import java.util.Objects;
/**
* @test
@@ -36,6 +39,18 @@
// run in other vm to ensure the initialization code path is exercised.
public class ToolProviderTest {
public static void main(String... args) {
+ // The following code allows the test to be skipped when run on
+ // an exploded image.
+ // See https://bugs.openjdk.java.net/browse/JDK-8155858
+ Path javaHome = Paths.get(System.getProperty("java.home"));
+ Path image = javaHome.resolve("lib").resolve("modules");
+ Path modules = javaHome.resolve("modules");
+ if (!Files.exists(image) && Files.exists(modules)) {
+ System.err.println("Test running on exploded image");
+ System.err.println("Test skipped!");
+ return;
+ }
+
System.setSecurityManager(new SecurityManager());
Objects.requireNonNull(ToolProvider.getSystemDocumentationTool());
--- a/langtools/test/tools/javac/diags/CheckResourceKeys.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java Thu Oct 27 08:52:00 2016 -0700
@@ -257,6 +257,8 @@
// ignore package and class names
if (cs.matches("(com|java|javax|jdk|sun)\\.[A-Za-z.]+"))
continue;
+ if (cs.matches("(java|javax|sun)\\."))
+ continue;
// ignore debug flag names
if (cs.startsWith("debug."))
continue;
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Thu Oct 27 08:52:00 2016 -0700
@@ -111,6 +111,7 @@
compiler.err.cant.inherit.from.anon # error for subclass of anonymous class
compiler.misc.bad.class.file # class file is malformed
compiler.misc.bad.const.pool.entry # constant pool entry has wrong type
+compiler.warn.access.to.member.from.serializable.lambda # in order to generate it we need to modify a restricted package
# The following module-related messages will have to stay on the not-yet list for various reasons:
compiler.warn.locn.unknown.file.on.module.path # Never issued ATM (short circuited with an if (false))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalFilename.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+// key: compiler.note.removal.filename
+// key: compiler.note.removal.recompile
+// options: -Xlint:-removal
+
+class RemovalFilename {
+ RemovalClass d;
+}
+
+@Deprecated(forRemoval=true)
+class RemovalClass { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalFilenameAdditional.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+// key: compiler.note.removal.filename.additional
+// key: compiler.warn.has.been.deprecated.for.removal
+// options: -Xmaxwarns 1
+
+class RemovalFilename {
+ RemovalClass d;
+}
+
+class RemovalFilenameAdditional {
+ RemovalClass d;
+}
+
+@Deprecated(forRemoval=true)
+class RemovalClass { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPlural/RemovalClass.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+@Deprecated(forRemoval=true)
+class RemovalClass { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPlural/RemovalFilename.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+class RemovalFileName {
+ RemovalClass d;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPlural/RemovalPlural.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+// key: compiler.note.removal.plural
+// key: compiler.note.removal.recompile
+// options: -Xlint:-removal
+
+class RemovalPlural {
+ RemovalClass d;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPluralAdditional/RemovalClass.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+@Deprecated(forRemoval=true)
+class RemovalClass { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPluralAdditional/RemovalFilename.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+class RemovalFileName {
+ RemovalClass d;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPluralAdditional/RemovalPlural.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+class RemovalPlural {
+ RemovalClass d;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RemovalPluralAdditional/RemovalPluralAdditional.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+// key: compiler.note.removal.plural.additional
+// key: compiler.warn.has.been.deprecated.for.removal
+// options: -Xlint:deprecation -Xmaxwarns 1
+
+class RemovalPluralAdditional {
+ RemovalClass d;
+}
--- a/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/javac/diags/examples/WarnSerializableLambda.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,21 +21,24 @@
* questions.
*/
-// key: compiler.warn.access.to.sensitive.member.from.serializable.element
-// options: -XDwarnOnAccessToSensitiveMembers
+// key: compiler.warn.access.to.member.from.serializable.element
+// options: -XDwarnOnAccessToMembers
import java.io.Serializable;
public class WarnSerializableLambda {
- interface SAM {
- void apply(String s);
- }
-
private void m1() {
- SAM s = (SAM & Serializable) c -> {
- packageField = "";
+ new SerializableClass() {
+ @Override
+ public void m() {
+ packageField = "";
+ }
};
}
String packageField;
+
+ class SerializableClass implements Serializable {
+ public void m() {}
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8168480/T8168480.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,125 @@
+/*
+ * @test
+ * @bug 8168480
+ * @summary Speculative attribution of lambda causes NPE in Flow
+ * @compile T8168480.java
+ */
+
+import java.util.function.Supplier;
+
+class T8168480 {
+ void f(Runnable r) { }
+ void s(Supplier<Runnable> r) { }
+
+ private void testVoid(boolean cond) {
+ f(() ->
+ new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ }.run());
+
+ f(() ->
+ f(() -> {
+ switch (42) {
+ default:
+ break;
+ }
+ }));
+
+ f(() -> {
+ if (cond) {
+ new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ }.run();
+ } else {
+ f(() -> {
+ switch (42) {
+ default:
+ break;
+ }
+ });
+ }
+ });
+ }
+
+ private void testReturn(boolean cond) {
+ s(() ->
+ new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ });
+
+ s(() ->
+ () -> {
+ switch (42) {
+ default:
+ break;
+ }
+ });
+
+ s(() -> {
+ if (cond) {
+ return new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ };
+ } else {
+ return () -> {
+ switch (42) {
+ default:
+ break;
+ }
+ };
+ }
+ });
+
+ s(() -> {
+ return cond ?
+ new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ } : () -> {
+ switch (42) {
+ default:
+ break;
+ }
+ };
+ });
+
+ s(() -> cond ?
+ new Runnable() {
+ public void run() {
+ switch (42) {
+ default:
+ break;
+ }
+ }
+ } : () -> {
+ switch (42) {
+ default:
+ break;
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8168480/T8168480b.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8168480
+ * @summary Speculative attribution of lambda causes NPE in Flow
+ * @compile/fail/ref=T8168480b.out -XDrawDiagnostics T8168480b.java
+ */
+
+import java.util.function.Supplier;
+
+class T8168480b {
+ Supplier<Runnable> ssr = () -> () -> { while (true); System.err.println("Hello"); };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/8168480/T8168480b.out Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,2 @@
+T8168480b.java:11:57: compiler.err.unreachable.stmt
+1 error
--- a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, 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
@@ -26,6 +26,7 @@
* @bug 8002099 8010822
* @summary Add support for intersection types in cast expression
* @modules jdk.compiler/com.sun.tools.javac.util
+ * @run main/othervm IntersectionTargetTypeTest
*/
import com.sun.source.util.JavacTask;
--- a/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/javac/processing/model/testgetallmembers/Main.java Thu Oct 27 08:52:00 2016 -0700
@@ -31,6 +31,7 @@
*/
import java.io.File;
+import java.nio.file.Path;
import java.util.*;
import java.util.Map.Entry;
@@ -84,7 +85,9 @@
continue;
if (type.endsWith("module-info"))
continue;
- String moduleName = fm.asPath(file).getName(1).toString();
+ Path path = fm.asPath(file);
+ int moduleIndex = path.getNameCount() - type.split("\\Q.\\E").length - 1;
+ String moduleName = path.getName(moduleIndex).toString();
try {
ModuleElement me = elements.getModuleElement(moduleName);
me.getClass();
--- a/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/javac/processing/rounds/OverwriteBetweenCompilations.java Thu Oct 27 08:52:00 2016 -0700
@@ -25,7 +25,7 @@
* @test
* @bug 8038455
* @summary Verify that annotation processor can overwrite source and class files it generated
- * during previous compilations, and that the Symbols are updated appropriatelly.
+ * during previous compilations, and that the Symbols are updated appropriately.
* @library /tools/lib /tools/javac/lib/
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
--- a/langtools/test/tools/javac/profiles/ProfileOptionTest.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/javac/profiles/ProfileOptionTest.java Thu Oct 27 08:52:00 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -176,9 +176,14 @@
Arrays.asList(fo));
task.analyze();
- List<String> expectDiagCodes = (p.value >= e.getKey().value)
- ? Collections.<String>emptyList()
- : Arrays.asList("compiler.err.not.in.profile");
+ List<String> expectDiagCodes = new ArrayList<>();
+ if (fo.getName().equals("TPolicyFile.java")) {
+ expectDiagCodes.add("compiler.warn.has.been.deprecated.for.removal");
+ }
+
+ if (p.value < e.getKey().value) {
+ expectDiagCodes.add("compiler.err.not.in.profile");
+ }
checkDiags(opts + " " + fo.getName(), dl.getDiagnostics(), expectDiagCodes);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/Removal.java Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,544 @@
+/*
+ * 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 8145471
+ * @summary javac changes for enhanced deprecation
+ * @library /tools/lib
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * @modules jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox
+ * @run main Removal
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import toolbox.JavacTask;
+import toolbox.Task.Expect;
+import toolbox.Task.OutputKind;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+/*
+ * From JEP 277, JDK-8085614
+ *
+ * use site | API declaration site
+ * context | not dep. ord. dep. term. dep.
+ * +----------------------------------
+ * not dep. | N W W
+ * |
+ * ord. dep. | N N (2) W (4)
+ * |
+ * term. dep. | N N (3) W (5)
+ */
+
+public class Removal extends TestRunner {
+ public static void main(String... args) throws Exception {
+ Removal r = new Removal();
+ r.runTests(m -> new Object[] { Paths.get(m.getName()) });
+ r.report();
+ }
+
+ private final ToolBox tb = new ToolBox();
+ private final Path libSrc = Paths.get("lib").resolve("src");
+ private final Path libClasses = Paths.get("lib").resolve("classes");
+ int testCount = 0;
+
+ /**
+ * Options that may be used during compilation.
+ */
+ enum Options {
+ DEFAULT(),
+ XLINT_DEPRECATED("-Xlint:deprecation"),
+ XLINT_NO_REMOVAL("-Xlint:-removal");
+
+ Options(String... opts) {
+ this.opts = Arrays.asList(opts);
+ }
+
+ final List<String> opts;
+ }
+
+ /**
+ * The kind of deprecation.
+ */
+ enum DeprKind {
+ NONE("", null),
+ DEPRECATED("@Deprecated ", "compiler.warn.has.been.deprecated"),
+ REMOVAL("@Deprecated(forRemoval=true) ", "compiler.warn.has.been.deprecated.for.removal");
+ DeprKind(String anno, String warn) {
+ this.anno = anno;
+ this.warn = warn;
+ }
+ final String anno;
+ final String warn;
+ }
+
+ final String[] lib = {
+ "package lib; public class Class {\n"
+ + " public static void method() { }\n"
+ + " @Deprecated public static void depMethod() { }\n"
+ + " @Deprecated(forRemoval=true) public static void remMethod() { }\n"
+ + " public static int field;\n"
+ + " @Deprecated public static int depField;\n"
+ + " @Deprecated(forRemoval=true) public static int remField;\n"
+ + "}",
+ "package lib; @Deprecated public class DepClass { }",
+ "package lib; @Deprecated(forRemoval=true) public class RemClass { }"
+ };
+
+ /**
+ * The kind of declaration to be referenced at the use site.
+ */
+ enum RefKind {
+ CLASS("lib.%s c;", "Class", "DepClass", "RemClass"),
+ METHOD("{ lib.Class.%s(); }", "method", "depMethod", "remMethod"),
+ FIELD("int i = lib.Class.%s;", "field", "depField", "remField");
+
+ RefKind(String template, String def, String dep, String rem) {
+ fragments.put(DeprKind.NONE, String.format(template, def));
+ fragments.put(DeprKind.DEPRECATED, String.format(template, dep));
+ fragments.put(DeprKind.REMOVAL, String.format(template, rem));
+ }
+
+ String getFragment(DeprKind k) {
+ return fragments.get(k);
+ }
+
+ private final Map<DeprKind, String> fragments = new EnumMap<>(DeprKind.class);
+ }
+
+ /**
+ * Get source code for a reference to a possibly-deprecated item declared in a library.
+ * @param refKind the kind of element (class, method, field) being referenced
+ * @param declDeprKind the kind of deprecation on the declaration of the item being referenced
+ * @param useDeprKind the kind of deprecation enclosing the use site
+ * @return
+ */
+ static String getSource(RefKind refKind, DeprKind declDeprKind, DeprKind useDeprKind) {
+ return "package p; "
+ + useDeprKind.anno
+ + "class Class { "
+ + refKind.getFragment(declDeprKind)
+ + " }";
+ }
+
+ private static final String NO_OUTPUT = null;
+
+ public Removal() throws IOException {
+ super(System.err);
+ initLib();
+ }
+
+ void initLib() throws IOException {
+ tb.writeJavaFiles(libSrc, lib);
+
+ new JavacTask(tb)
+ .outdir(Files.createDirectories(libClasses))
+ .files(tb.findJavaFiles(libSrc))
+ .run()
+ .writeAll();
+ }
+
+ void report() {
+ out.println(testCount + " test cases");
+ }
+
+ /*
+ * Declaration site: not deprecated; use site: not deprecated
+ * Options: default
+ * Expect: no warnings
+ */
+ @Test
+ public void test_DeclNone_UseNone(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.NONE, DeprKind.NONE),
+ Options.DEFAULT,
+ NO_OUTPUT);
+ }
+ }
+
+ /*
+ * Declaration site: not deprecated; use site: deprecated
+ * Options: default
+ * Expect: no warnings
+ */
+ @Test
+ public void test_DeclNone_UseDeprecated(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.NONE, DeprKind.DEPRECATED),
+ Options.DEFAULT,
+ NO_OUTPUT);
+ }
+ }
+
+ /*
+ * Declaration site: not deprecated; use site: deprecated for removal
+ * Options: default
+ * Expect: no warnings
+ */
+ @Test
+ public void test_DeclNone_UseRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.NONE, DeprKind.REMOVAL),
+ Options.DEFAULT,
+ NO_OUTPUT);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated; use site: not deprecated
+ * Options: default
+ * Expect: deprecated note
+ */
+ @Test
+ public void test_DeclDeprecated_UseNone_Default(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.DEPRECATED, DeprKind.NONE),
+ Options.DEFAULT,
+ "compiler.note.deprecated.filename: Class.java");
+ }
+ }
+
+ /*
+ * Declaration site: deprecated; use site: not deprecated
+ * Options: -Xlint:deprecation
+ * Expect: deprecated warning
+ */
+ @Test
+ public void test_DeclDeprecated_UseNone_XlintDep(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ String error = "<unset>";
+ switch (rk) {
+ case CLASS:
+ error = "Class.java:1:29: compiler.warn.has.been.deprecated: lib.DepClass, lib";
+ break;
+
+ case METHOD:
+ error = "Class.java:1:37: compiler.warn.has.been.deprecated: depMethod(), lib.Class";
+ break;
+
+ case FIELD:
+ error = "Class.java:1:43: compiler.warn.has.been.deprecated: depField, lib.Class";
+ break;
+ }
+
+ test(base,
+ getSource(rk, DeprKind.DEPRECATED, DeprKind.NONE),
+ Options.XLINT_DEPRECATED,
+ error);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated; use site: deprecated
+ * Options: default
+ * Expect: no warnings
+ */
+ @Test
+ public void test_DeclDeprecated_UseDeprecated(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.DEPRECATED, DeprKind.DEPRECATED),
+ Options.DEFAULT,
+ NO_OUTPUT);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated; use site: deprecated for removal
+ * Options: default
+ * Expect: no warnings
+ */
+ @Test
+ public void test_DeclDeprecated_UseRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.DEPRECATED, DeprKind.REMOVAL),
+ Options.DEFAULT,
+ NO_OUTPUT);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: not deprecated
+ * Options: default
+ * Expect: removal warning
+ */
+ @Test
+ public void test_DeclRemoval_UseNone_Default(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ String error = "<unset>";
+ switch (rk) {
+ case CLASS:
+ error = "Class.java:1:29: compiler.warn.has.been.deprecated.for.removal: lib.RemClass, lib";
+ break;
+
+ case METHOD:
+ error = "Class.java:1:37: compiler.warn.has.been.deprecated.for.removal: remMethod(), lib.Class";
+ break;
+
+ case FIELD:
+ error = "Class.java:1:43: compiler.warn.has.been.deprecated.for.removal: remField, lib.Class";
+ break;
+ }
+
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.NONE),
+ Options.DEFAULT,
+ error);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: not deprecated
+ * Options: default, @SuppressWarnings("removal")
+ * Expect: removal warning
+ */
+ @Test
+ public void test_DeclRemoval_UseNone_SuppressRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ String source =
+ getSource(rk, DeprKind.REMOVAL, DeprKind.NONE)
+ .replace("class Class", "@SuppressWarnings(\"removal\") class Class");
+
+ test(base,
+ source,
+ Options.DEFAULT,
+ null);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: not deprecated
+ * Options: -Xlint:-removal
+ * Expect: removal note
+ */
+ @Test
+ public void test_DeclRemoval_UseNone_XlintNoRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.NONE),
+ Options.XLINT_NO_REMOVAL,
+ "compiler.note.removal.filename: Class.java");
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: deprecated
+ * Options: default
+ * Expect: removal warning
+ */
+ @Test
+ public void test_DeclRemoval_UseDeprecated_Default(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ String error = "<unset>";
+ switch (rk) {
+ case CLASS:
+ error = "Class.java:1:41: compiler.warn.has.been.deprecated.for.removal: lib.RemClass, lib";
+ break;
+
+ case METHOD:
+ error = "Class.java:1:49: compiler.warn.has.been.deprecated.for.removal: remMethod(), lib.Class";
+ break;
+
+ case FIELD:
+ error = "Class.java:1:55: compiler.warn.has.been.deprecated.for.removal: remField, lib.Class";
+ break;
+ }
+
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.DEPRECATED),
+ Options.DEFAULT,
+ error);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: deprecated
+ * Options: -Xlint:-removal
+ * Expect: removal note
+ */
+ @Test
+ public void test_DeclRemoval_UseDeprecated_XlintNoRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.DEPRECATED),
+ Options.XLINT_NO_REMOVAL,
+ "compiler.note.removal.filename: Class.java");
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: deprecated for removal
+ * Options: default
+ * Expect: removal warning
+ */
+ @Test
+ public void test_DeclRemoval_UseRemoval_Default(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ String error = "<unset>";
+ switch (rk) {
+ case CLASS:
+ error = "Class.java:1:58: compiler.warn.has.been.deprecated.for.removal: lib.RemClass, lib";
+ break;
+
+ case METHOD:
+ error = "Class.java:1:66: compiler.warn.has.been.deprecated.for.removal: remMethod(), lib.Class";
+ break;
+
+ case FIELD:
+ error = "Class.java:1:72: compiler.warn.has.been.deprecated.for.removal: remField, lib.Class";
+ break;
+ }
+
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.REMOVAL),
+ Options.DEFAULT,
+ error);
+ }
+ }
+
+ /*
+ * Declaration site: deprecated for removal; use site: deprecated for removal
+ * Options: -Xlint:-removal
+ * Expect: removal note
+ */
+ @Test
+ public void test_DeclRemoval_UseRemoval_XlintNoRemoval(Path base) throws IOException {
+ for (RefKind rk : RefKind.values()) {
+ test(base,
+ getSource(rk, DeprKind.REMOVAL, DeprKind.REMOVAL),
+ Options.XLINT_NO_REMOVAL,
+ "compiler.note.removal.filename: Class.java");
+ }
+ }
+
+ /*
+ * Additional special case:
+ * there should not be any warnings for any reference in a type-import statement.
+ */
+ @Test
+ public void test_UseImports(Path base) throws IOException {
+ String source =
+ "import lib.Class;\n"
+ + "import lib.DepClass;\n"
+ + "import lib.RemClass;\n"
+ + "class C { }";
+ for (Options o : Options.values()) {
+ test(base, source, o, NO_OUTPUT);
+ }
+ }
+
+ /**
+ * Compile source code with given options, and check for expected output.
+ * The compilation is done twice, first against the library in source form,
+ * and then again, against the compiled library.
+ * @param base base working directory
+ * @param source the source code to be compiled
+ * @param options the options for the compilation
+ * @param expectText the expected output, or NO_OUTPUT, if none expected.
+ * @throws IOException if an error occurs during the compilation
+ */
+ private void test(Path base, String source, Options options, String expectText) throws IOException {
+ test(base.resolve("lib-source"), libSrc, source, options, expectText);
+ test(base.resolve("lib-classes"), libClasses, source, options, expectText);
+ }
+
+ /**
+ * Compile source code with given options against a given version of the library,
+ * and check for expected output.
+ * @param base base working directory
+ * @param lib the directory containing the library, in either source or compiled form
+ * @param source the source code to be compiled
+ * @param options the options for the compilation
+ * @param expectText the expected output, or NO_OUTPUT, if none expected.
+ * @throws IOException if an error occurs during the compilation
+ */
+ private void test(Path base, Path lib, String source, Options options, String expectText)
+ throws IOException {
+ Expect expect = (expectText != null && expectText.contains("compiler.warn.")) ? Expect.FAIL : Expect.SUCCESS;
+ test(base, lib, source, options.opts, expect, expectText);
+ }
+
+ /**
+ * Compile source code with given options against a given version of the library,
+ * and check for expected exit code and expected output.
+ * @param base base working directory
+ * @param lib the directory containing the library, in either source or compiled form
+ * @param source the source code to be compiled
+ * @param options the options for the compilation
+ * @param expect the expected outcome of the compilation
+ * @param expectText the expected output, or NO_OUTPUT, if none expected.
+ * @throws IOException if an error occurs during the compilation
+ */
+ private void test(Path base, Path lib, String source, List<String> options,
+ Expect expect, String expectText) throws IOException {
+ testCount++;
+
+ Path src = base.resolve("src");
+ Path classes = Files.createDirectories(base.resolve("classes"));
+ tb.writeJavaFiles(src, source);
+
+ List<String> allOptions = new ArrayList<>();
+ allOptions.add("-XDrawDiagnostics");
+ allOptions.add("-Werror");
+ allOptions.addAll(options);
+
+ out.println("Source: " + source);
+ out.println("Classpath: " + lib);
+ out.println("Options: " + options.stream().collect(Collectors.joining(" ")));
+
+ String log = new JavacTask(tb)
+ .outdir(classes)
+ .classpath(lib) // use classpath for libSrc or libClasses
+ .files(tb.findJavaFiles(src))
+ .options(allOptions.toArray(new String[0]))
+ .run(expect)
+ .writeAll()
+ .getOutput(OutputKind.DIRECT);
+
+ if (expectText == null) {
+ if (!log.trim().isEmpty())
+ error("Unexpected text found: >>>" + log + "<<<");
+ } else {
+ if (!log.contains(expectText))
+ error("expected text not found: >>>" + expectText + "<<<");
+ }
+ }
+}
+
--- a/langtools/test/tools/lib/toolbox/JavadocTask.java Wed Oct 19 08:05:48 2016 -0700
+++ b/langtools/test/tools/lib/toolbox/JavadocTask.java Thu Oct 27 08:52:00 2016 -0700
@@ -38,7 +38,9 @@
import java.util.stream.Stream;
import javax.tools.DocumentationTool.DocumentationTask;
+import javax.tools.DocumentationTool;
import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
@@ -303,7 +305,8 @@
if (fileManager == null)
fileManager = internalFileManager = jdtool.getStandardFileManager(null, null, null);
if (outdir != null)
- setLocationFromPaths(StandardLocation.CLASS_OUTPUT, Collections.singletonList(outdir));
+ setLocationFromPaths(DocumentationTool.Location.DOCUMENTATION_OUTPUT,
+ Collections.singletonList(outdir));
if (classpath != null)
setLocationFromPaths(StandardLocation.CLASS_PATH, classpath);
if (sourcepath != null)
@@ -326,7 +329,7 @@
}
}
- private void setLocationFromPaths(StandardLocation location, List<Path> files) throws IOException {
+ private void setLocationFromPaths(Location location, List<Path> files) throws IOException {
if (!(fileManager instanceof StandardJavaFileManager))
throw new IllegalStateException("not a StandardJavaFileManager");
((StandardJavaFileManager) fileManager).setLocationFromPaths(location, files);
--- a/make/Javadoc.gmk Wed Oct 19 08:05:48 2016 -0700
+++ b/make/Javadoc.gmk Thu Oct 27 08:52:00 2016 -0700
@@ -22,140 +22,16 @@
# questions.
#
+default: all
+
include $(SPEC)
include MakeBase.gmk
-#################################################################
-#
-# CORE_PKGS environment variable has been moved to the following file
-#
-include CORE_PKGS.gmk
-#
-# Load environment variables for API package names that are not part of
-# the Java SE platform
-#
-include NON_CORE_PKGS.gmk
-
-
-.SUFFIXES: # Delete the default suffixes
-.SUFFIXES: .java
-
-#
-# Definitions for directories
-#
-
-DOCSDIR := $(DOCS_IMAGE_DIR)
-DOCSTMPDIR = $(SUPPORT_OUTPUTDIR)/docs
-
-HOTSPOT_DOCS_IMPORT_PATH=$(HOTSPOT_OUTPUTDIR)/docs
-
-JAVADOC_CMD = $(JAVA) \
- -Djava.awt.headless=true \
- $(NEW_JAVADOC)
-
-JAVADOC_CMD_SMALL = $(JAVA_SMALL) \
- -Djava.awt.headless=true \
- $(NEW_JAVADOC)
-
-# Copyright year for beginning of Java and some of the apis
-# (Needed when creating the javadocs)
-FIRST_COPYRIGHT_YEAR = 1993
-DOMAPI_FIRST_COPYRIGHT_YEAR = 2005
-MIRROR_FIRST_COPYRIGHT_YEAR = 2004
-DOCLETAPI_FIRST_COPYRIGHT_YEAR = 1993
-TAGLETAPI_FIRST_COPYRIGHT_YEAR = 1993
-JDI_FIRST_COPYRIGHT_YEAR = 1999
-JAAS_FIRST_COPYRIGHT_YEAR = 1998
-JGSS_FIRST_COPYRIGHT_YEAR = 2000
-SMARTCARDIO_FIRST_COPYRIGHT_YEAR = 2005
-HTTPSERVER_FIRST_COPYRIGHT_YEAR = 2005
-MGMT_FIRST_COPYRIGHT_YEAR = 2003
-ATTACH_FIRST_COPYRIGHT_YEAR = 2005
-JCONSOLE_FIRST_COPYRIGHT_YEAR = 2006
-SCTPAPI_FIRST_COPYRIGHT_YEAR = 2009
-TRACING_FIRST_COPYRIGHT_YEAR = 2008
-JSHELLAPI_FIRST_COPYRIGHT_YEAR = 2015
-TREEAPI_FIRST_COPYRIGHT_YEAR = 2005
-NASHORNAPI_FIRST_COPYRIGHT_YEAR = 2014
-DYNALINKAPI_FIRST_COPYRIGHT_YEAR = 2015
-JNLP_FIRST_COPYRIGHT_YEAR = 1998
-PLUGIN2_FIRST_COPYRIGHT_YEAR = 2007
-JDKNET_FIRST_COPYRIGHT_YEAR = 2014
-JACCESSAPI_FIRST_COPYRIGHT_YEAR = 2002
-JSOBJECT_FIRST_COPYRIGHT_YEAR = 1993
-
-# Oracle name
-FULL_COMPANY_NAME = Oracle and/or its affiliates
-
-# Copyright address
-COMPANY_ADDRESS = 500 Oracle Parkway<br>Redwood Shores, CA 94065 USA.
-
-# The trademark symbol
-TRADEMARK = ™
-
-# Common copyright lines used
-# The word "Copyright" might optionally be a link to the file cpyr.html.
-# The first year of copyright may vary or not be available.
-# The address to the company might be optional.
-COMMA:= ,
-EMPTY:=
-SPACE:=$(EMPTY) $(EMPTY)
-COPYRIGHT_SYMBOL = &\#x00a9;
-# Macro to construct the copyright line
-# (The GNU make 3.78.1 "if" conditional is broken, fixed in GNU make 3.81)
-define CopyrightLine # optionalurl optionalfirstyear optionaladdress
-$(if $(strip $1),<a href="$(strip $1)">Copyright</a>,Copyright) \
-$(COPYRIGHT_SYMBOL) $(if $2,$2${COMMA},) $(COPYRIGHT_YEAR),\
-$(FULL_COMPANY_NAME). $3 All rights reserved.
-endef
-
-# Url to root of documents
-DOCSDIR_URL = {@docroot}/$(GET2DOCSDIR)
-
-# Url to copyright html file
-COPYRIGHT_URL = $(DOCSDIR_URL)/legal/cpyr.html
-
-# Url to bug filing site
-BUG_SUBMIT_URL = http://bugreport.java.com/bugreport/
-
-# Common line for how to submit a bug or rfe
-BUG_SUBMIT_LINE = <a href="$(BUG_SUBMIT_URL)">Submit a bug or feature</a>
-
-# Url to devdocs page
-DOCS_BASE_URL = http://docs.oracle.com/javase/$(VERSION_SPECIFICATION)/docs
-DEV_DOCS_URL = $(DOCS_BASE_URL)/index.html
-
-# Common Java trademark line
-JAVA_TRADEMARK_LINE = Java is a trademark or registered trademark of \
-$(FULL_COMPANY_NAME) in the US and other countries.
-
-#################################################################
-# Macros:
-
+################################################################################
# List of all possible directories for javadoc to look for sources
-# NOTE: Quotes are required around sourcepath argument only on Windows.
-# Otherwise, you get "No packages or classes specified." due
-# to $(PATH_SEP) being interpreted as an end of
-# command (newline or shell ; character)
-ALL_SOURCE_DIRS := $(wildcard \
- $(SUPPORT_OUTPUTDIR)/gensrc/j* \
- $(if $(IMPORT_MODULES_SRC), $(IMPORT_MODULES_SRC)/*) \
- $(JDK_TOPDIR)/src/*/$(OPENJDK_TARGET_OS)/classes \
- $(JDK_TOPDIR)/src/*/$(OPENJDK_TARGET_OS_TYPE)/classes \
- $(JDK_TOPDIR)/src/*/share/classes \
- $(HOTSPOT_TOPDIR)/src/*/share/classes \
- $(LANGTOOLS_TOPDIR)/src/*/share/classes \
- $(NASHORN_TOPDIR)/src/*/share/classes \
- $(CORBA_TOPDIR)/src/*/share/classes \
- $(JAXP_TOPDIR)/src/*/share/classes \
- $(JAXWS_TOPDIR)/src/*/share/classes \
- $(SUPPORT_OUTPUTDIR)/rmic/j* \
- $(JDK_TOPDIR)/src/*/share/doc/stub \
- ) \
- #
-
-ALL_MODULE_SOURCE_DIRS := \
+# Allow custom to overwrite.
+JAVADOC_SOURCE_DIRS = \
$(SUPPORT_OUTPUTDIR)/gensrc/* \
$(if $(IMPORT_MODULES_SRC), $(IMPORT_MODULES_SRC)/*) \
$(JDK_TOPDIR)/src/*/$(OPENJDK_TARGET_OS)/classes \
@@ -171,181 +47,56 @@
$(JDK_TOPDIR)/src/*/share/doc/stub \
#
-
-# List with classpath separator between them
-EMPTY:=
-SPACE:= $(EMPTY) $(EMPTY)
-RELEASEDOCS_SOURCEPATH = \
- $(subst $(SPACE),$(PATH_SEP),$(strip $(ALL_SOURCE_DIRS)))
-
-RELEASEDOCS_MODULESOURCEPATH = \
- $(subst $(SPACE),$(PATH_SEP),$(strip $(ALL_MODULE_SOURCE_DIRS)))
-
-define prep-target
- $(MKDIR) -p $(@D)
- $(RM) $@
-endef
-
-# Prep for javadoc creation, assumes $@ is an index.html file
-define prep-javadoc
- @if [ -f "$@" -a "$?" != "" ] ; then \
- $(ECHO) "# Dependencies have changed: $?"; \
- fi
- $(RM) -r $(@D)
- $(MKDIR) -p $(@D)
-endef
-
-$(eval $(call FillCacheFind, $(ALL_SOURCE_DIRS)))
-define PackageDependencies
- $(call CacheFind, $(wildcard $(foreach p, $(subst .,/,$1), $(addsuffix /$p, $(ALL_SOURCE_DIRS)))))
-endef
-
-# Given a list of packages, add packages that exist to $@, print summary
-define PackageFilter # packages
- @if [ "$1" != "" ] ; then \
- for p in $1 ; do \
- pd=`$(ECHO) $${p} | $(SED) -e 's@[.]@/@g'`; \
- found="false"; \
- for cp in $(ALL_SOURCE_DIRS) ; do \
- if [ -d $${cp}/$${pd} ] ; then \
- $(ECHO) "$${p}" >> $@; \
- found="true"; \
- break; \
- fi; \
- done; \
- if [ "$${found}" = "false" ] ; then \
- $(ECHO) "WARNING: Package not found: $${p}"; \
- fi; \
- done; \
- fi
-endef
-
-# Print out a summary of the javadoc command about to be run
-define JavadocSummary # optionsfile packagesfile
- @$(ECHO) "# Running javadoc for $(patsubst $(OUTPUT_ROOT)/%,%,$@)" $(LOG_WARN)
- @($(ECHO) "# Options (`$(BASENAME) $1`):"; $(SED) -e 's@^@# @' $1) $(LOG_DEBUG)
- @($(ECHO) "# Packages (`$(BASENAME) $2`):";$(SED) -e 's@^@# @' $2) $(LOG_DEBUG)
-endef
-
-#
-# Different api directories created from root directory
-#
-COREAPI_DOCSDIR = $(DOCSDIR)/api
-JDK_API_DOCSDIR = $(DOCSDIR)/jdk/api
-JRE_API_DOCSDIR = $(DOCSDIR)/jre/api
-PLATFORM_DOCSDIR = $(DOCSDIR)/platform
-
-JAVADOC_ARCHIVE_NAME := jdk-$(VERSION_STRING)-docs.zip
-JAVADOC_ARCHIVE_ASSEMBLY_DIR := $(DOCSTMPDIR)/zip-docs
-JAVADOC_ARCHIVE_DIR := $(OUTPUT_ROOT)/bundles
-JAVADOC_ARCHIVE := $(JAVADOC_ARCHIVE_DIR)/$(JAVADOC_ARCHIVE_NAME)
+# Should we use -Xdocrootparent? Allow custom to overwrite.
+DOCROOTPARENT_FLAG = TRUE
# The core api index file is the target for the core api javadocs rule
# and needs to be defined early so that all other javadoc rules may
# depend on it.
-COREAPI_INDEX_FILE = $(COREAPI_DOCSDIR)/index.html
-
-# The non-core api javadocs need to be able to access the root of the core
-# api directory, so for jdk/api or jre/api to get to the core api/
-# directory we would use this:
-JDKJRE2COREAPI = ../../api
-
-# Common bottom argument
-define CommonBottom # year
-<font size="-1"><br> $(call CopyrightLine,,$1,)</font>
-endef
-
-# Common trademark bottom argument (Not sure why this is used sometimes)
-define CommonTrademarkBottom # year
-<font size="-1">\
-$(BUG_SUBMIT_LINE)<br>$(JAVA_TRADEMARK_LINE)<br>\
-$(call CopyrightLine,,$1,$(COMPANY_ADDRESS))\
-</font>
-endef
+CORE_INDEX_FILE := $(JAVADOC_OUTPUTDIR)/api/index.html
-# Common echo of option
-define OptionOnly # opt
- if [ "$(strip $1)" != "" ] ; then \
- $(PRINTF) "%s\n" "$(strip $1)"; \
- fi
-endef
-
-define OptionPair # opt arg
- $(PRINTF) "%s '%s'\n" "$(strip $1)" '$(strip $2)'
-endef
+# Symbols
+TRADEMARK := ™
+COPYRIGHT_SYMBOL := &$(HASH)x00a9;
+COPYRIGHT_TEXT := Copyright
+ALL_RIGHTS_RESERVED := All rights reserved.
-define OptionTrip # opt arg arg
- $(PRINTF) "%s '%s' '%s'\n" "$(strip $1)" '$(strip $2)' '$(strip $3)'
-endef
+# URLs
+JAVADOC_BASE_URL := http://docs.oracle.com/javase/$(VERSION_SPECIFICATION)/docs
+BUG_SUBMIT_URL := http://bugreport.java.com/bugreport/
-# Core api bottom argument (with special sauce)
-COREAPI_BOTTOM = <font size="-1"> $(BUG_SUBMIT_LINE)\
-<br>For further API reference and developer documentation, \
-see <a href="$(DEV_DOCS_URL)" target="_blank">Java SE Documentation</a>. \
-That documentation contains more detailed, developer-targeted descriptions, \
-with conceptual overviews, definitions of terms, workarounds, \
-and working code examples.<br>\
-$(call CopyrightLine,$(COPYRIGHT_URL),$(FIRST_COPYRIGHT_YEAR),)\
-</font>
-
-# Common javadoc options used by all bundles
+################################################################################
+# Text snippets
-# This flag may be overridden from a custom makefile
-DOCROOTPARENT_FLAG = -Xdocrootparent $(DOCS_BASE_URL)
+FULL_COMPANY_NAME := Oracle and/or its affiliates
+COMPANY_ADDRESS := 500 Oracle Parkway<br>Redwood Shores, CA 94065 USA.
+BUG_SUBMIT_LINE := <a href="$(BUG_SUBMIT_URL)">Submit a bug or feature</a>
+JAVA_TRADEMARK_LINE := Java is a trademark or registered trademark of \
+ $(FULL_COMPANY_NAME) in the US and other countries.
-define COMMON_JAVADOCFLAGS
- $(call OptionOnly,-XDignore.symbol.file=true) ; \
- $(call OptionOnly,-quiet) ; \
- $(call OptionOnly,-use) ; \
- $(call OptionOnly,-keywords) ; \
- $(call OptionOnly,$(DOCROOTPARENT_FLAG))
-endef
-
-# Common javadoc tags used by all bundles
-
-# Java language specification cite
-TAG_JLS = jls:a:See <cite> \
-The Java™ Language Specification</cite>:
-
-# Java virtual machine specification cite
-TAG_JVMS = jvms:a:See <cite> \
-The Java™ Virtual Machine Specification</cite>:
+COMMON_BOTTOM_ADDRESS := $(COMPANY_ADDRESS)
+COMMON_BOTTOM_TEXT := $(BUG_SUBMIT_LINE)<br>$(JAVA_TRADEMARK_LINE)
-# In order to get a specific ordering it's necessary to specify the total
-# ordering of tags as the tags are otherwise ordered in order of definition.
-define COMMON_JAVADOCTAGS
- $(call OptionPair,-tag,beaninfo:X) ; \
- $(call OptionPair,-tag,revised:X) ; \
- $(call OptionPair,-tag,since.unbundled:X) ; \
- $(call OptionPair,-tag,spec:X) ; \
- $(call OptionPair,-tag,specdefault:X) ; \
- $(call OptionPair,-tag,Note:X) ; \
- $(call OptionPair,-tag,ToDo:X) ; \
- $(call OptionPair,-tag,apiNote:a:API Note:) ; \
- $(call OptionPair,-tag,implSpec:a:Implementation Requirements:) ; \
- $(call OptionPair,-tag,implNote:a:Implementation Note:) ; \
- $(call OptionPair,-tag,param) ; \
- $(call OptionPair,-tag,return) ; \
- $(call OptionPair,-tag,throws) ; \
- $(call OptionPair,-tag,since) ; \
- $(call OptionPair,-tag,version) ; \
- $(call OptionPair,-tag,serialData) ; \
- $(call OptionPair,-tag,factory) ; \
- $(call OptionPair,-tag,see) ; \
- $(call OptionPair,-tag,$(TAG_JVMS)) ; \
- $(call OptionPair,-tag,$(TAG_JLS))
-endef
+CORE_BOTTOM_COPYRIGHT_URL := {@docroot}/../legal/cpyr.html
+CORE_BOTTOM_TEXT := $(BUG_SUBMIT_LINE)\
+<br>For further API reference and developer documentation, \
+see <a href="$(JAVADOC_BASE_URL)/index.html" target="_blank">Java SE \
+Documentation</a>. That documentation contains more detailed, \
+developer-targeted descriptions, with conceptual overviews, definitions of \
+terms, workarounds, and working code examples.
-
-
-# Assume we need a draft format when the version string is not a GA version.
-ifeq ($(VERSION_IS_GA), false)
+ifeq ($(VERSION_IS_GA), true)
+ DRAFT_HEADER :=
+ DRAFT_BOTTOM :=
+ DRAFT_WINTITLE :=
+ CORE_TOP_EARLYACCESS :=
+else
+ # We need a draft format when not building the GA version.
DRAFT_HEADER := <br><strong>DRAFT $(VERSION_STRING)</strong>
DRAFT_BOTTOM := <br><strong>DRAFT $(VERSION_STRING)</strong>
DRAFT_WINTITLE := $(VERSION_BUILD)
- # Early access top text (not used in FCS releases)
- COREAPI_TOP_EARLYACCESS := \
-<div style="background-color: \#EEEEEE"> \
+ CORE_TOP_EARLYACCESS := \
+<div style="background-color: $$(HASH)EEEEEE"> \
<div style="padding: 6px; margin-top: 2px; margin-bottom: 6px; \
margin-left: 6px; margin-right: 6px; text-align: justify; \
font-size: 80%; font-family: Helvetica, Arial, sans-serif; \
@@ -355,1384 +106,932 @@
The information is being made available to you solely for purpose of \
evaluation. \
</div> </div>
-else
- DRAFT_HEADER :=
- DRAFT_BOTTOM :=
- DRAFT_WINTITLE :=
- COREAPI_TOP_EARLYACCESS :=
endif
-#################################################################
+################################################################################
+# Support functions for SetupJavadocGeneration
-#
-# Load custom Javadoc rules
-#
-
-$(eval $(call IncludeCustomExtension, , Javadoc.gmk))
+# Print an option line to the target file
+# Arguments:
+# arg 1: the option name
+# arg 2-3: optional arguments to the option
+define AddOption
+ $(PRINTF) "%s$(if $(strip $2), '%s',)$(if $(strip $3), '%s',)\n" \
+ "$(strip $1)"$(if $(strip $2), '$(strip $2)',)$(if $(strip $3), \
+ '$(strip $3)',) >> $@
+endef
-#################################################################
+# This function goes to great pains to exactly mimic the old behavior
+# in all details, including whitespace.
+# Note that COPYRIGHT_YEAR is the current year (from spec.gmk)
+# Arguments:
+# arg 1: first copyright year
+# arg 2: copyright url (optional)
+# arg 3: company address (optional)
+# arg 4: free-form text snippet (optional)
+define GenerateBottom
+ <font size="-1">$(if $(strip $4), $(strip $4))<br> $(if \
+ $(strip $2),<a href="$(strip $2)">$(COPYRIGHT_TEXT)</a>,$(COPYRIGHT_TEXT)) \
+ $(COPYRIGHT_SYMBOL) $(strip $1), $(COPYRIGHT_YEAR), \
+ $(FULL_COMPANY_NAME). $(strip $3) \
+ $(ALL_RIGHTS_RESERVED)$(if $(strip $4), )</font>
+endef
-#
-# Default target is same as docs target, create core api and all others it can
+# Speed up finding by filling cache
+$(eval $(call FillCacheFind, $(wildcard $(JAVADOC_SOURCE_DIRS))))
+
+# Prevent # from expanding
+EscapeHash = $(subst $(HASH),{hash},$(strip $1))
+
+################################################################################
+# Setup make rules for running javadoc.
#
-
-all: docs
-docs: coredocs otherdocs
-
+# Parameter 1 is the name of the rule. This name is used as variable prefix,
+# and the targets generated are listed in a variable by that name. Note that
+# the index.html file will work as a "touch file" for all the magnitude of
+# files that are generated by javadoc.
#
-# Optional target which bundles all generated javadocs into a zip archive.
-# The dependency on docs is handled in Main.gmk.
-#
-
-zip-docs: $(JAVADOC_ARCHIVE)
-
-#############################################################
+# Remaining parameters are named arguments. These include:
+# MODULES - Modules to include
+# PACKAGES - Packages to include
+# PACKAGE_FILTER - Filter for packages
+# IS_CORE - Set to TRUE for the Core API package which needs special treatment
+# API_ROOT - Where to base the documentation (jre or jdk)
+# DEST_DIR - A directory relative to the API root
+# OVERVIEW - Path to a html overview file
+# TITLE - Default title to use for the more specific versions below
+# WINDOW_TITLE - Title to use in -windowtitle. Computed from TITLE if empty.
+# HEADER_TITLE - Title to use in -header. Computed from TITLE if empty.
+# DOC_TITLE - Title to use in -doctitle. Computed from TITLE if empty.
+# FIRST_COPYRIGHT_YEAR - First year this bundle was introduced
+# DOCLINT - Doclint level. Defaults to "all".
+# DOCLINT_PACKAGES - Optional -Xdoclint/package value
+# ENCODING - Change character encoding (defaults to 'ascii')
+# SPLIT_INDEX - Enable -splitIndex
+# BREAKITERATOR - Enable -breakiterator
+# NODEPRECATEDLIST - Enable nodeprecatedlist
+# NOINDEX - Enable -noindex and -nonavbar
+# BOTTOM_COPYRIGHT_URL - Copyright URL to use in -bottom
+# BOTTOM_ADDRESS - Company address to use in -bottom
+# BOTTOM_TEXT - Extra text to use in -bottom
+# EXTRA_TOP - Additional -top data
#
-# coredocs
-#
-COREAPI_DOCTITLE = Java$(TRADEMARK) Platform, Standard Edition \
-$(VERSION_SPECIFICATION)<br>API Specification
-COREAPI_WINDOWTITLE = Java Platform SE $(VERSION_SPECIFICATION)
-COREAPI_HEADER = \
-<strong>Java$(TRADEMARK) Platform<br>Standard Ed. $(VERSION_SPECIFICATION)</strong>
+SetupJavadocGeneration = $(NamedParamsMacroTemplate)
+define SetupJavadocGenerationBody
+ ifeq ($$($1_IS_CORE), TRUE)
+ $1_JAVA := $$(JAVA)
+ $1_OUTPUT_DIRNAME := api
+ else
+ $1_JAVA := $$(JAVA_SMALL)
+ $1_OUTPUT_DIRNAME := $$($1_API_ROOT)/api/$$($1_DEST_DIR)
+
+ ifeq ($$($1_RELATIVE_CORE_DIR),)
+ # Compute a relative path to core root.
+ # The non-core api javadocs need to be able to access the root of the core
+ # api directory, so for jdk/api or jre/api to get to the core api/
+ # directory we would use this
+ # NOTE: Need to be able to override for broken old code in JShell
+ $1_RELATIVE_CORE_DIR := $$(strip $$(subst $$(call DirToDotDot, \
+ $$(JAVADOC_OUTPUTDIR))/,, $$(call DirToDotDot, \
+ $$(JAVADOC_OUTPUTDIR)/$$($1_OUTPUT_DIRNAME))))
+ endif
+
+ $1_DEPS += $(CORE_INDEX_FILE)
+ endif
-# Overview file for core apis
-COREAPI_OVERVIEW = $(JDK_TOPDIR)/src/java.base/share/classes/overview-core.html
+ ifneq ($$($1_OVERVIEW), )
+ $1_DEPS += $$($1_OVERVIEW)
+ endif
+
+ ifeq ($$($1_ENCODING), )
+ $1_ENCODING := ascii
+ endif
+
+ ifeq ($$($1_DOCLINT), )
+ $1_DOCLINT := all
+ endif
+
+ ifeq ($$($1_DOC_TITLE), )
+ $1_DOC_TITLE := $$($1_TITLE)
+ endif
+
+ ifeq ($$($1_WINDOW_TITLE), )
+ $1_WINDOW_TITLE := $$(strip $$(subst $$(TRADEMARK),, $$($1_TITLE)))
+ endif
+
+ ifeq ($$($1_HEADER_TITLE), )
+ $1_HEADER_TITLE := $$(strip $$(subst $$(TRADEMARK),, $$($1_TITLE)))
+ endif
+ $1_HEADER := <strong>$$($1_HEADER_TITLE)</strong>
-# The options and packages files
-COREAPI_OPTIONS_FILE = $(DOCSTMPDIR)/coredocs.options
-COREAPI_PACKAGES_FILE = $(DOCSTMPDIR)/coredocs.packages
+ $1_BOTTOM := $$(call GenerateBottom, $$($1_FIRST_COPYRIGHT_YEAR), \
+ $$($1_BOTTOM_COPYRIGHT_URL), $$($1_BOTTOM_ADDRESS), $$($1_BOTTOM_TEXT))
-# The modules required to be documented
-COREAPI_MODULES = java.se.ee
+ # The index.html, options, and packages files
+ $1_INDEX_FILE := $$(JAVADOC_OUTPUTDIR)/$$($1_OUTPUT_DIRNAME)/index.html
+ $1_OPTIONS_FILE := $$(SUPPORT_OUTPUTDIR)/docs/$1.options
+ $1_PACKAGES_FILE := $$(SUPPORT_OUTPUTDIR)/docs/$1.packages
-coredocs: $(COREAPI_INDEX_FILE)
+ $1_PACKAGES_VARDEPS := $$($1_PACKAGES) $$($1_PACKAGES_SINGLE_CLASS)
+ $1_PACKAGES_VARDEPS_FILE := $$(call DependOnVariable, $1_PACKAGES_VARDEPS, \
+ $$($1_PACKAGES_FILE).vardeps)
-# Set relative location to core api document root
-$(COREAPI_INDEX_FILE): GET2DOCSDIR=..
+ # Rule for creating a file with the package names in it
+ $$($1_PACKAGES_FILE): $$($1_PACKAGES_VARDEPS_FILE)
+ $$(call LogInfo, Creating Javadoc package file for $1)
+ $$(call MakeDir, $$(@D))
+ ifeq ($$($1_PACKAGES_SINGLE_CLASS), )
+ $$(ECHO) $$($1_PACKAGES) | $$(TR) ' ' '\n' > $$@
+ else
+ # NOTE: This is for backwards compatibility for taglet
+ $$(ECHO) $$($1_PACKAGES_SINGLE_CLASS) > $$@
+ endif
-# Run javadoc if the index file is out of date or missing
-$(COREAPI_INDEX_FILE): $(COREAPI_OPTIONS_FILE) $(COREAPI_PACKAGES_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(COREAPI_OPTIONS_FILE),$(COREAPI_PACKAGES_FILE))
- $(JAVADOC_CMD) -d $(@D) \
- @$(COREAPI_OPTIONS_FILE) @$(COREAPI_PACKAGES_FILE)
+ # NOTE: Not including $$($1_EXTRA_TOP) due to $$(HASH)
+ $1_OPTIONS_VARDEPS := $$(call EscapeHash, \
+ $$($DOCROOTPARENT_FLAG) $$(JAVADOC_BASE_URL) $$($1_NO_COMMON_TAGS) \
+ $$($1_DOCLINT) $$($1_DOCLINT_PACKAGES) $$(JAVADOC_SOURCE_DIRS) \
+ $$($1_MODULES) $$($1_ENCODING) $$($1_NODEPRECATEDLIST) \
+ $$($1_BREAKITERATOR) $$($1_SPLIT_INDEX) $$($1_OVERVIEW) \
+ $$($1_DOC_TITLE) $$($1_WINDOW_TITLE) $$(DRAFT_WINTITLE) \
+ $$($1_HEADER) $$(DRAFT_HEADER) $$($1_NOINDEX) $$($1_EXTRA_TOP_2) \
+ $$($1_BOTTOM) $$(DRAFT_BOTTOM)) $$($1_PACKAGE_FILTER) $$($1_RELATIVE_CORE_DIR) \
+ $$(JAVADOC_OUTPUTDIR) \
+ )
+ $1_OPTIONS_VARDEPS_FILE := $$(call DependOnVariable, $1_OPTIONS_VARDEPS, \
+ $$($1_OPTIONS_FILE).vardeps)
-# Create file with javadoc options in it
-$(COREAPI_OPTIONS_FILE): $(COREAPI_OVERVIEW)
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:reference) ; \
- $(call OptionOnly,-Xdoclint/package:-org.omg.*$(COMMA)jdk.internal.logging.*) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(COREAPI_MODULES)) ; \
- $(call OptionPair,-encoding,ISO-8859-1) ; \
- $(call OptionOnly,-splitIndex) ; \
- $(call OptionPair,-overview,$(COREAPI_OVERVIEW)) ; \
- $(call OptionPair,-doctitle,$(COREAPI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(COREAPI_WINDOWTITLE) $(DRAFT_WINTITLE)) ; \
- $(call OptionPair,-header,$(COREAPI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(COREAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- ) >> $@
- ifdef COREAPI_TOP_EARLYACCESS
- @$(call OptionPair,-top,$(COREAPI_TOP_EARLYACCESS)) >> $@
+ # Rule for creating a file with javadoc options in it
+ $$($1_OPTIONS_FILE): $$($1_OPTIONS_VARDEPS_FILE)
+ $$(call LogInfo, Creating Javadoc options file for $1)
+ $$(call MakeDir, $$(@D))
+ $$(RM) $$@
+ $$(call AddOption, -XDignore.symbol.file=true)
+ ifneq ($$(LOG_LEVEL), trace)
+ $$(call AddOption, -quiet)
+ endif
+ $$(call AddOption, -use)
+ $$(call AddOption, -keywords)
+ ifneq ($$($DOCROOTPARENT_FLAG), )
+ # NOTE: Argument to -Xdocrootparent is not quoted to keep backwards compatibility.
+ $$(call AddOption, -Xdocrootparent $(JAVADOC_BASE_URL))
+ endif
+ ifneq ($$($1_NO_COMMON_TAGS), TRUE)
+ # In order to get a specific ordering it's necessary to specify the total
+ # ordering of tags as the tags are otherwise ordered in order of definition.
+ $$(call AddOption, -tag, beaninfo:X)
+ $$(call AddOption, -tag, revised:X)
+ $$(call AddOption, -tag, since.unbundled:X)
+ $$(call AddOption, -tag, spec:X)
+ $$(call AddOption, -tag, specdefault:X)
+ $$(call AddOption, -tag, Note:X)
+ $$(call AddOption, -tag, ToDo:X)
+ $$(call AddOption, -tag, apiNote:a:API Note:)
+ $$(call AddOption, -tag, implSpec:a:Implementation Requirements:)
+ $$(call AddOption, -tag, implNote:a:Implementation Note:)
+ $$(call AddOption, -tag, param)
+ $$(call AddOption, -tag, return)
+ $$(call AddOption, -tag, throws)
+ $$(call AddOption, -tag, since)
+ $$(call AddOption, -tag, version)
+ $$(call AddOption, -tag, serialData)
+ $$(call AddOption, -tag, factory)
+ $$(call AddOption, -tag, see)
+ $$(call AddOption, -tag, \
+ jvms:a:See <cite> The Java™ Virtual Machine Specification</cite>:)
+ $$(call AddOption, -tag, \
+ jls:a:See <cite> The Java™ Language Specification</cite>:)
+ endif
+ $$(call AddOption, -Xdoclint:$$($1_DOCLINT))
+ ifneq ($$($1_DOCLINT_PACKAGES), )
+ $$(call AddOption, -Xdoclint/package:$$(call CommaList, $$($1_DOCLINT_PACKAGES)))
+ endif
+ $$(call AddOption, --system, none)
+ $$(call AddOption, --module-source-path, $$(subst ",, $$(call PathList, $$(JAVADOC_SOURCE_DIRS))))
+ $$(call AddOption, --add-modules, $$(call CommaList, $$($1_MODULES)))
+ $$(call AddOption, -encoding, $$($1_ENCODING))
+ ifneq ($$($1_NODEPRECATEDLIST), )
+ $$(call AddOption, -nodeprecatedlist)
+ endif
+ ifneq ($$($1_BREAKITERATOR), )
+ $$(call AddOption, -breakiterator)
+ endif
+ ifneq ($$($1_SPLIT_INDEX), )
+ $$(call AddOption, -splitIndex)
+ endif
+ ifneq ($$($1_OVERVIEW), )
+ $$(call AddOption, -overview, $$($1_OVERVIEW))
+ endif
+ $$(call AddOption, -doctitle, $$($1_DOC_TITLE))
+ $$(call AddOption, -windowtitle, $$($1_WINDOW_TITLE) $$(DRAFT_WINTITLE))
+ $$(call AddOption, -header, $$($1_HEADER)$$(DRAFT_HEADER))
+ ifneq ($$($1_NOINDEX), )
+ $$(call AddOption, -nonavbar)
+ $$(call AddOption, -noindex)
+ endif
+ ifneq ($$($1_EXTRA_TOP_2), )
+ $$(call AddOption, -top,$$($1_EXTRA_TOP_2))
+ endif
+ $$(call AddOption, -bottom, $$($1_BOTTOM)$$(DRAFT_BOTTOM))
+ ifneq ($$($1_PACKAGE_FILTER), )
+ $$(call AddOption, -group, Packages, $$($1_PACKAGE_FILTER))
+ endif
+ ifneq ($$($1_RELATIVE_CORE_DIR), )
+ $$(call AddOption, -linkoffline, $$($1_RELATIVE_CORE_DIR)/api, $$(JAVADOC_OUTPUTDIR)/api/)
+ endif
+ ifneq ($$($1_EXTRA_TOP), )
+ $$(call AddOption, -top, $$($1_EXTRA_TOP))
endif
-# Create a file with the package names in it
-$(COREAPI_PACKAGES_FILE): $(call PackageDependencies,$(CORE_PKGS))
- $(prep-target)
- $(call PackageFilter,$(CORE_PKGS))
-
-#############################################################
-#
-# docletapidocs
-#
-
-ALL_OTHER_TARGETS += docletapidocs
-
-DOCLETAPI_DOCDIR := $(JDK_API_DOCSDIR)/javadoc/doclet
-DOCLETAPI2COREAPI := ../../$(JDKJRE2COREAPI)
-DOCLETAPI_DOCTITLE := Doclet API
-DOCLETAPI_WINDOWTITLE := Doclet API
-DOCLETAPI_HEADER := <strong>Doclet API</strong>
-DOCLETAPI_BOTTOM := $(call CommonTrademarkBottom,$(DOCLETAPI_FIRST_COPYRIGHT_YEAR))
-DOCLETAPI_GROUPNAME := Packages
-DOCLETAPI_REGEXP := jdk.javadoc.doclet*
-# DOCLETAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-# The index.html, options, and packages files
-DOCLETAPI_INDEX_FILE = $(DOCLETAPI_DOCDIR)/index.html
-DOCLETAPI_OPTIONS_FILE = $(DOCSTMPDIR)/docletapi.options
-DOCLETAPI_PACKAGES_FILE = $(DOCSTMPDIR)/docletapi.packages
-
-# The modules required to be documented
-DOCLETAPI_MODULES = jdk.javadoc
-
-docletapidocs: $(DOCLETAPI_INDEX_FILE)
-
-# Set relative location to core api document root
-$(DOCLETAPI_INDEX_FILE): GET2DOCSDIR=$(DOCLETAPI2COREAPI)/..
+ $1_PACKAGE_DEPS := $$(call CacheFind, $$(wildcard $$(foreach p, \
+ $$(subst .,/,$$(strip $$($1_PACKAGES))), \
+ $$(addsuffix /$$p, $$(wildcard $$(JAVADOC_SOURCE_DIRS))))))
-# Run javadoc if the index file is out of date or missing
-$(DOCLETAPI_INDEX_FILE): $(DOCLETAPI_OPTIONS_FILE) $(DOCLETAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(DOCLETAPI_OPTIONS_FILE),$(DOCLETAPI_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(DOCLETAPI_OPTIONS_FILE) @$(DOCLETAPI_PACKAGES_FILE)
+ # Rule for actually running javadoc
+ $$($1_INDEX_FILE): $$($1_OPTIONS_FILE) $$($1_PACKAGES_FILE) \
+ $$($1_PACKAGE_DEPS) $$($1_DEPS)
+ $$(call LogWarn, Generating Javadoc for $$($1_OUTPUT_DIRNAME))
+ $$(call MakeDir, $$(@D))
+ ifneq ($$(findstring $$(LOG_LEVEL), debug trace),)
+ $$(ECHO) "Contents of $$($1_OPTIONS_FILE):" `$$(CAT) $$($1_OPTIONS_FILE)`
+ $$(ECHO) "Contents of $$($1_PACKAGES_FILE):" `$$(CAT) $$($1_PACKAGES_FILE)`
+ endif
+ $$(call ExecuteWithLog, $$(SUPPORT_OUTPUTDIR)/docs/$1.javadoc, \
+ $$($1_JAVA) -Djava.awt.headless=true $(NEW_JAVADOC) -d $$(@D) \
+ @$$($1_OPTIONS_FILE) @$$($1_PACKAGES_FILE))
+ $$(TOUCH) $$($1_INDEX_FILE)
-# Create file with javadoc options in it
-$(DOCLETAPI_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:all) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(DOCLETAPI_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-breakiterator) ; \
- $(call OptionPair,-doctitle,$(DOCLETAPI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(DOCLETAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(DOCLETAPI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(DOCLETAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-group,$(DOCLETAPI_GROUPNAME),$(DOCLETAPI_REGEXP)); \
- $(call OptionTrip,-linkoffline,$(DOCLETAPI2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
+ # The output returned will be the index.html file
+ $1 := $$($1_INDEX_FILE)
+endef
-# Create a file with the package names in it
-$(DOCLETAPI_PACKAGES_FILE): $(call PackageDependencies,$(DOCLETAPI_PKGS))
- $(prep-target)
- $(call PackageFilter,$(DOCLETAPI_PKGS))
-
-#############################################################
-#
-# old docletapidocs
-#
-
-ALL_OTHER_TARGETS += olddocletapidocs
+################################################################################
-OLD_DOCLET_DIR := $(JDK_API_DOCSDIR)/javadoc/old
-OLD_DOCLETAPI_DOCDIR := $(OLD_DOCLET_DIR)/doclet
-OLD_DOCLETAPI2COREAPI := ../../../$(JDKJRE2COREAPI)
-OLD_DOCLETAPI_DOCTITLE := Doclet API
-OLD_DOCLETAPI_WINDOWTITLE := Doclet API
-OLD_DOCLETAPI_HEADER := <strong>Doclet API</strong>
-OLD_DOCLETAPI_BOTTOM := $(call CommonTrademarkBottom,$(DOCLETAPI_FIRST_COPYRIGHT_YEAR))
-OLD_DOCLETAPI_GROUPNAME := Packages
-OLD_DOCLETAPI_REGEXP := com.sun.javadoc
-# OLD_DOCLETAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-# The index.html, options, and packages files
-OLD_DOCLETAPI_INDEX_FILE = $(OLD_DOCLETAPI_DOCDIR)/index.html
-OLD_DOCLETAPI_OPTIONS_FILE = $(DOCSTMPDIR)/old-docletapi.options
-OLD_DOCLETAPI_PACKAGES_FILE = $(DOCSTMPDIR)/old-docletapi.packages
-
-# The modules required to be documented
-OLD_DOCLETAPI_MODULES = jdk.javadoc
-
-olddocletapidocs: $(OLD_DOCLETAPI_INDEX_FILE)
-
-# Set relative location to core api document root
-$(OLD_DOCLETAPI_INDEX_FILE): GET2DOCSDIR=$(OLD_DOCLETAPI2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(OLD_DOCLETAPI_INDEX_FILE): $(OLD_DOCLETAPI_OPTIONS_FILE) $(OLD_DOCLETAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(OLD_DOCLETAPI_OPTIONS_FILE),$(OLD_DOCLETAPI_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(OLD_DOCLETAPI_OPTIONS_FILE) @$(OLD_DOCLETAPI_PACKAGES_FILE)
+CORE_PACKAGES := \
+ java.applet \
+ java.awt \
+ java.awt.color \
+ java.awt.datatransfer \
+ java.awt.desktop \
+ java.awt.dnd \
+ java.awt.event \
+ java.awt.font \
+ java.awt.geom \
+ java.awt.im \
+ java.awt.im.spi \
+ java.awt.image \
+ java.awt.image.renderable \
+ java.awt.print \
+ java.beans \
+ java.beans.beancontext \
+ java.io \
+ java.lang \
+ java.lang.annotation \
+ java.lang.instrument \
+ java.lang.invoke \
+ java.lang.management \
+ java.lang.module \
+ java.lang.ref \
+ java.lang.reflect \
+ java.math \
+ java.net \
+ java.net.http \
+ java.net.spi \
+ java.nio \
+ java.nio.channels \
+ java.nio.channels.spi \
+ java.nio.charset \
+ java.nio.charset.spi \
+ java.nio.file \
+ java.nio.file.attribute \
+ java.nio.file.spi \
+ java.rmi \
+ java.rmi.activation \
+ java.rmi.dgc \
+ java.rmi.registry \
+ java.rmi.server \
+ java.security \
+ java.security.acl \
+ java.security.cert \
+ java.security.interfaces \
+ java.security.spec \
+ java.sql \
+ java.text \
+ java.text.spi \
+ java.time \
+ java.time.chrono \
+ java.time.format \
+ java.time.temporal \
+ java.time.zone \
+ java.util \
+ java.util.concurrent \
+ java.util.concurrent.atomic \
+ java.util.concurrent.locks \
+ java.util.function \
+ java.util.jar \
+ java.util.logging \
+ java.util.prefs \
+ java.util.regex \
+ java.util.spi \
+ java.util.stream \
+ java.util.zip \
+ javax.accessibility \
+ javax.activation \
+ javax.activity \
+ javax.annotation \
+ javax.annotation.processing \
+ javax.crypto \
+ javax.crypto.interfaces \
+ javax.crypto.spec \
+ javax.imageio \
+ javax.imageio.event \
+ javax.imageio.metadata \
+ javax.imageio.plugins.jpeg \
+ javax.imageio.plugins.bmp \
+ javax.imageio.plugins.tiff \
+ javax.imageio.spi \
+ javax.imageio.stream \
+ javax.jws \
+ javax.jws.soap \
+ javax.lang.model \
+ javax.lang.model.element \
+ javax.lang.model.type \
+ javax.lang.model.util \
+ javax.management \
+ javax.management.loading \
+ javax.management.monitor \
+ javax.management.relation \
+ javax.management.openmbean \
+ javax.management.timer \
+ javax.management.modelmbean \
+ javax.management.remote \
+ javax.management.remote.rmi \
+ javax.naming \
+ javax.naming.directory \
+ javax.naming.event \
+ javax.naming.ldap \
+ javax.naming.spi \
+ javax.net \
+ javax.net.ssl \
+ javax.print \
+ javax.print.attribute \
+ javax.print.attribute.standard \
+ javax.print.event \
+ javax.rmi \
+ javax.rmi.CORBA \
+ javax.rmi.ssl \
+ javax.script \
+ javax.security.auth \
+ javax.security.auth.callback \
+ javax.security.auth.kerberos \
+ javax.security.auth.login \
+ javax.security.auth.spi \
+ javax.security.auth.x500 \
+ javax.security.cert \
+ javax.security.sasl \
+ javax.sound.sampled \
+ javax.sound.sampled.spi \
+ javax.sound.midi \
+ javax.sound.midi.spi \
+ javax.sql \
+ javax.sql.rowset \
+ javax.sql.rowset.serial \
+ javax.sql.rowset.spi \
+ javax.swing \
+ javax.swing.border \
+ javax.swing.colorchooser \
+ javax.swing.filechooser \
+ javax.swing.event \
+ javax.swing.table \
+ javax.swing.text \
+ javax.swing.text.html \
+ javax.swing.text.html.parser \
+ javax.swing.text.rtf \
+ javax.swing.tree \
+ javax.swing.undo \
+ javax.swing.plaf \
+ javax.swing.plaf.basic \
+ javax.swing.plaf.metal \
+ javax.swing.plaf.multi \
+ javax.swing.plaf.nimbus \
+ javax.swing.plaf.synth \
+ javax.tools \
+ javax.transaction \
+ javax.transaction.xa \
+ javax.xml.catalog \
+ javax.xml.parsers \
+ javax.xml.bind \
+ javax.xml.bind.annotation \
+ javax.xml.bind.annotation.adapters \
+ javax.xml.bind.attachment \
+ javax.xml.bind.helpers \
+ javax.xml.bind.util \
+ javax.xml.soap \
+ javax.xml.ws \
+ javax.xml.ws.handler \
+ javax.xml.ws.handler.soap \
+ javax.xml.ws.http \
+ javax.xml.ws.soap \
+ javax.xml.ws.spi \
+ javax.xml.ws.spi.http \
+ javax.xml.ws.wsaddressing \
+ javax.xml.transform \
+ javax.xml.transform.sax \
+ javax.xml.transform.dom \
+ javax.xml.transform.stax \
+ javax.xml.transform.stream \
+ javax.xml \
+ javax.xml.crypto \
+ javax.xml.crypto.dom \
+ javax.xml.crypto.dsig \
+ javax.xml.crypto.dsig.dom \
+ javax.xml.crypto.dsig.keyinfo \
+ javax.xml.crypto.dsig.spec \
+ javax.xml.datatype \
+ javax.xml.validation \
+ javax.xml.namespace \
+ javax.xml.xpath \
+ javax.xml.stream \
+ javax.xml.stream.events \
+ javax.xml.stream.util \
+ org.ietf.jgss \
+ org.omg.CORBA \
+ org.omg.CORBA.DynAnyPackage \
+ org.omg.CORBA.ORBPackage \
+ org.omg.CORBA.TypeCodePackage \
+ org.omg.stub.java.rmi \
+ org.omg.CORBA.portable \
+ org.omg.CORBA_2_3 \
+ org.omg.CORBA_2_3.portable \
+ org.omg.CosNaming \
+ org.omg.CosNaming.NamingContextExtPackage \
+ org.omg.CosNaming.NamingContextPackage \
+ org.omg.SendingContext \
+ org.omg.PortableServer \
+ org.omg.PortableServer.CurrentPackage \
+ org.omg.PortableServer.POAPackage \
+ org.omg.PortableServer.POAManagerPackage \
+ org.omg.PortableServer.ServantLocatorPackage \
+ org.omg.PortableServer.portable \
+ org.omg.PortableInterceptor \
+ org.omg.PortableInterceptor.ORBInitInfoPackage \
+ org.omg.Messaging \
+ org.omg.IOP \
+ org.omg.IOP.CodecFactoryPackage \
+ org.omg.IOP.CodecPackage \
+ org.omg.Dynamic \
+ org.omg.DynamicAny \
+ org.omg.DynamicAny.DynAnyPackage \
+ org.omg.DynamicAny.DynAnyFactoryPackage \
+ org.w3c.dom \
+ org.w3c.dom.events \
+ org.w3c.dom.bootstrap \
+ org.w3c.dom.ls \
+ org.w3c.dom.ranges \
+ org.w3c.dom.traversal \
+ org.w3c.dom.views \
+ org.xml.sax \
+ org.xml.sax.ext \
+ org.xml.sax.helpers
-# Create file with javadoc options in it
-$(OLD_DOCLETAPI_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:all) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(OLD_DOCLETAPI_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-breakiterator) ; \
- $(call OptionPair,-doctitle,$(OLD_DOCLETAPI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(OLD_DOCLETAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(OLD_DOCLETAPI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(OLD_DOCLETAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-group,$(OLD_DOCLETAPI_GROUPNAME),$(OLD_DOCLETAPI_REGEXP)); \
- $(call OptionTrip,-linkoffline,$(OLD_DOCLETAPI2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
+$(eval $(call SetupJavadocGeneration, coredocs, \
+ MODULES := java.se.ee, \
+ PACKAGES := $(CORE_PACKAGES), \
+ IS_CORE := TRUE, \
+ OVERVIEW := $(JDK_TOPDIR)/src/java.base/share/classes/overview-core.html, \
+ WINDOW_TITLE := Java Platform SE $(VERSION_SPECIFICATION), \
+ HEADER_TITLE := Java$(TRADEMARK) Platform<br>Standard Ed. $(VERSION_SPECIFICATION), \
+ DOC_TITLE := Java$(TRADEMARK) Platform$(COMMA) Standard Edition \
+ $(VERSION_SPECIFICATION)<br>API Specification, \
+ FIRST_COPYRIGHT_YEAR := 1993, \
+ DOCLINT := reference, \
+ DOCLINT_PACKAGES := -org.omg.* jdk.internal.logging.*, \
+ ENCODING := ISO-8859-1, \
+ SPLIT_INDEX := TRUE, \
+ BOTTOM_COPYRIGHT_URL := $(CORE_BOTTOM_COPYRIGHT_URL), \
+ BOTTOM_TEXT := $(CORE_BOTTOM_TEXT), \
+ EXTRA_TOP := $(CORE_TOP_EARLYACCESS), \
+))
-# Create a file with the package names in it
-$(OLD_DOCLETAPI_PACKAGES_FILE): $(call PackageDependencies,$(OLD_DOCLETAPI_PKGS))
- $(prep-target)
- $(call PackageFilter,$(OLD_DOCLETAPI_PKGS))
+TARGETS += $(coredocs)
+
+################################################################################
+
+$(eval $(call SetupJavadocGeneration, docletapi, \
+ MODULES := jdk.javadoc, \
+ PACKAGES := \
+ jdk.javadoc.doclet \
+ jdk.javadoc.doclet.taglet \
+ jdk.javadoc.doclets, \
+ PACKAGE_FILTER := jdk.javadoc.doclet*, \
+ API_ROOT := jdk, \
+ DEST_DIR := javadoc/doclet, \
+ TITLE := Doclet API, \
+ FIRST_COPYRIGHT_YEAR := 1993, \
+ BREAKITERATOR := TRUE, \
+ BOTTOM_ADDRESS := $(COMMON_BOTTOM_ADDRESS), \
+ BOTTOM_TEXT := $(COMMON_BOTTOM_TEXT), \
+))
-#############################################################
-#
-# tagletapidocs
-#
+TARGETS += $(docletapi)
+
+################################################################################
-ALL_OTHER_TARGETS += tagletapidocs
-TAGLETAPI_DOCDIR := $(OLD_DOCLET_DIR)/taglet
-TAGLETAPI2COREAPI := ../../../$(JDKJRE2COREAPI)
-TAGLETAPI_DOCTITLE := Taglet API
-TAGLETAPI_WINDOWTITLE := Taglet API
-TAGLETAPI_HEADER := <strong>Taglet API</strong>
-TAGLETAPI_BOTTOM := $(call CommonTrademarkBottom,$(TAGLETAPI_FIRST_COPYRIGHT_YEAR))
-# TAGLETAPI_FILE is located in NON_CORE_PKGS.gmk
+$(eval $(call SetupJavadocGeneration, old-docletapi, \
+ MODULES := jdk.javadoc, \
+ PACKAGES := com.sun.javadoc, \
+ PACKAGE_FILTER := com.sun.javadoc, \
+ API_ROOT := jdk, \
+ DEST_DIR := javadoc/old/doclet, \
+ TITLE := Doclet API, \
+ FIRST_COPYRIGHT_YEAR := 1993, \
+ BREAKITERATOR := TRUE, \
+ BOTTOM_ADDRESS := $(COMMON_BOTTOM_ADDRESS), \
+ BOTTOM_TEXT := $(COMMON_BOTTOM_TEXT), \
+))
+
+TARGETS += $(old-docletapi)
-# The index.html, options, and packages files
-TAGLETAPI_INDEX_FILE = $(TAGLETAPI_DOCDIR)/index.html
-TAGLETAPI_OPTIONS_FILE = $(DOCSTMPDIR)/tagletapi.options
-TAGLETAPI_PACKAGES_FILE = $(DOCSTMPDIR)/tagletapi.packages
+################################################################################
-# The modules required to be documented
-TAGLETAPI_MODULES = jdk.javadoc
+# Specify a single class instead of a package
+TAGLET_PACKAGE_SINGLE_CLASS := com/sun/tools/doclets/Taglet.java
+TAGLET_PACKAGE_DIR := $(LANGTOOLS_TOPDIR)/src/jdk.javadoc/share/classes
-tagletapidocs: $(TAGLETAPI_INDEX_FILE)
-
-# Run javadoc if the index file is out of date or missing
-$(TAGLETAPI_INDEX_FILE): $(TAGLETAPI_OPTIONS_FILE) $(TAGLETAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(TAGLETAPI_OPTIONS_FILE),$(TAGLETAPI_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(TAGLETAPI_OPTIONS_FILE) @$(TAGLETAPI_PACKAGES_FILE)
+$(eval $(call SetupJavadocGeneration, tagletapi, \
+ MODULES := jdk.javadoc, \
+ PACKAGES := com.sun.tools.doclets, \
+ PACKAGES_SINGLE_CLASS := $(TAGLET_PACKAGE_DIR)/$(TAGLET_PACKAGE_SINGLE_CLASS), \
+ API_ROOT := jdk, \
+ DEST_DIR := javadoc/old/taglet, \
+ TITLE := Taglet API, \
+ FIRST_COPYRIGHT_YEAR := 1993, \
+ BREAKITERATOR := TRUE, \
+ NOINDEX := TRUE, \
+ BOTTOM_ADDRESS := $(COMMON_BOTTOM_ADDRESS), \
+ BOTTOM_TEXT := $(COMMON_BOTTOM_TEXT), \
+))
-# Create file with javadoc options in it
-$(TAGLETAPI_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:all) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(TAGLETAPI_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-breakiterator) ; \
- $(call OptionPair,-doctitle,$(TAGLETAPI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(TAGLETAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(TAGLETAPI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionOnly,-nonavbar) ; \
- $(call OptionOnly,-noindex) ; \
- $(call OptionPair,-bottom,$(TAGLETAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-linkoffline,$(TAGLETAPI2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
+TARGETS += $(tagletapi)
+
+################################################################################
+
+$(eval $(call SetupJavadocGeneration, domapi, \
+ MODULES := \
+ java.xml \
+ jdk.xml.dom, \
+ PACKAGES := \
+ org.w3c.dom \
+ org.w3c.dom.bootstrap \
+ org.w3c.dom.ls \
+ org.w3c.dom.ranges \
+ org.w3c.dom.traversal \
+ org.w3c.dom.html \
+ org.w3c.dom.stylesheets \
+ org.w3c.dom.css \
+ org.w3c.dom.events \
+ org.w3c.dom.views, \
+ PACKAGE_FILTER := org.w3c.dom*, \
+ API_ROOT := jre, \
+ DEST_DIR := plugin/dom, \
+ TITLE := Common DOM API, \
+ FIRST_COPYRIGHT_YEAR := 2005, \
+ DOCLINT := none, \
+ SPLIT_INDEX := TRUE, \
+ BOTTOM_ADDRESS := $(COMMON_BOTTOM_ADDRESS), \
+ BOTTOM_TEXT := $(COMMON_BOTTOM_TEXT), \
+))
+
+TARGETS += $(domapi)
+
+################################################################################
-# Create a file with the package names in it
-$(TAGLETAPI_PACKAGES_FILE): $(call PackageDependencies,$(TAGLETAPI_PKGS))
- $(prep-target)
- @($(ECHO) "$(LANGTOOLS_TOPDIR)/src/jdk.javadoc/share/classes/$(TAGLETAPI_FILE)" ) > $@
+$(eval $(call SetupJavadocGeneration, jdi, \
+ MODULES := jdk.jdi, \
+ PACKAGES := \
+ com.sun.jdi \
+ com.sun.jdi.event \
+ com.sun.jdi.request \
+ com.sun.jdi.connect \
+ com.sun.jdi.connect.spi, \
+ API_ROOT := jdk, \
+ DEST_DIR := jpda/jdi, \
+ OVERVIEW := $(JDK_TOPDIR)/src/jdk.jdi/share/classes/jdi-overview.html, \
+ TITLE := Java$(TRADEMARK) Debug Interface, \
+ FIRST_COPYRIGHT_YEAR := 1999, \
+ DOCLINT := none, \
+))
-#############################################################
-#
-# domapidocs
-#
+TARGETS += $(jdi)
-ALL_OTHER_TARGETS += domapidocs
+################################################################################
-DOMAPI_DOCDIR := $(JRE_API_DOCSDIR)/plugin/dom
-DOMAPI2COREAPI := ../../$(JDKJRE2COREAPI)
-DOMAPI_DOCTITLE := Common DOM API
-DOMAPI_WINDOWTITLE := Common DOM API
-DOMAPI_HEADER := <strong>Common DOM API</strong>
-DOMAPI_BOTTOM := $(call CommonTrademarkBottom,$(DOMAPI_FIRST_COPYRIGHT_YEAR))
-DOMAPI_GROUPNAME := Packages
-DOMAPI_REGEXP := org.w3c.dom*
-# DOMAPI_PKGS is located in NON_CORE_PKGS.gmk
+$(eval $(call SetupJavadocGeneration, jaas, \
+ MODULES := jdk.security.auth, \
+ PACKAGES := \
+ com.sun.security.auth \
+ com.sun.security.auth.callback \
+ com.sun.security.auth.login \
+ com.sun.security.auth.module, \
+ API_ROOT := jre, \
+ DEST_DIR := security/jaas/spec, \
+ OVERVIEW := $(JDK_TOPDIR)/src/jdk.security.auth/share/classes/jaas-overview.html, \
+ TITLE := Java$(TRADEMARK) Authentication and Authorization Service, \
+ FIRST_COPYRIGHT_YEAR := 1998, \
+ DOCLINT := none, \
+))
+
+TARGETS += $(jaas)
+
+################################################################################
-# The index.html, options, and packages files
-DOMAPI_INDEX_FILE = $(DOMAPI_DOCDIR)/index.html
-DOMAPI_OPTIONS_FILE = $(DOCSTMPDIR)/domapi.options
-DOMAPI_PACKAGES_FILE = $(DOCSTMPDIR)/domapi.packages
+$(eval $(call SetupJavadocGeneration, jgss, \
+ MODULES := jdk.security.jgss, \
+ PACKAGES := com.sun.security.jgss, \
+ API_ROOT := jre, \
+ DEST_DIR := security/jgss/spec, \
+ OVERVIEW := $(JDK_TOPDIR)/src/java.security.jgss/share/classes/jgss-overview.html, \
+ TITLE := Java$(TRADEMARK) GSS-API Utilities, \
+ FIRST_COPYRIGHT_YEAR := 2000, \
+ DOCLINT := none, \
+ NODEPRECATEDLIST := TRUE, \
+))
-# The modules required to be documented
-DOMAPI_MODULES = java.xml,jdk.xml.dom
+TARGETS += $(jgss)
-domapidocs: $(DOMAPI_INDEX_FILE)
+################################################################################
-# Set relative location to core api document root
-$(DOMAPI_INDEX_FILE): GET2DOCSDIR=$(DOMAPI2COREAPI)/..
+$(eval $(call SetupJavadocGeneration, smartcardio, \
+ MODULES := java.smartcardio, \
+ PACKAGES := javax.smartcardio, \
+ API_ROOT := jre, \
+ DEST_DIR := security/smartcardio/spec, \
+ TITLE := Java$(TRADEMARK) Smart Card I/O, \
+ FIRST_COPYRIGHT_YEAR := 2005, \
+ DOCLINT := none, \
+ NODEPRECATEDLIST := TRUE, \
+))
+
+TARGETS += $(smartcardio)
+
+################################################################################
-# Run javadoc if the index file is out of date or missing
-$(DOMAPI_INDEX_FILE): $(DOMAPI_OPTIONS_FILE) $(DOMAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(DOMAPI_OPTIONS_FILE),$(DOMAPI_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(DOMAPI_OPTIONS_FILE) @$(DOMAPI_PACKAGES_FILE)
+$(eval $(call SetupJavadocGeneration, httpserver, \
+ MODULES := jdk.httpserver, \
+ PACKAGES := \
+ com.sun.net.httpserver \
+ com.sun.net.httpserver.spi, \
+ API_ROOT := jre, \
+ DEST_DIR := net/httpserver/spec, \
+ TITLE := Java$(TRADEMARK) HTTP Server, \
+ FIRST_COPYRIGHT_YEAR := 2005, \
+ DOCLINT := none, \
+ NODEPRECATEDLIST := TRUE, \
+))
+
+TARGETS += $(httpserver)
-# Create file with javadoc options in it
-$(DOMAPI_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(DOMAPI_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-splitIndex) ; \
- $(call OptionPair,-doctitle,$(DOMAPI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(DOMAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(DOMAPI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(DOMAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-group,$(DOMAPI_GROUPNAME),$(DOMAPI_REGEXP)); \
- $(call OptionTrip,-linkoffline,$(DOMAPI2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
+################################################################################
+
+$(eval $(call SetupJavadocGeneration, jsobject, \
+ MODULES := jdk.jsobject, \
+ PACKAGES := netscape.javascript, \
+ API_ROOT := jre, \
+ DEST_DIR := plugin/jsobject, \
+ FIRST_COPYRIGHT_YEAR := 1993, \
+ TITLE := Java$(TRADEMARK) JSObject Doc, \
+ DOCLINT := none, \
+ NODEPRECATEDLIST := TRUE, \
+))
+
+TARGETS += $(jsobject)
+
+################################################################################
-# Create a file with the package names in it
-$(DOMAPI_PACKAGES_FILE): $(call PackageDependencies,$(DOMAPI_PKGS))
- $(prep-target)
- $(call PackageFilter,$(DOMAPI_PKGS))
+$(eval $(call SetupJavadocGeneration, mgmt, \
+ MODULES := jdk.management, \
+ PACKAGES := com.sun.management, \
+ API_ROOT := jre, \
+ DEST_DIR := management/extension, \
+ OVERVIEW := $(JDK_TOPDIR)/src/java.management/share/classes/mgmt-overview.html, \
+ TITLE := Monitoring and Management Interface for the Java$(TRADEMARK) Platform, \
+ FIRST_COPYRIGHT_YEAR := 2003, \
+ DOCLINT := none, \
+ NODEPRECATEDLIST := TRUE, \
+))
+
+TARGETS += $(mgmt)
+
+################################################################################
+
+$(eval $(call SetupJavadocGeneration, attach, \
+ MODULES := jdk.attach, \
+ PACKAGES := \
+ com.sun.tools.attach \
+ com.sun.tools.attach.spi, \
+ API_ROOT := jdk, \
+ DEST_DIR := attach/spec, \
+ TITLE := Attach API, \
+ FIRST_COPYRIGHT_YEAR := 2005, \
+ DOCLINT := none, \
+ NODEPRECATEDLIST := TRUE, \
+))
-#############################################################
-#
-# jpdadocs
-#
+TARGETS += $(attach)
+
+################################################################################
-ALL_OTHER_TARGETS += jpdadocs
+$(eval $(call SetupJavadocGeneration, jconsole, \
+ MODULES := jdk.jconsole, \
+ PACKAGES := com.sun.tools.jconsole, \
+ API_ROOT := jdk, \
+ DEST_DIR := jconsole/spec, \
+ TITLE := JConsole API, \
+ FIRST_COPYRIGHT_YEAR := 2006, \
+ DOCLINT := none, \
+ NODEPRECATEDLIST := TRUE, \
+))
+
+TARGETS += $(jconsole)
-jpdadocs: jdidocs jdwpdocs jvmtidocs
+################################################################################
-#############################################################
-#
-# jdidocs
-#
-
-ALL_OTHER_TARGETS += jdidocs
+# NOTE: Need to override RELATIVE_CORE_DIR to be bug compatible with old code.
+$(eval $(call SetupJavadocGeneration, jshellapi, \
+ MODULES := jdk.jshell, \
+ PACKAGES := \
+ jdk.jshell \
+ jdk.jshell.spi \
+ jdk.jshell.execution, \
+ API_ROOT := jdk, \
+ DEST_DIR := jshell, \
+ RELATIVE_CORE_DIR := ../../../.., \
+ OVERVIEW := $(LANGTOOLS_TOPDIR)/src/jdk.jshell/share/classes/jdk/jshell/overview.html, \
+ TITLE := JShell API, \
+ HEADER_TITLE := JSHELL API, \
+ FIRST_COPYRIGHT_YEAR := 2015, \
+))
-JDI_DOCDIR := $(JDK_API_DOCSDIR)/jpda/jdi
-JDI2COREAPI := ../../$(JDKJRE2COREAPI)
-JDI_DOCTITLE := Java$(TRADEMARK) Debug Interface
-JDI_WINDOWTITLE := Java Debug Interface
-JDI_HEADER := <strong>Java Debug Interface</strong>
-JDI_BOTTOM := $(call CommonBottom,$(JDI_FIRST_COPYRIGHT_YEAR))
-JDI_OVERVIEW := $(JDK_TOPDIR)/src/jdk.jdi/share/classes/jdi-overview.html
-# JDI_PKGS is located in NON_CORE_PKGS.gmk
+TARGETS += $(jshellapi)
+
+################################################################################
-# The index.html, options, and packages files
-JDI_INDEX_FILE = $(JDI_DOCDIR)/index.html
-JDI_OPTIONS_FILE = $(DOCSTMPDIR)/jdi.options
-JDI_PACKAGES_FILE = $(DOCSTMPDIR)/jdi.packages
+$(eval $(call SetupJavadocGeneration, treeapi, \
+ MODULES := jdk.compiler, \
+ PACKAGES := \
+ com.sun.source.doctree \
+ com.sun.source.tree \
+ com.sun.source.util, \
+ PACKAGE_FILTER := com.sun.source.*, \
+ API_ROOT := jdk, \
+ DEST_DIR := javac/tree, \
+ TITLE := Compiler Tree API, \
+ FIRST_COPYRIGHT_YEAR := 2005, \
+))
-# The modules required to be documented
-JDI_MODULES = jdk.jdi
+TARGETS += $(treeapi)
-jdidocs: $(JDI_INDEX_FILE)
+################################################################################
-# Set relative location to core api document root
-$(JDI_INDEX_FILE): GET2DOCSDIR=$(JDI2COREAPI)/..
+$(eval $(call SetupJavadocGeneration, nashornapi, \
+ MODULES := jdk.scripting.nashorn, \
+ PACKAGES := \
+ jdk.nashorn.api.scripting \
+ jdk.nashorn.api.tree, \
+ PACKAGE_FILTER := jdk.nashorn.api.*, \
+ API_ROOT := jdk, \
+ DEST_DIR := nashorn, \
+ TITLE := Nashorn API, \
+ FIRST_COPYRIGHT_YEAR := 2014, \
+))
-# Run javadoc if the index file is out of date or missing
-$(JDI_INDEX_FILE): $(JDI_OPTIONS_FILE) $(JDI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(JDI_OPTIONS_FILE),$(JDI_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(JDI_OPTIONS_FILE) @$(JDI_PACKAGES_FILE)
+TARGETS += $(nashornapi)
+
+################################################################################
-# Create file with javadoc options in it
-$(JDI_OPTIONS_FILE): $(JDI_OVERVIEW)
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(JDI_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionPair,-overview,$(JDI_OVERVIEW)) ; \
- $(call OptionPair,-doctitle,$(JDI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(JDI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(JDI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(JDI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-linkoffline,$(JDI2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
+$(eval $(call SetupJavadocGeneration, dynalinkapi, \
+ MODULES := jdk.dynalink, \
+ PACKAGES := \
+ jdk.dynalink \
+ jdk.dynalink.beans \
+ jdk.dynalink.linker \
+ jdk.dynalink.linker.support \
+ jdk.dynalink.support, \
+ API_ROOT := jdk, \
+ DEST_DIR := dynalink, \
+ TITLE := Dynalink API, \
+ FIRST_COPYRIGHT_YEAR := 2015, \
+))
+
+TARGETS += $(dynalinkapi)
+
+################################################################################
+
+$(eval $(call SetupJavadocGeneration, sctp, \
+ MODULES := jdk.sctp, \
+ PACKAGES := com.sun.nio.sctp, \
+ API_ROOT := jre, \
+ DEST_DIR := nio/sctp/spec, \
+ TITLE := SCTP API, \
+ FIRST_COPYRIGHT_YEAR := 2009, \
+ DOCLINT := none, \
+ NODEPRECATEDLIST := TRUE, \
+))
+
+TARGETS += $(sctp)
+
+################################################################################
+
+$(eval $(call SetupJavadocGeneration, jaccess, \
+ MODULES := jdk.accessibility, \
+ PACKAGES := com.sun.java.accessibility.util, \
+ API_ROOT := jre, \
+ DEST_DIR := accessibility/jaccess/spec, \
+ TITLE := JACCESS API, \
+ FIRST_COPYRIGHT_YEAR := 2002, \
+ NODEPRECATEDLIST := TRUE, \
+))
+
+TARGETS += $(jaccess)
-# Create a file with the package names in it
-$(JDI_PACKAGES_FILE): $(call PackageDependencies,$(JDI_PKGS))
- $(prep-target)
- $(call PackageFilter,$(JDI_PKGS))
+################################################################################
-#############################################################
-#
-# jdwpdocs
-#
+$(eval $(call SetupJavadocGeneration, jdknet, \
+ MODULES := jdk.net, \
+ PACKAGES := jdk.net, \
+ API_ROOT := jre, \
+ DEST_DIR := net/socketoptions/spec, \
+ TITLE := jdk.net API, \
+ FIRST_COPYRIGHT_YEAR := 2014, \
+ DOCLINT := none, \
+ NODEPRECATEDLIST := TRUE, \
+))
-ALL_OTHER_TARGETS += jdwpdocs
+TARGETS += $(jdknet)
+
+################################################################################
-JDWP_DOCDIR = $(PLATFORM_DOCSDIR)/jpda/jdwp
+# TODO: Need to decide when the plugin API is ready to publish as experimental API.
+# This target is temporarily added for internal use for now.
+$(eval $(call SetupJavadocGeneration, jlinkplugins, \
+ MODULES := jdk.jlink, \
+ PACKAGES := jdk.tools.jlink.plugin, \
+ API_ROOT := jdk, \
+ DEST_DIR := jlink, \
+ TITLE := JLink Plugin API - EXPERIMENTAL, \
+ FIRST_COPYRIGHT_YEAR := 2015, \
+ DOCLINT := none, \
+ NODEPRECATEDLIST := TRUE, \
+))
+
+TARGETS += $(jlinkplugins)
-jdwpdocs: $(JDWP_DOCDIR)/jdwp-protocol.html
-$(JDWP_DOCDIR)/jdwp-protocol.html : $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/jdwp-protocol.html
- $(MKDIR) -p $(@D)
- $(RM) $@
- $(CP) $< $@
+################################################################################
+# Copy JDWP html file
+
+JDWP_HTML := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/jdwp-protocol.html
-#############################################################
-#
-# jvmtidocs
-#
+$(eval $(call SetupCopyFiles, COPY_JDWP_HTML, \
+ FILES := $(JDWP_HTML), \
+ DEST := $(JAVADOC_OUTPUTDIR)/platform/jpda/jdwp, \
+))
-JVMTI_DOCDIR := $(PLATFORM_DOCSDIR)/jvmti
+COPY_TARGETS += $(COPY_JDWP_HTML)
+
+################################################################################
+# Copy JVMTI html file
+
# Pick jvmti.html from any jvm variant, they are all the same.
JVMTI_HTML := $(firstword \
$(wildcard $(HOTSPOT_OUTPUTDIR)/variant-*/gensrc/jvmtifiles/jvmti.html))
$(eval $(call SetupCopyFiles, COPY_JVMTI_HTML, \
FILES := $(JVMTI_HTML), \
- DEST := $(PLATFORM_DOCSDIR)/jvmti, \
+ DEST := $(JAVADOC_OUTPUTDIR)/platform/jvmti, \
))
-jvmtidocs: $(COPY_JVMTI_HTML)
-
-#############################################################
-#
-# jaasdocs
-#
-
-ALL_OTHER_TARGETS += jaasdocs
-
-JAAS_DOCDIR := $(JRE_API_DOCSDIR)/security/jaas/spec
-JAAS2COREAPI := ../../../$(JDKJRE2COREAPI)
-JAAS_DOCTITLE := Java$(TRADEMARK) Authentication and Authorization Service
-JAAS_WINDOWTITLE := Java Authentication and Authorization Service
-JAAS_HEADER := <strong>Java Authentication and Authorization Service</strong>
-JAAS_BOTTOM := $(call CommonBottom,$(JAAS_FIRST_COPYRIGHT_YEAR))
-# JAAS_PKGS is located in NON_CORE_PKGS.gmk
-JAAS_OVERVIEW := $(JDK_TOPDIR)/src/jdk.security.auth/share/classes/jaas-overview.html
-
-# The index.html, options, and packages files
-JAAS_INDEX_FILE = $(JAAS_DOCDIR)/index.html
-JAAS_OPTIONS_FILE = $(DOCSTMPDIR)/jaas.options
-JAAS_PACKAGES_FILE = $(DOCSTMPDIR)/jaas.packages
-
-# The modules required to be documented
-JAAS_MODULES = jdk.security.auth
-
-jaasdocs: $(JAAS_INDEX_FILE)
-
-# Set relative location to core api document root
-$(JAAS_INDEX_FILE): GET2DOCSDIR=$(JAAS2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(JAAS_INDEX_FILE): $(JAAS_OPTIONS_FILE) $(JAAS_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(JAAS_OPTIONS_FILE),$(JAAS_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(JAAS_OPTIONS_FILE) @$(JAAS_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(JAAS_OPTIONS_FILE): $(JAAS_OVERVIEW)
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(JAAS_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionPair,-overview,$(JAAS_OVERVIEW)) ; \
- $(call OptionPair,-doctitle,$(JAAS_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(JAAS_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(JAAS_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(JAAS_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-linkoffline,$(JAAS2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(JAAS_PACKAGES_FILE): $(call PackageDependencies,$(JAAS_PKGS))
- $(prep-target)
- $(call PackageFilter,$(JAAS_PKGS))
-
-#############################################################
-#
-# jgssdocs
-#
-
-ALL_OTHER_TARGETS += jgssdocs
-
-JGSS_DOCDIR := $(JRE_API_DOCSDIR)/security/jgss/spec
-JGSS2COREAPI := ../../../$(JDKJRE2COREAPI)
-JGSS_DOCTITLE := Java$(TRADEMARK) GSS-API Utilities
-JGSS_WINDOWTITLE := Java GSS-API Utilities
-JGSS_HEADER := <strong>Java GSS-API Utilities</strong>
-JGSS_BOTTOM := $(call CommonBottom,$(JGSS_FIRST_COPYRIGHT_YEAR))
-JGSS_OVERVIEW := $(JDK_TOPDIR)/src/java.security.jgss/share/classes/jgss-overview.html
-# JGSS_PKGS is located in NON_CORE_PKGS.gmk
-
-# The index.html, options, and packages files
-JGSS_INDEX_FILE = $(JGSS_DOCDIR)/index.html
-JGSS_OPTIONS_FILE = $(DOCSTMPDIR)/jgss.options
-JGSS_PACKAGES_FILE = $(DOCSTMPDIR)/jgss.packages
-
-# The modules required to be documented
-JGSS_MODULES = jdk.security.jgss
-
-jgssdocs: $(JGSS_INDEX_FILE)
-
-# Set relative location to core api document root
-$(JGSS_INDEX_FILE): GET2DOCSDIR=$(JGSS2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(JGSS_INDEX_FILE): $(JGSS_OPTIONS_FILE) $(JGSS_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(JGSS_OPTIONS_FILE),$(JGSS_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(JGSS_OPTIONS_FILE) @$(JGSS_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(JGSS_OPTIONS_FILE): $(JGSS_OVERVIEW)
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(JGSS_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-nodeprecatedlist) ; \
- $(call OptionPair,-overview,$(JGSS_OVERVIEW)) ; \
- $(call OptionPair,-doctitle,$(JGSS_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(JGSS_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(JGSS_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(JGSS_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-linkoffline,$(JGSS2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(JGSS_PACKAGES_FILE): $(call PackageDependencies,$(JGSS_PKGS))
- $(prep-target)
- $(call PackageFilter,$(JGSS_PKGS))
-
-#############################################################
-#
-# smartcardiodocs
-#
-
-ALL_OTHER_TARGETS += smartcardiodocs
-
-SMARTCARDIO_DOCDIR := $(JRE_API_DOCSDIR)/security/smartcardio/spec
-SMARTCARDIO2COREAPI := ../../../$(JDKJRE2COREAPI)
-SMARTCARDIO_DOCTITLE := Java$(TRADEMARK) Smart Card I/O
-SMARTCARDIO_WINDOWTITLE := Java Smart Card I/O
-SMARTCARDIO_HEADER := <strong>Java Smart Card I/O</strong>
-SMARTCARDIO_BOTTOM := $(call CommonBottom,$(SMARTCARDIO_FIRST_COPYRIGHT_YEAR))
-# SMARTCARDIO_PKGS is located in NON_CORE_PKGS.gmk
-
-# The index.html, options, and packages files
-SMARTCARDIO_INDEX_FILE = $(SMARTCARDIO_DOCDIR)/index.html
-SMARTCARDIO_OPTIONS_FILE = $(DOCSTMPDIR)/smartcardio.options
-SMARTCARDIO_PACKAGES_FILE = $(DOCSTMPDIR)/smartcardio.packages
-
-# The modules required to be documented
-SMARTCARDIO_MODULES = java.smartcardio
-
-smartcardiodocs: $(SMARTCARDIO_INDEX_FILE)
-
-# Set relative location to core api document root
-$(SMARTCARDIO_INDEX_FILE): GET2DOCSDIR=$(SMARTCARDIO2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(SMARTCARDIO_INDEX_FILE): $(SMARTCARDIO_OPTIONS_FILE) $(SMARTCARDIO_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(SMARTCARDIO_OPTIONS_FILE),$(SMARTCARDIO_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(SMARTCARDIO_OPTIONS_FILE) @$(SMARTCARDIO_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(SMARTCARDIO_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(SMARTCARDIO_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-nodeprecatedlist) ; \
- $(call OptionPair,-doctitle,$(SMARTCARDIO_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(SMARTCARDIO_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(SMARTCARDIO_HEADER)$(DRAFT_HEADER)); \
- $(call OptionPair,-bottom,$(SMARTCARDIO_BOTTOM)$(DRAFT_BOTTOM)); \
- $(call OptionTrip,-linkoffline,$(SMARTCARDIO2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(SMARTCARDIO_PACKAGES_FILE): $(call PackageDependencies,$(SMARTCARDIO_PKGS))
- $(prep-target)
- $(call PackageFilter,$(SMARTCARDIO_PKGS))
-
-#############################################################
-#
-# httpserverdocs
-#
-
-ALL_OTHER_TARGETS += httpserverdocs
-
-HTTPSERVER_DOCDIR := $(JRE_API_DOCSDIR)/net/httpserver/spec
-HTTPSERVER2COREAPI := ../../../$(JDKJRE2COREAPI)
-HTTPSERVER_DOCTITLE := Java$(TRADEMARK) HTTP Server
-HTTPSERVER_WINDOWTITLE := Java HTTP Server
-HTTPSERVER_HEADER := <strong>Java HTTP Server</strong>
-HTTPSERVER_BOTTOM := $(call CommonBottom,$(HTTPSERVER_FIRST_COPYRIGHT_YEAR))
-# HTTPSERVER_PKGS is located in NON_CORE_PKGS.gmk
-
-HTTPSERVER_INDEX_HTML = $(HTTPSERVER_DOCDIR)/index.html
-HTTPSERVER_OPTIONS_FILE = $(DOCSTMPDIR)/httpserver.options
-HTTPSERVER_PACKAGES_FILE = $(DOCSTMPDIR)/httpserver.packages
-
-# The modules required to be documented
-HTTPSERVER_MODULES = jdk.httpserver
-
-httpserverdocs: $(HTTPSERVER_INDEX_HTML)
-
-# Set relative location to core api document root
-$(HTTPSERVER_INDEX_HTML): GET2DOCSDIR=$(HTTPSERVER2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(HTTPSERVER_INDEX_HTML): $(HTTPSERVER_OPTIONS_FILE) $(HTTPSERVER_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(HTTPSERVER_OPTIONS_FILE),$(HTTPSERVER_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(HTTPSERVER_OPTIONS_FILE) @$(HTTPSERVER_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(HTTPSERVER_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(HTTPSERVER_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-nodeprecatedlist) ; \
- $(call OptionPair,-doctitle,$(HTTPSERVER_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(HTTPSERVER_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(HTTPSERVER_HEADER)$(DRAFT_HEADER)); \
- $(call OptionPair,-bottom,$(HTTPSERVER_BOTTOM)$(DRAFT_BOTTOM)); \
- $(call OptionTrip,-linkoffline,$(HTTPSERVER2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(HTTPSERVER_PACKAGES_FILE): $(call PackageDependencies,$(HTTPSERVER_PKGS))
- $(prep-target)
- $(call PackageFilter,$(HTTPSERVER_PKGS))
-
-#############################################################
-#
-# jsobjectdocs
-#
-
-ALL_OTHER_TARGETS += jsobjectdocs
-
-JSOBJECT_DOCDIR := $(JRE_API_DOCSDIR)/plugin/jsobject
-JSOBJECT2COREAPI := ../../$(JDKJRE2COREAPI)
-JSOBJECT_DOCTITLE := Java$(TRADEMARK) JSObject Doc
-JSOBJECT_WINDOWTITLE := Java JSObject Doc
-JSOBJECT_HEADER := <strong>Java JSObject Doc</strong>
-JSOBJECT_BOTTOM := $(call CommonBottom,$(JSOBJECT_FIRST_COPYRIGHT_YEAR))
-# JSOBJECT_PKGS is located in NON_CORE_PKGS.gmk
-
-JSOBJECT_INDEX_HTML = $(JSOBJECT_DOCDIR)/index.html
-JSOBJECT_OPTIONS_FILE = $(DOCSTMPDIR)/jsobject.options
-JSOBJECT_PACKAGES_FILE = $(DOCSTMPDIR)/jsobject.packages
-
-# The modules required to be documented
-JSOBJECT_MODULES = jdk.jsobject
-
-jsobjectdocs: $(JSOBJECT_INDEX_HTML)
-
-# Set relative location to core api document root
-$(JSOBJECT_INDEX_HTML): GET2DOCSDIR=$(JSOBJECT2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(JSOBJECT_INDEX_HTML): $(JSOBJECT_OPTIONS_FILE) $(JSOBJECT_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(JSOBJECT_OPTIONS_FILE),$(JSOBJECT_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(JSOBJECT_OPTIONS_FILE) @$(JSOBJECT_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(JSOBJECT_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(JSOBJECT_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-nodeprecatedlist) ; \
- $(call OptionPair,-doctitle,$(JSOBJECT_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(JSOBJECT_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(JSOBJECT_HEADER)$(DRAFT_HEADER)); \
- $(call OptionPair,-bottom,$(JSOBJECT_BOTTOM)$(DRAFT_BOTTOM)); \
- $(call OptionTrip,-linkoffline,$(JSOBJECT2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(JSOBJECT_PACKAGES_FILE): $(call PackageDependencies,$(JSOBJECT_PKGS))
- $(prep-target)
- $(call PackageFilter,$(JSOBJECT_PKGS))
-
-
-#############################################################
-#
-# mgmtdocs
-#
-
-ALL_OTHER_TARGETS += mgmtdocs
-
-MGMT_DOCDIR := $(JRE_API_DOCSDIR)/management/extension
-MGMT2COREAPI := ../../$(JDKJRE2COREAPI)
-MGMT_DOCTITLE := Monitoring and Management Interface for the Java$(TRADEMARK) Platform
-MGMT_WINDOWTITLE := Monitoring and Management Interface for the Java Platform
-MGMT_HEADER := <strong>Monitoring and Management Interface for the Java Platform</strong>
-MGMT_BOTTOM := $(call CommonBottom,$(MGMT_FIRST_COPYRIGHT_YEAR))
-MGMT_OVERVIEW := $(JDK_TOPDIR)/src/java.management/share/classes/mgmt-overview.html
-# MGMT_PKGS is located in NON_CORE_PKGS.gmk
-
-# The index.html, options, and packages files
-MGMT_INDEX_FILE = $(MGMT_DOCDIR)/index.html
-MGMT_OPTIONS_FILE = $(DOCSTMPDIR)/mgmt.options
-MGMT_PACKAGES_FILE = $(DOCSTMPDIR)/mgmt.packages
-
-# The modules required to be documented
-MGMT_MODULES = jdk.management
-
-mgmtdocs: $(MGMT_INDEX_FILE)
-
-# Set relative location to core api document root
-$(MGMT_INDEX_FILE): GET2DOCSDIR=$(MGMT2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(MGMT_INDEX_FILE): $(MGMT_OPTIONS_FILE) $(MGMT_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(MGMT_OPTIONS_FILE),$(MGMT_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(MGMT_OPTIONS_FILE) @$(MGMT_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(MGMT_OPTIONS_FILE): $(MGMT_OVERVIEW)
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(MGMT_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-nodeprecatedlist) ; \
- $(call OptionPair,-overview,$(MGMT_OVERVIEW)) ; \
- $(call OptionPair,-doctitle,$(MGMT_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(MGMT_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(MGMT_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(MGMT_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-linkoffline,$(MGMT2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(MGMT_PACKAGES_FILE): $(call PackageDependencies,$(MGMT_PKGS))
- $(prep-target)
- $(call PackageFilter,$(MGMT_PKGS))
-
-#############################################################
-#
-# attachdocs
-#
-
-ALL_OTHER_TARGETS += attachdocs
-
-ATTACH_DOCDIR := $(JDK_API_DOCSDIR)/attach/spec
-ATTACH2COREAPI := ../../$(JDKJRE2COREAPI)
-ATTACH_DOCTITLE := Attach API
-ATTACH_WINDOWTITLE := Attach API
-ATTACH_HEADER := <strong>Attach API</strong>
-ATTACH_BOTTOM := $(call CommonBottom,$(ATTACH_FIRST_COPYRIGHT_YEAR))
-# ATTACH_PKGS is located in NON_CORE_PKGS.gmk
-
-ATTACH_INDEX_HTML = $(ATTACH_DOCDIR)/index.html
-ATTACH_OPTIONS_FILE = $(DOCSTMPDIR)/attach.options
-ATTACH_PACKAGES_FILE = $(DOCSTMPDIR)/attach.packages
-
-# The modules required to be documented
-ATTACH_MODULES = jdk.attach
-
-attachdocs: $(ATTACH_INDEX_HTML)
-
-# Set relative location to core api document root
-$(ATTACH_INDEX_HTML): GET2DOCSDIR=$(ATTACH2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(ATTACH_INDEX_HTML): $(ATTACH_OPTIONS_FILE) $(ATTACH_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(ATTACH_OPTIONS_FILE),$(ATTACH_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(ATTACH_OPTIONS_FILE) @$(ATTACH_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(ATTACH_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(ATTACH_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-nodeprecatedlist) ; \
- $(call OptionPair,-doctitle,$(ATTACH_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(ATTACH_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(ATTACH_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(ATTACH_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-linkoffline,$(ATTACH2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(ATTACH_PACKAGES_FILE): $(call PackageDependencies,$(ATTACH_PKGS))
- $(prep-target)
- $(call PackageFilter,$(ATTACH_PKGS))
-
-#############################################################
-#
-# jconsoledocs
-#
-
-ALL_OTHER_TARGETS += jconsoledocs
-
-JCONSOLE_DOCDIR := $(JDK_API_DOCSDIR)/jconsole/spec
-JCONSOLE2COREAPI := ../../$(JDKJRE2COREAPI)
-JCONSOLE_DOCTITLE := JConsole API
-JCONSOLE_WINDOWTITLE := JConsole API
-JCONSOLE_HEADER := <strong>JConsole API</strong>
-JCONSOLE_BOTTOM := $(call CommonBottom,$(JCONSOLE_FIRST_COPYRIGHT_YEAR))
-# JCONSOLE_PKGS is located in NON_CORE_PKGS.gmk
-
-JCONSOLE_INDEX_HTML = $(JCONSOLE_DOCDIR)/index.html
-JCONSOLE_OPTIONS_FILE = $(DOCSTMPDIR)/jconsole.options
-JCONSOLE_PACKAGES_FILE = $(DOCSTMPDIR)/jconsole.packages
-
-# The modules required to be documented
-JCONSOLE_MODULES = jdk.jconsole
-
-jconsoledocs: $(JCONSOLE_INDEX_HTML)
-
-# Set relative location to core api document root
-$(JCONSOLE_INDEX_HTML): GET2DOCSDIR=$(JCONSOLE2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(JCONSOLE_INDEX_HTML): $(JCONSOLE_OPTIONS_FILE) $(JCONSOLE_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(JCONSOLE_OPTIONS_FILE),$(JCONSOLE_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(JCONSOLE_OPTIONS_FILE) @$(JCONSOLE_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(JCONSOLE_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(JCONSOLE_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-nodeprecatedlist) ; \
- $(call OptionPair,-doctitle,$(JCONSOLE_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(JCONSOLE_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(JCONSOLE_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(JCONSOLE_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-linkoffline,$(JCONSOLE2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(JCONSOLE_PACKAGES_FILE): $(call PackageDependencies,$(JCONSOLE_PKGS))
- $(prep-target)
- $(call PackageFilter,$(JCONSOLE_PKGS))
+COPY_TARGETS += $(COPY_JVMTI_HTML)
-#############################################################
-#
-# jshellapidocs
-#
-
-ALL_OTHER_TARGETS += jshellapidocs
-
-JSHELLAPI_DOCDIR := $(JDK_API_DOCSDIR)/jshell
-JSHELLAPI2COREAPI := ../../$(JDKJRE2COREAPI)
-JSHELLAPI_DOCTITLE := JShell API
-JSHELLAPI_WINDOWTITLE := JShell API
-JSHELLAPI_HEADER := <strong>JSHELL API</strong>
-JSHELLAPI_BOTTOM := $(call CommonBottom,$(JSHELLAPI_FIRST_COPYRIGHT_YEAR))
-JSHELLAPI_OVERVIEW := $(LANGTOOLS_TOPDIR)/src/jdk.jshell/share/classes/jdk/jshell/overview.html
-# JSHELLAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-JSHELLAPI_INDEX_HTML = $(JSHELLAPI_DOCDIR)/index.html
-JSHELLAPI_OPTIONS_FILE = $(DOCSTMPDIR)/jshellapi.options
-JSHELLAPI_PACKAGES_FILE = $(DOCSTMPDIR)/jshellapi.packages
-
-# The modules required to be documented
-JSHELLAPI_MODULES = jdk.jshell
-
-jshellapidocs: $(JSHELLAPI_INDEX_HTML)
-
-# Set relative location to core api document root
-$(JSHELLAPI_INDEX_HTML): GET2DOCSDIR=$(JSHELLAPI2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(JSHELLAPI_INDEX_HTML): $(JSHELLAPI_OPTIONS_FILE) $(JSHELLAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(JSHELLAPI_OPTIONS_FILE),$(JSHELLAPI_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(JSHELLAPI_OPTIONS_FILE) @$(JSHELLAPI_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(JSHELLAPI_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:all) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(JSHELLAPI_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionPair,-overview,$(JSHELLAPI_OVERVIEW)) ; \
- $(call OptionPair,-doctitle,$(JSHELLAPI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(JSHELLAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(JSHELLAPI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(JSHELLAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-linkoffline,$(JSHELLAPI2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(JSHELLAPI_PACKAGES_FILE): $(call PackageDependencies,$(JSHELLAPI_PKGS))
- $(prep-target)
- $(call PackageFilter,$(JSHELLAPI_PKGS))
-
-#############################################################
-#
-# treeapidocs
-#
-
-ALL_OTHER_TARGETS += treeapidocs
-
-TREEAPI_DOCDIR := $(JDK_API_DOCSDIR)/javac/tree
-TREEAPI2COREAPI := ../../$(JDKJRE2COREAPI)
-TREEAPI_DOCTITLE := Compiler Tree API
-TREEAPI_WINDOWTITLE := Compiler Tree API
-TREEAPI_HEADER := <strong>Compiler Tree API</strong>
-TREEAPI_BOTTOM := $(call CommonBottom,$(TREEAPI_FIRST_COPYRIGHT_YEAR))
-TREEAPI_GROUPNAME := Packages
-TREEAPI_REGEXP := com.sun.source.*
-# TREEAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-TREEAPI_INDEX_HTML = $(TREEAPI_DOCDIR)/index.html
-TREEAPI_OPTIONS_FILE = $(DOCSTMPDIR)/treeapi.options
-TREEAPI_PACKAGES_FILE = $(DOCSTMPDIR)/treeapi.packages
-
-# The modules required to be documented
-TREEAPI_MODULES = jdk.compiler
-
-treeapidocs: $(TREEAPI_INDEX_HTML)
-
-# Set relative location to core api document root
-$(TREEAPI_INDEX_HTML): GET2DOCSDIR=$(TREEAPI2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(TREEAPI_INDEX_HTML): $(TREEAPI_OPTIONS_FILE) $(TREEAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(TREEAPI_OPTIONS_FILE),$(TREEAPI_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(TREEAPI_OPTIONS_FILE) @$(TREEAPI_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(TREEAPI_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:all) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(TREEAPI_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionPair,-doctitle,$(TREEAPI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(TREEAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(TREEAPI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(TREEAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-group,$(TREEAPI_GROUPNAME),$(TREEAPI_REGEXP)); \
- $(call OptionTrip,-linkoffline,$(TREEAPI2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(TREEAPI_PACKAGES_FILE): $(call PackageDependencies,$(TREEAPI_PKGS))
- $(prep-target)
- $(call PackageFilter,$(TREEAPI_PKGS))
-
-#############################################################
-#
-# nashornapidocs
-#
-
-ALL_OTHER_TARGETS += nashornapidocs
-
-NASHORNAPI_DOCDIR := $(JDK_API_DOCSDIR)/nashorn
-NASHORNAPI2COREAPI := ../$(JDKJRE2COREAPI)
-NASHORNAPI_DOCTITLE := Nashorn API
-NASHORNAPI_WINDOWTITLE := Nashorn API
-NASHORNAPI_HEADER := <strong>Nashorn API</strong>
-NASHORNAPI_BOTTOM := $(call CommonBottom,$(NASHORNAPI_FIRST_COPYRIGHT_YEAR))
-NASHORNAPI_GROUPNAME := Packages
-NASHORNAPI_REGEXP := jdk.nashorn.api.*
-# NASHORNAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-NASHORNAPI_INDEX_HTML = $(NASHORNAPI_DOCDIR)/index.html
-NASHORNAPI_OPTIONS_FILE = $(DOCSTMPDIR)/nashornapi.options
-NASHORNAPI_PACKAGES_FILE = $(DOCSTMPDIR)/nashornapi.packages
-
-# The modules required to be documented
-NASHORNAPI_MODULES = jdk.scripting.nashorn
-
-nashornapidocs: $(NASHORNAPI_INDEX_HTML)
-
-# Set relative location to core api document root
-$(NASHORNAPI_INDEX_HTML): GET2DOCSDIR=$(NASHORNAPI2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(NASHORNAPI_INDEX_HTML): $(NASHORNAPI_OPTIONS_FILE) $(NASHORNAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(NASHORNAPI_OPTIONS_FILE),$(NASHORNAPI_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(NASHORNAPI_OPTIONS_FILE) @$(NASHORNAPI_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(NASHORNAPI_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:all) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(NASHORNAPI_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionPair,-doctitle,$(NASHORNAPI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(NASHORNAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(NASHORNAPI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(NASHORNAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-group,$(NASHORNAPI_GROUPNAME),$(NASHORNAPI_REGEXP)); \
- $(call OptionTrip,-linkoffline,$(NASHORNAPI2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(NASHORNAPI_PACKAGES_FILE): $(call PackageDependencies,$(NASHORNAPI_PKGS))
- $(prep-target)
- $(call PackageFilter,$(NASHORNAPI_PKGS))
-
-#############################################################
-#
-# dynalinkapidocs
-#
-
-ALL_OTHER_TARGETS += dynalinkapidocs
-
-DYNALINKAPI_DOCDIR := $(JDK_API_DOCSDIR)/dynalink
-DYNALINKAPI2COREAPI := ../$(JDKJRE2COREAPI)
-DYNALINKAPI_DOCTITLE := Dynalink API
-DYNALINKAPI_WINDOWTITLE := Dynalink API
-DYNALINKAPI_HEADER := <strong>Dynalink API</strong>
-DYNALINKAPI_BOTTOM := $(call CommonBottom,$(DYNALINKAPI_FIRST_COPYRIGHT_YEAR))
-DYNALINKAPI_GROUPNAME := Packages
-DYNALINKAPI_REGEXP := jdk.dynalink.*
-# DYNALINKAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-DYNALINKAPI_INDEX_HTML = $(DYNALINKAPI_DOCDIR)/index.html
-DYNALINKAPI_OPTIONS_FILE = $(DOCSTMPDIR)/dynalinkapi.options
-DYNALINKAPI_PACKAGES_FILE = $(DOCSTMPDIR)/dynalinkapi.packages
-
-# The modules required to be documented
-DYNALINKAPI_MODULES = jdk.dynalink
-
-dynalinkapidocs: $(DYNALINKAPI_INDEX_HTML)
-
-# Set relative location to core api document root
-$(DYNALINKAPI_INDEX_HTML): GET2DOCSDIR=$(DYNALINKAPI2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(DYNALINKAPI_INDEX_HTML): $(DYNALINKAPI_OPTIONS_FILE) $(DYNALINKAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(DYNALINKAPI_OPTIONS_FILE),$(DYNALINKAPI_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(DYNALINKAPI_OPTIONS_FILE) @$(DYNALINKAPI_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(DYNALINKAPI_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:all) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(DYNALINKAPI_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionPair,-doctitle,$(DYNALINKAPI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(DYNALINKAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(DYNALINKAPI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(DYNALINKAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-linkoffline,$(DYNALINKAPI2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(DYNALINKAPI_PACKAGES_FILE): $(call PackageDependencies,$(DYNALINKAPI_PKGS))
- $(prep-target)
- $(call PackageFilter,$(DYNALINKAPI_PKGS))
+################################################################################
+# Optional target which bundles all generated javadocs into a zip archive.
+# The dependency on docs is handled in Main.gmk.
-#############################################################
-#
-# sctpdocs
-#
-
-ALL_OTHER_TARGETS += sctpdocs
-
-SCTPAPI_DOCDIR := $(JRE_API_DOCSDIR)/nio/sctp/spec
-SCTPAPI2COREAPI := ../../../$(JDKJRE2COREAPI)
-SCTPAPI_DOCTITLE := SCTP API
-SCTPAPI_WINDOWTITLE := SCTP API
-SCTPAPI_HEADER := <strong>SCTP API</strong>
-SCTPAPI_BOTTOM := $(call CommonBottom,$(SCTPAPI_FIRST_COPYRIGHT_YEAR))
-# SCTPAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-SCTPAPI_INDEX_HTML = $(SCTPAPI_DOCDIR)/index.html
-SCTPAPI_OPTIONS_FILE = $(DOCSTMPDIR)/sctp.options
-SCTPAPI_PACKAGES_FILE = $(DOCSTMPDIR)/sctp.packages
-
-# The modules required to be documented
-SCTPAPI_MODULES = jdk.sctp
-
-sctpdocs: $(SCTPAPI_INDEX_HTML)
-
-# Set relative location to core api document root
-$(SCTPAPI_INDEX_HTML): GET2DOCSDIR=$(SCTPAPI2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(SCTPAPI_INDEX_HTML): $(SCTPAPI_OPTIONS_FILE) $(SCTPAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(SCTPAPI_OPTIONS_FILE),$(SCTPAPI_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(SCTPAPI_OPTIONS_FILE) @$(SCTPAPI_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(SCTPAPI_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(SCTPAPI_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-nodeprecatedlist) ; \
- $(call OptionPair,-doctitle,$(SCTPAPI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(SCTPAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(SCTPAPI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(SCTPAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-linkoffline,$(SCTPAPI2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(SCTPAPI_PACKAGES_FILE): $(call PackageDependencies,$(SCTPAPI_PKGS))
- $(prep-target)
- $(call PackageFilter,$(SCTPAPI_PKGS))
-
-#############################################################
-#
-# jaccessdocs - Java Accessibility Utilities
-#
-
-ALL_OTHER_TARGETS += jaccessdocs
-
-JACCESSAPI_DOCDIR := $(JRE_API_DOCSDIR)/accessibility/jaccess/spec
-JACCESSAPI2COREAPI := ../../../$(JDKJRE2COREAPI)
-JACCESSAPI_DOCTITLE := JACCESS API
-JACCESSAPI_WINDOWTITLE := JACCESS API
-JACCESSAPI_HEADER := <strong>JACCESS API</strong>
-JACCESSAPI_BOTTOM := $(call CommonBottom,$(JACCESSAPI_FIRST_COPYRIGHT_YEAR))
-# JACCESSAPI_PKGS is located in NON_CORE_PKGS.gmk
-
-JACCESSAPI_INDEX_HTML = $(JACCESSAPI_DOCDIR)/index.html
-JACCESSAPI_OPTIONS_FILE = $(DOCSTMPDIR)/jaccess.options
-JACCESSAPI_PACKAGES_FILE = $(DOCSTMPDIR)/jaccess.packages
-
-# The modules required to be documented
-JACCESSAPI_MODULES = jdk.accessibility
-
-jaccessdocs: $(JACCESSAPI_INDEX_HTML)
-
-# Set relative location to core api document root
-$(JACCESSAPI_INDEX_HTML): GET2DOCSDIR=$(JACCESSAPI2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(JACCESSAPI_INDEX_HTML): $(JACCESSAPI_OPTIONS_FILE) $(JACCESSAPI_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(JACCESSAPI_OPTIONS_FILE),$(JACCESSAPI_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(JACCESSAPI_OPTIONS_FILE) @$(JACCESSAPI_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(JACCESSAPI_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:all) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(JACCESSAPI_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-nodeprecatedlist) ; \
- $(call OptionPair,-doctitle,$(JACCESSAPI_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(JACCESSAPI_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(JACCESSAPI_HEADER)$(DRAFT_HEADER)) ; \
- $(call OptionPair,-bottom,$(JACCESSAPI_BOTTOM)$(DRAFT_BOTTOM)) ; \
- $(call OptionTrip,-linkoffline,$(JACCESSAPI2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(JACCESSAPI_PACKAGES_FILE): $(call PackageDependencies,$(JACCESSAPI_PKGS))
- $(prep-target)
- $(call PackageFilter,$(JACCESSAPI_PKGS))
-
-#############################################################
-#
-# jdk.net docs
-#
-
-ALL_OTHER_TARGETS += jdknetdocs
-
-JDKNET_DOCDIR := $(JRE_API_DOCSDIR)/net/socketoptions/spec
-JDKNET2COREAPI := ../../../$(JDKJRE2COREAPI)
-JDKNET_DOCTITLE := jdk.net API
-JDKNET_WINDOWTITLE := jdk.net API
-JDKNET_HEADER := <strong>jdk.net API</strong>
-JDKNET_BOTTOM := $(call CommonBottom,$(JDKNET_FIRST_COPYRIGHT_YEAR))
-JDKNET_PKGS := jdk.net
-
-JDKNET_INDEX_HTML = $(JDKNET_DOCDIR)/index.html
-JDKNET_OPTIONS_FILE = $(DOCSTMPDIR)/jdknet.options
-JDKNET_PACKAGES_FILE = $(DOCSTMPDIR)/jdknet.packages
-
-# The modules required to be documented
-JDKNET_MODULES = jdk.net
-
-jdknetdocs: $(JDKNET_INDEX_HTML)
-
-# Set relative location to core api document root
-$(JDKNET_INDEX_HTML): GET2DOCSDIR=$(JDKNET2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(JDKNET_INDEX_HTML): $(JDKNET_OPTIONS_FILE) $(JDKNET_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(JDKNET_OPTIONS_FILE),$(JDKNET_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(JDKNET_OPTIONS_FILE) @$(JDKNET_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(JDKNET_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(JDKNET_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-nodeprecatedlist) ; \
- $(call OptionPair,-doctitle,$(JDKNET_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(JDKNET_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(JDKNET_HEADER)$(DRAFT_HEADER)); \
- $(call OptionPair,-bottom,$(JDKNET_BOTTOM)$(DRAFT_BOTTOM)); \
- $(call OptionTrip,-linkoffline,$(JDKNET2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(JDKNET_PACKAGES_FILE): $(call PackageDependencies,$(JDKNET_PKGS))
- $(prep-target)
- $(call PackageFilter,$(JDKNET_PKGS))
-
-#############################################################
-#
-# jlink plugin API docs
-#
-# TODO: Need to decide when the plugin API is ready to publish as experimental API.
-# This target is temporarily added for internal use for now.
-#
-
-ALL_OTHER_TARGETS += jlinkdocs
-
-JLINK_PLUGIN_FIRST_COPYRIGHT_YEAR = 2015
-JLINK_PLUGIN_DOCDIR := $(JDK_API_DOCSDIR)/jlink
-JLINK_PLUGIN2COREAPI := ../$(JDKJRE2COREAPI)
-JLINK_PLUGIN_DOCTITLE := JLink Plugin API - EXPERIMENTAL
-JLINK_PLUGIN_WINDOWTITLE := JLink Plugin API - EXPERIMENTAL
-JLINK_PLUGIN_HEADER := <strong>JLink Plugin API - EXPERIMENTAL</strong>
-JLINK_PLUGIN_BOTTOM := $(call CommonBottom,$(JLINK_PLUGIN_FIRST_COPYRIGHT_YEAR))
-JLINK_PLUGIN_PKGS = jdk.tools.jlink.plugin
-
-JLINK_PLUGIN_INDEX_HTML = $(JLINK_PLUGIN_DOCDIR)/index.html
-JLINK_PLUGIN_OPTIONS_FILE = $(DOCSTMPDIR)/jlinkplugins.options
-JLINK_PLUGIN_PACKAGES_FILE = $(DOCSTMPDIR)/jlinkplugins.packages
-
-# The modules required to be documented
-JLINK_PLUGIN_MODULES = jdk.jlink
-
-jlinkdocs: $(JLINK_PLUGIN_INDEX_HTML)
-
-# Set relative location to core api document root
-$(JLINK_PLUGIN_INDEX_HTML): GET2DOCSDIR=$(JLINK_PLUGIN2COREAPI)/..
-
-# Run javadoc if the index file is out of date or missing
-$(JLINK_PLUGIN_INDEX_HTML): $(JLINK_PLUGIN_OPTIONS_FILE) $(JLINK_PLUGIN_PACKAGES_FILE) $(COREAPI_INDEX_FILE)
- $(prep-javadoc)
- $(call JavadocSummary,$(JLINK_PLUGIN_OPTIONS_FILE),$(JLINK_PLUGIN_PACKAGES_FILE))
- $(JAVADOC_CMD_SMALL) -d $(@D) \
- @$(JLINK_PLUGIN_OPTIONS_FILE) @$(JLINK_PLUGIN_PACKAGES_FILE)
-
-# Create file with javadoc options in it
-$(JLINK_PLUGIN_OPTIONS_FILE):
- $(prep-target)
- @($(call COMMON_JAVADOCFLAGS) ; \
- $(call COMMON_JAVADOCTAGS) ; \
- $(call OptionOnly,-Xdoclint:none) ; \
- $(call OptionPair,--system,none) ; \
- $(call OptionPair,--module-source-path,$(RELEASEDOCS_MODULESOURCEPATH)) ; \
- $(call OptionPair,--add-modules,$(JLINK_PLUGIN_MODULES)) ; \
- $(call OptionPair,-encoding,ascii) ; \
- $(call OptionOnly,-nodeprecatedlist) ; \
- $(call OptionPair,-doctitle,$(JLINK_PLUGIN_DOCTITLE)) ; \
- $(call OptionPair,-windowtitle,$(JLINK_PLUGIN_WINDOWTITLE) $(DRAFT_WINTITLE)); \
- $(call OptionPair,-header,$(JLINK_PLUGIN_HEADER)$(DRAFT_HEADER)); \
- $(call OptionPair,-bottom,$(JLINK_PLUGIN_BOTTOM)$(DRAFT_BOTTOM)); \
- $(call OptionTrip,-linkoffline,$(JLINK_PLUGIN2COREAPI),$(COREAPI_DOCSDIR)/); \
- ) >> $@
-
-# Create a file with the package names in it
-$(JLINK_PLUGIN_PACKAGES_FILE): $(call PackageDependencies,$(JLINK_PLUGIN_PKGS))
- $(prep-target)
- $(call PackageFilter,$(JLINK_PLUGIN_PKGS))
-
-
-otherdocs: $(ALL_OTHER_TARGETS)
-
-#
# Add the core docs as prerequisite to the archive to trigger a rebuild
# if the core docs were rebuilt. Ideally any doc rebuild should trigger
# this, but the way prerequisites are currently setup in this file, that
# is hard to achieve.
-#
-$(JAVADOC_ARCHIVE): $(COREAPI_INDEX_FILE)
+JAVADOC_ARCHIVE_NAME := jdk-$(VERSION_STRING)-docs.zip
+JAVADOC_ARCHIVE_ASSEMBLY_DIR := $(SUPPORT_OUTPUTDIR)/docs/zip-docs
+JAVADOC_ARCHIVE_DIR := $(OUTPUT_ROOT)/bundles
+JAVADOC_ARCHIVE := $(JAVADOC_ARCHIVE_DIR)/$(JAVADOC_ARCHIVE_NAME)
+
+$(JAVADOC_ARCHIVE): $(CORE_INDEX_FILE)
$(call LogInfo, Compressing javadoc to single $(JAVADOC_ARCHIVE_NAME))
$(MKDIR) -p $(JAVADOC_ARCHIVE_DIR)
$(RM) -r $(JAVADOC_ARCHIVE_ASSEMBLY_DIR)
$(MKDIR) -p $(JAVADOC_ARCHIVE_ASSEMBLY_DIR)
- all_roots=`$(FIND) $(DOCSDIR) | $(GREP) index.html | grep -v old/doclet`; \
+ all_roots=`$(FIND) $(JAVADOC_OUTPUTDIR) | $(GREP) index.html | grep -v old/doclet`; \
pushd $(JAVADOC_ARCHIVE_ASSEMBLY_DIR); \
for index_file in $${all_roots} ; do \
target_dir=`dirname $${index_file}`; \
@@ -1742,10 +1041,21 @@
$(ZIP) -q -r $(JAVADOC_ARCHIVE) * ; \
popd ;
-#############################################################
-.PHONY: all docs coredocs otherdocs \
- $(ALL_OTHER_TARGETS) zip-docs
+ZIP_TARGETS += $(JAVADOC_ARCHIVE)
+
+################################################################################
+
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, , Javadoc.gmk))
################################################################################
-$(eval $(call IncludeCustomExtension, , Javadoc-post.gmk))
+docs-javadoc: $(TARGETS)
+
+docs-copy: $(COPY_TARGETS)
+
+docs-zip: $(ZIP_TARGETS)
+
+all: docs-javadoc docs-copy docs-zip
+
+.PHONY: default all docs-javadoc docs-copy docs-zip
--- a/make/Main.gmk Wed Oct 19 08:05:48 2016 -0700
+++ b/make/Main.gmk Thu Oct 27 08:52:00 2016 -0700
@@ -341,15 +341,15 @@
# Docs targets
docs-javadoc:
- +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk docs)
+ +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk docs-javadoc)
-docs-jvmtidoc:
- +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk jvmtidocs)
+docs-copy:
+ +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk docs-copy)
-zip-docs:
- +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk zip-docs)
+docs-zip:
+ +($(CD) $(SRC_ROOT)/make && $(MAKE) $(MAKE_ARGS) -f Javadoc.gmk docs-zip)
-ALL_TARGETS += docs-javadoc docs-jvmtidoc zip-docs
+ALL_TARGETS += docs-javadoc docs-copy docs-zip
################################################################################
# Cross compilation support
@@ -683,9 +683,9 @@
docs-javadoc: $(GENSRC_TARGETS) rmic
- docs-jvmtidoc: hotspot
+ docs-copy: hotspot
- zip-docs: docs-javadoc docs-jvmtidoc
+ docs-zip: docs-javadoc docs-copy
test: jdk-image test-image
@@ -812,7 +812,7 @@
endif
# This target builds the documentation image
-docs-image: docs-javadoc docs-jvmtidoc
+docs-image: docs-javadoc docs-copy
# This target builds the test image
test-image: prepare-test-image test-image-hotspot-jtreg-native \
@@ -860,7 +860,7 @@
CLEAN_SUPPORT_DIR_TARGETS := $(addprefix clean-, $(CLEAN_SUPPORT_DIRS))
CLEAN_TESTS += hotspot-jtreg-native jdk-jtreg-native lib
CLEAN_TEST_TARGETS += $(addprefix clean-test-, $(CLEAN_TESTS))
-CLEAN_PHASES := gensrc java native include docs
+CLEAN_PHASES := gensrc java native include
CLEAN_PHASE_TARGETS := $(addprefix clean-, $(CLEAN_PHASES))
CLEAN_MODULE_TARGETS := $(addprefix clean-, $(ALL_MODULES))
# Construct targets of the form clean-$module-$phase
@@ -872,6 +872,9 @@
($(CD) $(OUTPUT_ROOT) && $(RM) -r build*.log*)
$(ECHO) Cleaned all build artifacts.
+clean-docs:
+ $(call CleanDocs)
+
$(CLEAN_DIR_TARGETS):
$(call CleanDir,$(patsubst clean-%, %, $@))
@@ -911,7 +914,7 @@
)
$(ECHO) Cleaned everything, you will have to re-run configure.
-ALL_TARGETS += clean dist-clean $(CLEAN_DIR_TARGETS) $(CLEAN_SUPPORT_DIR_TARGETS) \
+ALL_TARGETS += clean clean-docs dist-clean $(CLEAN_DIR_TARGETS) $(CLEAN_SUPPORT_DIR_TARGETS) \
$(CLEAN_TEST_TARGETS) $(CLEAN_PHASE_TARGETS) $(CLEAN_MODULE_TARGETS) \
$(CLEAN_MODULE_PHASE_TARGETS)
--- a/make/MainSupport.gmk Wed Oct 19 08:05:48 2016 -0700
+++ b/make/MainSupport.gmk Thu Oct 27 08:52:00 2016 -0700
@@ -41,6 +41,15 @@
JOBS=$(JOBS) $1) || true
endef
+define CleanDocs
+ @$(PRINTF) "Cleaning docs ..."
+ @$(PRINTF) "\n" $(LOG_DEBUG)
+ $(RM) -r $(SUPPORT_OUTPUTDIR)/docs
+ $(RM) -r $(SUPPORT_OUTPUTDIR)/javadoc
+ $(RM) -r $(IMAGES_OUTPUTDIR)/docs
+ @$(PRINTF) " done\n"
+endef
+
# Cleans the dir given as $1
define CleanDir
@$(PRINTF) "Cleaning $(strip $1) build artifacts ..."
@@ -99,15 +108,6 @@
@$(PRINTF) " done\n"
endef
-define Clean-docs
- @$(PRINTF) "Cleaning docs ..."
- @$(PRINTF) "\n" $(LOG_DEBUG)
- $(RM) -r $(SUPPORT_OUTPUTDIR)/docs
- $(RM) -r $(IMAGES_OUTPUTDIR)/docs
- $(RM) $(OUTPUT_ROOT)/bundles/jdk-*-docs.zip
- @$(PRINTF) " done\n"
-endef
-
define CleanModule
$(call Clean-gensrc, $1)
$(call Clean-java, $1)
--- a/make/common/NativeCompilation.gmk Wed Oct 19 08:05:48 2016 -0700
+++ b/make/common/NativeCompilation.gmk Thu Oct 27 08:52:00 2016 -0700
@@ -746,9 +746,10 @@
# This is a rough heuristic and may not always print accurate information.
$$($1_BUILD_INFO): $$($1_SRCS) $$($1_COMPILE_VARDEPS_FILE)
ifeq ($$(wildcard $$($1_TARGET)),)
- $(ECHO) 'Creating $$($1_BASENAME) from $$(words $$(filter-out %.vardeps, $$?)) file(s)'
+ $(ECHO) 'Creating $$(subst $$(BUILD_OUTPUT)/,,$$($1_TARGET)) from $$(words \
+ $$(filter-out %.vardeps, $$?)) file(s)'
else
- $(ECHO) $$(strip 'Updating $$($1_BASENAME)' \
+ $(ECHO) $$(strip 'Updating $$(subst $$(BUILD_OUTPUT)/,,$$($1_TARGET))' \
$$(if $$(filter-out %.vardeps, $$?), \
'due to $$(words $$(filter-out %.vardeps, $$?)) file(s)', \
$$(if $$(filter %.vardeps, $$?), 'due to makefile changes')))
--- a/make/common/SetupJavaCompilers.gmk Wed Oct 19 08:05:48 2016 -0700
+++ b/make/common/SetupJavaCompilers.gmk Thu Oct 27 08:52:00 2016 -0700
@@ -28,11 +28,11 @@
include JavaCompilation.gmk
-DISABLE_WARNINGS := -Xlint:all,-deprecation,-unchecked,-rawtypes,-cast,-serial,-dep-ann,-static,-fallthrough,-try,-varargs,-empty,-finally
+DISABLE_WARNINGS := -Xlint:all,-deprecation,-removal,-unchecked,-rawtypes,-cast,-serial,-dep-ann,-static,-fallthrough,-try,-varargs,-empty,-finally
# If warnings needs to be non-fatal for testing purposes use a command like:
# make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000"
-JAVAC_WARNINGS := -Xlint:all -Werror
+JAVAC_WARNINGS := -Xlint:all,-removal -Werror
# The BOOT_JAVAC setup uses the boot jdk compiler to compile the tools
# and the interim javac, to be run by the boot jdk.
--- a/nashorn/.hgtags Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/.hgtags Thu Oct 27 08:52:00 2016 -0700
@@ -374,3 +374,4 @@
4a6ee1185fc821df063e4d1537fa7ad2ebe9eb02 jdk-9+138
e3b11296395b39bfeb3364f26c2ef77fa652e300 jdk-9+139
785843878cf78d50cc2959ea2c5a4202bbe885b4 jdk-9+140
+a46b7d3867957a868a6cc8ee66c05079b883733a jdk-9+141
--- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java Thu Oct 27 08:52:00 2016 -0700
@@ -42,6 +42,8 @@
import jdk.internal.jline.console.ConsoleReader;
import jdk.internal.jline.console.KeyMap;
import jdk.internal.jline.extra.EditingHistory;
+import jdk.internal.misc.Signal;
+import jdk.internal.misc.Signal.Handler;
class Console implements AutoCloseable {
private static final String DOCUMENTATION_SHORTCUT = "\033\133\132"; //Shift-TAB
@@ -68,6 +70,21 @@
in.addCompleter(completer);
Runtime.getRuntime().addShutdownHook(new Thread((Runnable)this::saveHistory));
bind(DOCUMENTATION_SHORTCUT, (ActionListener)evt -> showDocumentation(docHelper));
+ try {
+ Signal.handle(new Signal("CONT"), new Handler() {
+ @Override public void handle(Signal sig) {
+ try {
+ in.getTerminal().reset();
+ in.redrawLine();
+ in.flush();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ });
+ } catch (IllegalArgumentException ignored) {
+ //the CONT signal does not exist on this platform
+ }
}
String readLine(final String prompt) throws IOException {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Thu Oct 27 08:52:00 2016 -0700
@@ -129,10 +129,11 @@
@Override
public String getProgram(final String... statements) {
+ Objects.requireNonNull(statements);
final StringBuilder sb = new StringBuilder();
for (final String statement : statements) {
- sb.append(statement).append(';');
+ sb.append(Objects.requireNonNull(statement)).append(';');
}
return sb.toString();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayIterator.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayIterator.java Thu Oct 27 08:52:00 2016 -0700
@@ -47,13 +47,25 @@
private final Global global;
- ArrayIterator(final Object iteratedObject, final IterationKind iterationKind, final Global global) {
+ private ArrayIterator(final Object iteratedObject, final IterationKind iterationKind, final Global global) {
super(global.getArrayIteratorPrototype(), $nasgenmap$);
this.iteratedObject = iteratedObject instanceof ScriptObject ? (ScriptObject) iteratedObject : null;
this.iterationKind = iterationKind;
this.global = global;
}
+ static ArrayIterator newArrayValueIterator(final Object iteratedObject) {
+ return new ArrayIterator(Global.toObject(iteratedObject), IterationKind.VALUE, Global.instance());
+ }
+
+ static ArrayIterator newArrayKeyIterator(final Object iteratedObject) {
+ return new ArrayIterator(Global.toObject(iteratedObject), IterationKind.KEY, Global.instance());
+ }
+
+ static ArrayIterator newArrayKeyValueIterator(final Object iteratedObject) {
+ return new ArrayIterator(Global.toObject(iteratedObject), IterationKind.KEY_VALUE, Global.instance());
+ }
+
/**
* 22.1.5.2.1 %ArrayIteratorPrototype%.next()
*
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java Thu Oct 27 08:52:00 2016 -0700
@@ -1726,7 +1726,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object entries(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.KEY_VALUE, Global.instance());
+ return ArrayIterator.newArrayKeyValueIterator(self);
}
/**
@@ -1737,7 +1737,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object keys(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.KEY, Global.instance());
+ return ArrayIterator.newArrayKeyIterator(self);
}
/**
@@ -1748,7 +1748,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object values(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.VALUE, Global.instance());
+ return ArrayIterator.newArrayValueIterator(self);
}
/**
@@ -1759,7 +1759,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
public static Object getIterator(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.VALUE, Global.instance());
+ return ArrayIterator.newArrayValueIterator(self);
}
/**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java Thu Oct 27 08:52:00 2016 -0700
@@ -232,6 +232,17 @@
return (NativeFloat32Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getFloat32ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java Thu Oct 27 08:52:00 2016 -0700
@@ -232,6 +232,17 @@
return (NativeFloat64Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getFloat64ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java Thu Oct 27 08:52:00 2016 -0700
@@ -225,6 +225,17 @@
return (NativeInt16Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getInt16ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java Thu Oct 27 08:52:00 2016 -0700
@@ -224,6 +224,17 @@
return (NativeInt32Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getInt32ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java Thu Oct 27 08:52:00 2016 -0700
@@ -224,6 +224,17 @@
return (NativeInt8Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getInt8ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java Thu Oct 27 08:52:00 2016 -0700
@@ -701,13 +701,9 @@
}
thisIndex = matcher.end();
- if (thisIndex == string.length() && matcher.start() == matcher.end()) {
- // Avoid getting empty match at end of string twice
- break;
- }
- // ECMA 15.5.4.10 String.prototype.match(regexp)
- if (thisIndex == previousLastIndex) {
+ // ECMA6 21.2.5.6 step 8.g.iv.5: If matchStr is empty advance index by one
+ if (matcher.start() == matcher.end()) {
setLastIndex(thisIndex + 1);
previousLastIndex = thisIndex + 1;
} else {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java Thu Oct 27 08:52:00 2016 -0700
@@ -229,6 +229,17 @@
return (NativeUint16Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint16ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java Thu Oct 27 08:52:00 2016 -0700
@@ -244,6 +244,17 @@
return (NativeUint32Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint32ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java Thu Oct 27 08:52:00 2016 -0700
@@ -230,6 +230,17 @@
return (NativeUint8Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint8ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Wed Oct 19 08:05:48 2016 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Thu Oct 27 08:52:00 2016 -0700
@@ -82,7 +82,6 @@
private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
private static final MethodHandle RINT_D = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "rint", double.class, double.class).methodHandle();
private static final MethodHandle RINT_O = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "rint", Object.class, Object.class).methodHandle();
- private static final MethodHandle CLAMP_LONG = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "clampLong", long.class, long.class).methodHandle();
private Uint8ClampedArrayData(final ByteBuffer nb, final int start, final int end) {
super((nb.position(start).limit(end)).slice(), end - start);
@@ -124,8 +123,6 @@
return MH.filterArguments(setter, 2, RINT_O);
} else if (elementType == double.class) {
return MH.filterArguments(setter, 2, RINT_D);
- } else if (elementType == long.class) {
- return MH.filterArguments(setter, 2, CLAMP_LONG);
}
}
return setter;
@@ -195,7 +192,7 @@
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
- return set(index, rint(value), strict);
+ return set(index, (int) rint(value), strict);
}
private static double rint(final double rint) {
@@ -207,15 +204,6 @@
return rint(JSType.toNumber(rint));
}
- @SuppressWarnings("unused")
- private static long clampLong(final long l) {
- if(l < 0L) {
- return 0L;
- } else if(l > 0xffL) {
- return 0xffL;
- }
- return l;
- }
}
/**
@@ -278,6 +266,17 @@
return (NativeUint8ClampedArray)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint8ClampedArrayPrototype();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8164708.js Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8164708: String.prototype.replace replaces empty match twice
+ *
+ * @test
+ * @run
+ */
+
+Assert.assertEquals("4005".replace(/\B(?=(\d{3})+(?!\d))/g, ","), "4,005");
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8168146.js Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * JDK-8168146: Infinite recursion in Uint8ClampedArray.set
+ *
+ * @test
+ * @run
+ */
+
+
+var a = new Uint8ClampedArray(10);
+
+for (var i = 0; i < 10; i++) {
+ a[i] = i;
+ Assert.assertTrue(a[i] === i);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/JDK-8168140.js Thu Oct 27 08:52:00 2016 -0700
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8168140: TypedArrays should implement ES6 iterator protocol
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+let TypedArrayTypes = [
+ Int8Array,
+ Uint8Array,
+ Uint8ClampedArray,
+ Int16Array,
+ Uint16Array,
+ Int32Array,
+ Uint32Array,
+ Float32Array,
+ Float64Array
+];
+
+let arrays = [];
+let sum = 0;
+
+TypedArrayTypes.forEach(function(ArrayType) {
+ var a = new ArrayType(10);
+ for (let i = 0; i < a.length; i++) {
+ a[i] = i;
+ }
+ arrays.push(a);
+});
+
+Assert.assertTrue(arrays.length === 9);
+
+for (let array of arrays) {
+
+ Assert.assertTrue(array.length === 10);
+ let count = 0;
+
+ for (let value of array) {
+ Assert.assertTrue(value === count++);
+ sum += value;
+ }
+}
+
+Assert.assertTrue(sum === 405);
--- a/test/Makefile Wed Oct 19 08:05:48 2016 -0700
+++ b/test/Makefile Thu Oct 27 08:52:00 2016 -0700
@@ -74,13 +74,14 @@
jaxp_%:
@$(NO_STOPPING)$(call SUBDIR_TEST, $(JAXP_DIR), CONCURRENCY=$(JDK_TEST_JOBS) TEST="$@" $@)
-ifeq ($(TEST_JOBS), 0)
- HOTSPOT_TEST_JOBS=1
-else
- HOTSPOT_TEST_JOBS=$(TEST_JOBS)
+SUB_MAKE_ARGS :=
+ifneq ($(TEST_JOBS), 0)
+ ifneq ($(TEST_JOBS), )
+ SUB_MAKE_ARGS += CONCURRENCY=$(TEST_JOBS)
+ endif
endif
hotspot_%:
- @$(NO_STOPPING)$(call SUBDIR_TEST, $(HOTSPOT_DIR), CONCURRENCY=$(HOTSPOT_TEST_JOBS) TEST="$@" $@)
+ @$(NO_STOPPING)$(call SUBDIR_TEST, $(HOTSPOT_DIR), $(SUB_MAKE_ARGS) TEST="$@" $@)
#
# jtreg_tests
--- a/test/failure_handler/src/share/conf/common.properties Wed Oct 19 08:05:48 2016 -0700
+++ b/test/failure_handler/src/share/conf/common.properties Thu Oct 27 08:52:00 2016 -0700
@@ -34,9 +34,8 @@
jcmd.vm.classloader_stats jcmd.vm.stringtable \
jcmd.vm.symboltable jcmd.vm.uptime jcmd.vm.dynlibs \
jcmd.vm.system_properties \
- jcmd.gc.class_stats jcmd.gc.class_histogram \
- jstack \
- jmap.heap jmap.histo jmap.clstats jmap.finalizerinfo
+ jcmd.gc.heap_info jcmd.gc.class_stats jcmd.gc.class_histogram jcmd.gc.finalizer_info \
+ jstack
jinfo.app=jinfo
@@ -55,16 +54,12 @@
jcmd.gc.class_stats.args=%p GC.class_stats
jcmd.gc.class_histogram.args=%p GC.class_histogram
+jcmd.gc.finalizer_info.args=%p GC.finalizer_info
+jcmd.gc.heap_info.args=%p GC.heap_info
jstack.app=jstack
jstack.params.repeat=6
-jmap.app=jmap
-jmap.heap.args=-heap %p
-jmap.histo.args=-histo %p
-jmap.clstats.args=-clstats %p
-jmap.finalizerinfo.args=-finalizerinfo %p
-
################################################################################
# environment info to gather
################################################################################