Merge
This commit is contained in:
commit
05feaeeecd
@ -25,103 +25,7 @@
|
||||
|
||||
include Modules.gmk
|
||||
|
||||
BOOT_MODULES :=
|
||||
UPGRADEABLE_MDOULES :=
|
||||
AGGREGATOR_MDOULES :=
|
||||
OTHER_PLATFORM_MODULES :=
|
||||
|
||||
# Hook to include the corresponding custom file, if present.
|
||||
$(eval $(call IncludeCustomExtension, jdk, gensrc/GensrcModuleLoaderMap.gmk))
|
||||
|
||||
BOOT_MODULES += \
|
||||
java.base \
|
||||
java.datatransfer \
|
||||
java.desktop \
|
||||
java.httpclient \
|
||||
java.instrument \
|
||||
java.logging \
|
||||
java.management \
|
||||
java.naming \
|
||||
java.prefs \
|
||||
java.rmi \
|
||||
java.security.jgss \
|
||||
java.security.sasl \
|
||||
java.sql \
|
||||
java.xml \
|
||||
java.xml.crypto \
|
||||
jdk.httpserver \
|
||||
jdk.management \
|
||||
jdk.sctp \
|
||||
jdk.security.auth \
|
||||
jdk.security.jgss \
|
||||
#
|
||||
|
||||
# to be deprivileged
|
||||
BOOT_MODULES += \
|
||||
java.compiler \
|
||||
java.scripting \
|
||||
java.sql.rowset \
|
||||
java.smartcardio \
|
||||
jdk.charsets \
|
||||
jdk.naming.rmi \
|
||||
#
|
||||
|
||||
UPGRADEABLE_MODULES += \
|
||||
java.activation \
|
||||
java.annotations.common \
|
||||
java.corba \
|
||||
java.transaction \
|
||||
java.xml.bind \
|
||||
java.xml.ws \
|
||||
#
|
||||
|
||||
AGGREGATOR_MODULES += \
|
||||
java.compact1 \
|
||||
java.compact2 \
|
||||
java.compact3 \
|
||||
java.se \
|
||||
java.se.ee \
|
||||
#
|
||||
|
||||
OTHER_PLATFORM_MODULES += \
|
||||
jdk.accessibility \
|
||||
jdk.crypto.ec \
|
||||
jdk.crypto.pkcs11 \
|
||||
jdk.dynalink \
|
||||
jdk.jsobject \
|
||||
jdk.xml.dom \
|
||||
jdk.localedata \
|
||||
jdk.naming.dns \
|
||||
jdk.scripting.nashorn \
|
||||
jdk.zipfs \
|
||||
#
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macsox)
|
||||
BOOT_MODULES += jdk.deploy.osx
|
||||
endif
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
OTHER_PLATFORM_MODULES += jdk.crypto.mscapi
|
||||
endif
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
OTHER_PLATFORM_MODULES += jdk.crypto.ucrypto
|
||||
endif
|
||||
|
||||
# Param 1 - Name of module
|
||||
define ReadImportMetaData
|
||||
ifneq ($$(wildcard $(IMPORT_MODULES_MAKE)/$$(strip $1)/build.properties), )
|
||||
classloader :=
|
||||
include $(IMPORT_MODULES_MAKE)/$$(strip $1)/build.properties
|
||||
ifeq ($$(classloader), boot)
|
||||
BOOT_MODULES += $1
|
||||
else ifeq ($$(classloader), ext)
|
||||
OTHER_PLATFORM_MODULES += $1
|
||||
endif
|
||||
endif
|
||||
endef
|
||||
|
||||
IMPORTED_MODULES := $(call FindImportedModules)
|
||||
$(foreach m, $(IMPORTED_MODULES), $(eval $(call ReadImportMetaData, $m)))
|
||||
|
||||
$(eval $(call ReadImportMetaData))
|
||||
|
||||
# Replacing double-comma with a single comma is to workaround the issue
|
||||
# with some version of make on windows that doesn't substitute spaces
|
||||
@ -132,7 +36,7 @@ $(strip \
|
||||
)
|
||||
endef
|
||||
BOOT_MODULES_LIST := $(call SubstComma, $(BOOT_MODULES))
|
||||
PLATFORM_MODULES_LIST := $(call SubstComma, $(UPGRADEABLE_MODULES) $(AGGREGATOR_MODULES) $(OTHER_PLATFORM_MODULES))
|
||||
PLATFORM_MODULES_LIST := $(call SubstComma, $(PLATFORM_MODULES))
|
||||
|
||||
VARDEPS_VALUE := $(BOOT_MODULES_LIST) $(PLATFORM_MODULES_LIST)
|
||||
VARDEPS_FILE := $(call DependOnVariable, VARDEPS_VALUE)
|
||||
|
@ -27,5 +27,6 @@ include LauncherCommon.gmk
|
||||
|
||||
$(eval $(call SetupBuildLauncher, jjs, \
|
||||
MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \
|
||||
JAVA_ARGS := -addmods ALL-SYSTEM, \
|
||||
CFLAGS := -DENABLE_ARG_FILES, \
|
||||
))
|
||||
|
@ -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
|
||||
@ -36,7 +36,7 @@ import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import static java.io.ObjectStreamClass.processQueue;
|
||||
@ -212,20 +212,20 @@ public class ObjectInputStream
|
||||
/** marker for unshared objects in internal handle table */
|
||||
private static final Object unsharedMarker = new Object();
|
||||
|
||||
/** table mapping primitive type names to corresponding class objects */
|
||||
private static final HashMap<String, Class<?>> primClasses
|
||||
= new HashMap<>(8, 1.0F);
|
||||
static {
|
||||
primClasses.put("boolean", boolean.class);
|
||||
primClasses.put("byte", byte.class);
|
||||
primClasses.put("char", char.class);
|
||||
primClasses.put("short", short.class);
|
||||
primClasses.put("int", int.class);
|
||||
primClasses.put("long", long.class);
|
||||
primClasses.put("float", float.class);
|
||||
primClasses.put("double", double.class);
|
||||
primClasses.put("void", void.class);
|
||||
}
|
||||
/**
|
||||
* immutable table mapping primitive type names to corresponding
|
||||
* class objects
|
||||
*/
|
||||
private static final Map<String, Class<?>> primClasses =
|
||||
Map.of("boolean", boolean.class,
|
||||
"byte", byte.class,
|
||||
"char", char.class,
|
||||
"short", short.class,
|
||||
"int", int.class,
|
||||
"long", long.class,
|
||||
"float", float.class,
|
||||
"double", double.class,
|
||||
"void", void.class);
|
||||
|
||||
private static class Caches {
|
||||
/** cache of subclass security audit results */
|
||||
|
@ -108,11 +108,14 @@ public class MethodHandles {
|
||||
* <p>
|
||||
* For now, the {@linkplain Lookup#lookupClass lookup class} of this lookup
|
||||
* object is in an unnamed module.
|
||||
* Consequently, the lookup context of this lookup object will be the bootstrap
|
||||
* class loader, which means it cannot find user classes.
|
||||
*
|
||||
* <p style="font-size:smaller;">
|
||||
* <em>Discussion:</em>
|
||||
* The lookup class can be changed to any other class {@code C} using an expression of the form
|
||||
* {@link Lookup#in publicLookup().in(C.class)}.
|
||||
* but may change the lookup context by virtue of changing the class loader.
|
||||
* A public lookup object is always subject to
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
|
||||
* Also, it cannot access
|
||||
@ -677,6 +680,11 @@ public class MethodHandles {
|
||||
* then no members, not even public members, will be accessible.
|
||||
* (In all other cases, public members will continue to be accessible.)
|
||||
* </ul>
|
||||
* <p>
|
||||
* The resulting lookup's capabilities for loading classes
|
||||
* (used during {@link #findClass} invocations)
|
||||
* are determined by the lookup class' loader,
|
||||
* which may change due to this operation.
|
||||
*
|
||||
* @param requestedLookupClass the desired lookup class for the new lookup object
|
||||
* @return a lookup object which reports the desired lookup class
|
||||
@ -983,13 +991,17 @@ assertEquals("[x, y, z]", pb.command().toString());
|
||||
/**
|
||||
* Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
|
||||
* initializer of the class is not run.
|
||||
* <p>
|
||||
* The lookup context here is determined by the {@linkplain #lookupClass() lookup class}, its class
|
||||
* loader, and the {@linkplain #lookupModes() lookup modes}. In particular, the method first attempts to
|
||||
* load the requested class, and then determines whether the class is accessible to this lookup object.
|
||||
*
|
||||
* @param targetName the fully qualified name of the class to be looked up.
|
||||
* @return the requested class.
|
||||
* @exception SecurityException if a security manager is present and it
|
||||
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
|
||||
* @throws LinkageError if the linkage fails
|
||||
* @throws ClassNotFoundException if the class does not exist.
|
||||
* @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.
|
||||
* @throws IllegalAccessException if the class is not accessible, using the allowed access
|
||||
* modes.
|
||||
* @exception SecurityException if a security manager is present and it
|
||||
@ -1004,6 +1016,9 @@ assertEquals("[x, y, z]", pb.command().toString());
|
||||
/**
|
||||
* Determines if a class can be accessed from the lookup context defined by this {@code Lookup} object. The
|
||||
* static initializer of the class is not run.
|
||||
* <p>
|
||||
* The lookup context here is determined by the {@linkplain #lookupClass() lookup class} and the
|
||||
* {@linkplain #lookupModes() lookup modes}.
|
||||
*
|
||||
* @param targetClass the class to be access-checked
|
||||
*
|
||||
|
@ -1106,7 +1106,7 @@ public final class Instant
|
||||
* complete units between the two instants.
|
||||
* The {@code Temporal} passed to this method is converted to a
|
||||
* {@code Instant} using {@link #from(TemporalAccessor)}.
|
||||
* For example, the amount in days between two dates can be calculated
|
||||
* For example, the amount in seconds between two dates can be calculated
|
||||
* using {@code startInstant.until(endInstant, SECONDS)}.
|
||||
* <p>
|
||||
* There are two equivalent ways of using this method.
|
||||
|
@ -619,6 +619,9 @@ public final class DateTimeFormatter {
|
||||
* The returned formatter has a chronology of ISO set to ensure dates in
|
||||
* other calendar systems are correctly converted.
|
||||
* It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
|
||||
* The {@code FULL} and {@code LONG} styles typically require a time-zone.
|
||||
* When formatting using these styles, a {@code ZoneId} must be available,
|
||||
* either by using {@code ZonedDateTime} or {@link DateTimeFormatter#withZone}.
|
||||
*
|
||||
* @param timeStyle the formatter style to obtain, not null
|
||||
* @return the time formatter, not null
|
||||
@ -647,6 +650,9 @@ public final class DateTimeFormatter {
|
||||
* The returned formatter has a chronology of ISO set to ensure dates in
|
||||
* other calendar systems are correctly converted.
|
||||
* It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
|
||||
* The {@code FULL} and {@code LONG} styles typically require a time-zone.
|
||||
* When formatting using these styles, a {@code ZoneId} must be available,
|
||||
* either by using {@code ZonedDateTime} or {@link DateTimeFormatter#withZone}.
|
||||
*
|
||||
* @param dateTimeStyle the formatter style to obtain, not null
|
||||
* @return the date-time formatter, not null
|
||||
@ -675,6 +681,9 @@ public final class DateTimeFormatter {
|
||||
* The returned formatter has a chronology of ISO set to ensure dates in
|
||||
* other calendar systems are correctly converted.
|
||||
* It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
|
||||
* The {@code FULL} and {@code LONG} styles typically require a time-zone.
|
||||
* When formatting using these styles, a {@code ZoneId} must be available,
|
||||
* either by using {@code ZonedDateTime} or {@link DateTimeFormatter#withZone}.
|
||||
*
|
||||
* @param dateStyle the date formatter style to obtain, not null
|
||||
* @param timeStyle the time formatter style to obtain, not null
|
||||
@ -923,6 +932,7 @@ public final class DateTimeFormatter {
|
||||
* <li>The {@link #ISO_LOCAL_DATE_TIME}
|
||||
* <li>The {@link ZoneOffset#getId() offset ID}. If the offset has seconds then
|
||||
* they will be handled even though this is not part of the ISO-8601 standard.
|
||||
* The offset parsing is lenient, which allows the minutes and seconds to be optional.
|
||||
* Parsing is case insensitive.
|
||||
* </ul>
|
||||
* <p>
|
||||
@ -935,7 +945,9 @@ public final class DateTimeFormatter {
|
||||
ISO_OFFSET_DATE_TIME = new DateTimeFormatterBuilder()
|
||||
.parseCaseInsensitive()
|
||||
.append(ISO_LOCAL_DATE_TIME)
|
||||
.parseLenient()
|
||||
.appendOffsetId()
|
||||
.parseStrict()
|
||||
.toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
|
||||
}
|
||||
|
||||
@ -1160,6 +1172,7 @@ public final class DateTimeFormatter {
|
||||
* <li>If the offset is not available to format or parse then the format is complete.
|
||||
* <li>The {@link ZoneOffset#getId() offset ID} without colons. If the offset has
|
||||
* seconds then they will be handled even though this is not part of the ISO-8601 standard.
|
||||
* The offset parsing is lenient, which allows the minutes and seconds to be optional.
|
||||
* Parsing is case insensitive.
|
||||
* </ul>
|
||||
* <p>
|
||||
@ -1178,7 +1191,9 @@ public final class DateTimeFormatter {
|
||||
.appendValue(MONTH_OF_YEAR, 2)
|
||||
.appendValue(DAY_OF_MONTH, 2)
|
||||
.optionalStart()
|
||||
.parseLenient()
|
||||
.appendOffset("+HHMMss", "Z")
|
||||
.parseStrict()
|
||||
.toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
|
||||
}
|
||||
|
||||
|
@ -866,7 +866,9 @@ public final class DateTimeFormatterBuilder {
|
||||
* Appends the zone offset, such as '+01:00', to the formatter.
|
||||
* <p>
|
||||
* This appends an instruction to format/parse the offset ID to the builder.
|
||||
* This is equivalent to calling {@code appendOffset("+HH:MM:ss", "Z")}.
|
||||
* This is equivalent to calling {@code appendOffset("+HH:mm:ss", "Z")}.
|
||||
* See {@link #appendOffset(String, String)} for details on formatting
|
||||
* and parsing.
|
||||
*
|
||||
* @return this, for chaining, not null
|
||||
*/
|
||||
@ -886,9 +888,18 @@ public final class DateTimeFormatterBuilder {
|
||||
* If the offset cannot be obtained then an exception is thrown unless the
|
||||
* section of the formatter is optional.
|
||||
* <p>
|
||||
* During parsing, the offset is parsed using the format defined below.
|
||||
* If the offset cannot be parsed then an exception is thrown unless the
|
||||
* section of the formatter is optional.
|
||||
* When parsing in strict mode, the input must contain the mandatory
|
||||
* and optional elements are defined by the specified pattern.
|
||||
* If the offset cannot be parsed then an exception is thrown unless
|
||||
* the section of the formatter is optional.
|
||||
* <p>
|
||||
* When parsing in lenient mode, only the hours are mandatory - minutes
|
||||
* and seconds are optional. The colons are required if the specified
|
||||
* pattern contains a colon. If the specified pattern is "+HH", the
|
||||
* presence of colons is determined by whether the character after the
|
||||
* hour digits is a colon or not.
|
||||
* If the offset cannot be parsed then an exception is thrown unless
|
||||
* the section of the formatter is optional.
|
||||
* <p>
|
||||
* The format of the offset is controlled by a pattern which must be one
|
||||
* of the following:
|
||||
@ -902,6 +913,10 @@ public final class DateTimeFormatterBuilder {
|
||||
* <li>{@code +HH:MM:ss} - hour and minute, with second if non-zero, with colon
|
||||
* <li>{@code +HHMMSS} - hour, minute and second, no colon
|
||||
* <li>{@code +HH:MM:SS} - hour, minute and second, with colon
|
||||
* <li>{@code +HHmmss} - hour, with minute if non-zero or with minute and
|
||||
* second if non-zero, no colon
|
||||
* <li>{@code +HH:mm:ss} - hour, with minute if non-zero or with minute and
|
||||
* second if non-zero, with colon
|
||||
* </ul>
|
||||
* The "no offset" text controls what text is printed when the total amount of
|
||||
* the offset fields to be output is zero.
|
||||
@ -1256,6 +1271,9 @@ public final class DateTimeFormatterBuilder {
|
||||
* During formatting, the chronology is obtained from the temporal object
|
||||
* being formatted, which may have been overridden by
|
||||
* {@link DateTimeFormatter#withChronology(Chronology)}.
|
||||
* The {@code FULL} and {@code LONG} styles typically require a time-zone.
|
||||
* When formatting using these styles, a {@code ZoneId} must be available,
|
||||
* either by using {@code ZonedDateTime} or {@link DateTimeFormatter#withZone}.
|
||||
* <p>
|
||||
* During parsing, if a chronology has already been parsed, then it is used.
|
||||
* Otherwise the default from {@code DateTimeFormatter.withChronology(Chronology)}
|
||||
@ -3315,7 +3333,7 @@ public final class DateTimeFormatterBuilder {
|
||||
*/
|
||||
static final class OffsetIdPrinterParser implements DateTimePrinterParser {
|
||||
static final String[] PATTERNS = new String[] {
|
||||
"+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS",
|
||||
"+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS", "+HHmmss", "+HH:mm:ss",
|
||||
}; // order used in pattern builder
|
||||
static final OffsetIdPrinterParser INSTANCE_ID_Z = new OffsetIdPrinterParser("+HH:MM:ss", "Z");
|
||||
static final OffsetIdPrinterParser INSTANCE_ID_ZERO = new OffsetIdPrinterParser("+HH:MM:ss", "0");
|
||||
@ -3362,11 +3380,11 @@ public final class DateTimeFormatterBuilder {
|
||||
int output = absHours;
|
||||
buf.append(totalSecs < 0 ? "-" : "+")
|
||||
.append((char) (absHours / 10 + '0')).append((char) (absHours % 10 + '0'));
|
||||
if (type >= 3 || (type >= 1 && absMinutes > 0)) {
|
||||
if ((type >= 3 && type < 9) || (type >= 9 && absSeconds > 0) || (type >= 1 && absMinutes > 0)) {
|
||||
buf.append((type % 2) == 0 ? ":" : "")
|
||||
.append((char) (absMinutes / 10 + '0')).append((char) (absMinutes % 10 + '0'));
|
||||
output += absMinutes;
|
||||
if (type >= 7 || (type >= 5 && absSeconds > 0)) {
|
||||
if (type == 7 || type == 8 || (type >= 5 && absSeconds > 0)) {
|
||||
buf.append((type % 2) == 0 ? ":" : "")
|
||||
.append((char) (absSeconds / 10 + '0')).append((char) (absSeconds % 10 + '0'));
|
||||
output += absSeconds;
|
||||
@ -3384,6 +3402,15 @@ public final class DateTimeFormatterBuilder {
|
||||
public int parse(DateTimeParseContext context, CharSequence text, int position) {
|
||||
int length = text.length();
|
||||
int noOffsetLen = noOffsetText.length();
|
||||
int parseType = type;
|
||||
if (context.isStrict() == false) {
|
||||
if ((parseType > 0 && (parseType % 2) == 0) ||
|
||||
(parseType == 0 && length > position + 3 && text.charAt(position + 3) == ':')) {
|
||||
parseType = 10;
|
||||
} else {
|
||||
parseType = 9;
|
||||
}
|
||||
}
|
||||
if (noOffsetLen == 0) {
|
||||
if (position == length) {
|
||||
return context.setParsedField(OFFSET_SECONDS, 0, position, position);
|
||||
@ -3404,9 +3431,9 @@ public final class DateTimeFormatterBuilder {
|
||||
int negative = (sign == '-' ? -1 : 1);
|
||||
int[] array = new int[4];
|
||||
array[0] = position + 1;
|
||||
if ((parseNumber(array, 1, text, true) ||
|
||||
parseNumber(array, 2, text, type >=3) ||
|
||||
parseNumber(array, 3, text, false)) == false) {
|
||||
if ((parseNumber(array, 1, text, true, parseType) ||
|
||||
parseNumber(array, 2, text, parseType >= 3 && parseType < 9, parseType) ||
|
||||
parseNumber(array, 3, text, parseType == 7 || parseType == 8, parseType)) == false) {
|
||||
// success
|
||||
long offsetSecs = negative * (array[1] * 3600L + array[2] * 60L + array[3]);
|
||||
return context.setParsedField(OFFSET_SECONDS, offsetSecs, position, array[0]);
|
||||
@ -3414,7 +3441,7 @@ public final class DateTimeFormatterBuilder {
|
||||
}
|
||||
// handle special case of empty no offset text
|
||||
if (noOffsetLen == 0) {
|
||||
return context.setParsedField(OFFSET_SECONDS, 0, position, position + noOffsetLen);
|
||||
return context.setParsedField(OFFSET_SECONDS, 0, position, position);
|
||||
}
|
||||
return ~position;
|
||||
}
|
||||
@ -3426,14 +3453,15 @@ public final class DateTimeFormatterBuilder {
|
||||
* @param arrayIndex the index to parse the value into
|
||||
* @param parseText the offset ID, not null
|
||||
* @param required whether this number is required
|
||||
* @param parseType the offset pattern type
|
||||
* @return true if an error occurred
|
||||
*/
|
||||
private boolean parseNumber(int[] array, int arrayIndex, CharSequence parseText, boolean required) {
|
||||
if ((type + 3) / 2 < arrayIndex) {
|
||||
private boolean parseNumber(int[] array, int arrayIndex, CharSequence parseText, boolean required, int parseType) {
|
||||
if ((parseType + 3) / 2 < arrayIndex) {
|
||||
return false; // ignore seconds/minutes
|
||||
}
|
||||
int pos = array[0];
|
||||
if ((type % 2) == 0 && arrayIndex > 1) {
|
||||
if ((parseType % 2) == 0 && arrayIndex > 1) {
|
||||
if (pos + 1 > parseText.length() || parseText.charAt(pos) != ':') {
|
||||
return required;
|
||||
}
|
||||
|
@ -218,6 +218,13 @@ final class DateTimePrintContext {
|
||||
}
|
||||
return query.queryFrom(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return temporal +
|
||||
(effectiveChrono != null ? " with chronology " + effectiveChrono : "") +
|
||||
(effectiveZone != null ? " with zone " + effectiveZone : "");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -279,7 +286,8 @@ final class DateTimePrintContext {
|
||||
<R> R getValue(TemporalQuery<R> query) {
|
||||
R result = temporal.query(query);
|
||||
if (result == null && optional == 0) {
|
||||
throw new DateTimeException("Unable to extract value: " + temporal.getClass());
|
||||
throw new DateTimeException("Unable to extract " +
|
||||
query + " from temporal " + temporal);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -341,58 +341,118 @@ public final class TemporalQueries {
|
||||
/**
|
||||
* A strict query for the {@code ZoneId}.
|
||||
*/
|
||||
static final TemporalQuery<ZoneId> ZONE_ID = (temporal) ->
|
||||
temporal.query(TemporalQueries.ZONE_ID);
|
||||
static final TemporalQuery<ZoneId> ZONE_ID = new TemporalQuery<>() {
|
||||
@Override
|
||||
public ZoneId queryFrom(TemporalAccessor temporal) {
|
||||
return temporal.query(TemporalQueries.ZONE_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ZoneId";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A query for the {@code Chronology}.
|
||||
*/
|
||||
static final TemporalQuery<Chronology> CHRONO = (temporal) ->
|
||||
temporal.query(TemporalQueries.CHRONO);
|
||||
static final TemporalQuery<Chronology> CHRONO = new TemporalQuery<>() {
|
||||
@Override
|
||||
public Chronology queryFrom(TemporalAccessor temporal) {
|
||||
return temporal.query(TemporalQueries.CHRONO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Chronology";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A query for the smallest supported unit.
|
||||
*/
|
||||
static final TemporalQuery<TemporalUnit> PRECISION = (temporal) ->
|
||||
temporal.query(TemporalQueries.PRECISION);
|
||||
static final TemporalQuery<TemporalUnit> PRECISION = new TemporalQuery<>() {
|
||||
@Override
|
||||
public TemporalUnit queryFrom(TemporalAccessor temporal) {
|
||||
return temporal.query(TemporalQueries.PRECISION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Precision";
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* A query for {@code ZoneOffset} returning null if not found.
|
||||
*/
|
||||
static final TemporalQuery<ZoneOffset> OFFSET = (temporal) -> {
|
||||
if (temporal.isSupported(OFFSET_SECONDS)) {
|
||||
return ZoneOffset.ofTotalSeconds(temporal.get(OFFSET_SECONDS));
|
||||
static final TemporalQuery<ZoneOffset> OFFSET = new TemporalQuery<>() {
|
||||
@Override
|
||||
public ZoneOffset queryFrom(TemporalAccessor temporal) {
|
||||
if (temporal.isSupported(OFFSET_SECONDS)) {
|
||||
return ZoneOffset.ofTotalSeconds(temporal.get(OFFSET_SECONDS));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ZoneOffset";
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* A lenient query for the {@code ZoneId}, falling back to the {@code ZoneOffset}.
|
||||
*/
|
||||
static final TemporalQuery<ZoneId> ZONE = (temporal) -> {
|
||||
ZoneId zone = temporal.query(ZONE_ID);
|
||||
return (zone != null ? zone : temporal.query(OFFSET));
|
||||
static final TemporalQuery<ZoneId> ZONE = new TemporalQuery<>() {
|
||||
@Override
|
||||
public ZoneId queryFrom(TemporalAccessor temporal) {
|
||||
ZoneId zone = temporal.query(ZONE_ID);
|
||||
return (zone != null ? zone : temporal.query(OFFSET));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Zone";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A query for {@code LocalDate} returning null if not found.
|
||||
*/
|
||||
static final TemporalQuery<LocalDate> LOCAL_DATE = (temporal) -> {
|
||||
if (temporal.isSupported(EPOCH_DAY)) {
|
||||
return LocalDate.ofEpochDay(temporal.getLong(EPOCH_DAY));
|
||||
static final TemporalQuery<LocalDate> LOCAL_DATE = new TemporalQuery<>() {
|
||||
@Override
|
||||
public LocalDate queryFrom(TemporalAccessor temporal) {
|
||||
if (temporal.isSupported(EPOCH_DAY)) {
|
||||
return LocalDate.ofEpochDay(temporal.getLong(EPOCH_DAY));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LocalDate";
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* A query for {@code LocalTime} returning null if not found.
|
||||
*/
|
||||
static final TemporalQuery<LocalTime> LOCAL_TIME = (temporal) -> {
|
||||
if (temporal.isSupported(NANO_OF_DAY)) {
|
||||
return LocalTime.ofNanoOfDay(temporal.getLong(NANO_OF_DAY));
|
||||
static final TemporalQuery<LocalTime> LOCAL_TIME = new TemporalQuery<>() {
|
||||
@Override
|
||||
public LocalTime queryFrom(TemporalAccessor temporal) {
|
||||
if (temporal.isSupported(NANO_OF_DAY)) {
|
||||
return LocalTime.ofNanoOfDay(temporal.getLong(NANO_OF_DAY));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LocalTime";
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
@ -1281,8 +1281,74 @@ public class ArrayList<E> extends AbstractList<E>
|
||||
|
||||
public Spliterator<E> spliterator() {
|
||||
checkForComodification();
|
||||
return new ArrayListSpliterator<>(ArrayList.this, offset,
|
||||
offset + this.size, this.modCount);
|
||||
|
||||
return new Spliterator<>() {
|
||||
private int index = offset; // current index, modified on advance/split
|
||||
private int fence = -1; // -1 until used; then one past last index
|
||||
private int expectedModCount; // initialized when fence set
|
||||
|
||||
private int getFence() { // initialize fence to size on first use
|
||||
int hi; // (a specialized variant appears in method forEach)
|
||||
if ((hi = fence) < 0) {
|
||||
expectedModCount = modCount;
|
||||
hi = fence = offset + size;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
|
||||
public ArrayListSpliterator<E> trySplit() {
|
||||
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
|
||||
return (lo >= mid) ? null : // divide range in half unless too small
|
||||
new ArrayListSpliterator<>(ArrayList.this, lo, index = mid,
|
||||
expectedModCount);
|
||||
}
|
||||
|
||||
public boolean tryAdvance(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
int hi = getFence(), i = index;
|
||||
if (i < hi) {
|
||||
index = i + 1;
|
||||
@SuppressWarnings("unchecked") E e = (E)elementData[i];
|
||||
action.accept(e);
|
||||
if (ArrayList.this.modCount != expectedModCount)
|
||||
throw new ConcurrentModificationException();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
int i, hi, mc; // hoist accesses and checks from loop
|
||||
ArrayList<E> lst = ArrayList.this;
|
||||
Object[] a;
|
||||
if ((a = lst.elementData) != null) {
|
||||
if ((hi = fence) < 0) {
|
||||
mc = modCount;
|
||||
hi = offset + size;
|
||||
}
|
||||
else
|
||||
mc = expectedModCount;
|
||||
if ((i = index) >= 0 && (index = hi) <= a.length) {
|
||||
for (; i < hi; ++i) {
|
||||
@SuppressWarnings("unchecked") E e = (E) a[i];
|
||||
action.accept(e);
|
||||
}
|
||||
if (lst.modCount == mc)
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
public long estimateSize() {
|
||||
return (long) (getFence() - index);
|
||||
}
|
||||
|
||||
public int characteristics() {
|
||||
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -718,7 +718,7 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shallow copy of this enum map. (The values themselves
|
||||
* Returns a shallow copy of this enum map. The values themselves
|
||||
* are not cloned.
|
||||
*
|
||||
* @return a shallow copy of this enum map
|
||||
|
@ -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
|
||||
@ -656,8 +656,9 @@ public final class Collectors {
|
||||
*/
|
||||
return new CollectorImpl<>(
|
||||
() -> new double[3],
|
||||
(a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t));
|
||||
a[2] += mapper.applyAsDouble(t);},
|
||||
(a, t) -> { double val = mapper.applyAsDouble(t);
|
||||
sumWithCompensation(a, val);
|
||||
a[2] += val;},
|
||||
(a, b) -> { sumWithCompensation(a, b[0]);
|
||||
a[2] += b[2];
|
||||
return sumWithCompensation(a, b[1]); },
|
||||
@ -768,7 +769,7 @@ public final class Collectors {
|
||||
*/
|
||||
return new CollectorImpl<>(
|
||||
() -> new double[4],
|
||||
(a, t) -> { sumWithCompensation(a, mapper.applyAsDouble(t)); a[2]++; a[3]+= mapper.applyAsDouble(t);},
|
||||
(a, t) -> { double val = mapper.applyAsDouble(t); sumWithCompensation(a, val); a[2]++; a[3]+= val;},
|
||||
(a, b) -> { sumWithCompensation(a, b[0]); sumWithCompensation(a, b[1]); a[2] += b[2]; a[3] += b[3]; return a; },
|
||||
a -> (a[2] == 0) ? 0.0d : (computeFinalSum(a) / a[2]),
|
||||
CH_NOID);
|
||||
|
@ -98,7 +98,7 @@ abstract class PipelineHelper<P_OUT> {
|
||||
* @implSpec
|
||||
* The implementation behaves as if:
|
||||
* <pre>{@code
|
||||
* intoWrapped(wrapSink(sink), spliterator);
|
||||
* copyInto(wrapSink(sink), spliterator);
|
||||
* }</pre>
|
||||
*
|
||||
* @param sink the {@code Sink} to receive the results
|
||||
|
@ -40,6 +40,15 @@ import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
* Although the class and all methods are public, use of this class is
|
||||
* limited because only trusted code can obtain instances of it.
|
||||
*
|
||||
* <em>Note:</em> It is the resposibility of the caller to make sure
|
||||
* arguments are checked before methods of this class are
|
||||
* called. While some rudimentary checks are performed on the input,
|
||||
* the checks are best effort and when performance is an overriding
|
||||
* priority, as when methods of this class are optimized by the
|
||||
* runtime compiler, some or all checks (if any) may be elided. Hence,
|
||||
* the caller must not rely on the checks and corresponding
|
||||
* exceptions!
|
||||
*
|
||||
* @author John R. Rose
|
||||
* @see #getUnsafe
|
||||
*/
|
||||
@ -358,6 +367,169 @@ public final class Unsafe {
|
||||
@HotSpotIntrinsicCandidate
|
||||
public native void putAddress(long address, long x);
|
||||
|
||||
|
||||
|
||||
/// helper methods for validating various types of objects/values
|
||||
|
||||
/**
|
||||
* Create an exception reflecting that some of the input was invalid
|
||||
*
|
||||
* <em>Note:</em> It is the resposibility of the caller to make
|
||||
* sure arguments are checked before the methods are called. While
|
||||
* some rudimentary checks are performed on the input, the checks
|
||||
* are best effort and when performance is an overriding priority,
|
||||
* as when methods of this class are optimized by the runtime
|
||||
* compiler, some or all checks (if any) may be elided. Hence, the
|
||||
* caller must not rely on the checks and corresponding
|
||||
* exceptions!
|
||||
*
|
||||
* @return an exception object
|
||||
*/
|
||||
private RuntimeException invalidInput() {
|
||||
return new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a value is 32-bit clean (32 MSB are all zero)
|
||||
*
|
||||
* @param value the 64-bit value to check
|
||||
*
|
||||
* @return true if the value is 32-bit clean
|
||||
*/
|
||||
private boolean is32BitClean(long value) {
|
||||
return value >>> 32 == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the validity of a size (the equivalent of a size_t)
|
||||
*
|
||||
* @throws RuntimeException if the size is invalid
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*/
|
||||
private void checkSize(long size) {
|
||||
if (ADDRESS_SIZE == 4) {
|
||||
// Note: this will also check for negative sizes
|
||||
if (!is32BitClean(size)) {
|
||||
throw invalidInput();
|
||||
}
|
||||
} else if (size < 0) {
|
||||
throw invalidInput();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the validity of a native address (the equivalent of void*)
|
||||
*
|
||||
* @throws RuntimeException if the address is invalid
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*/
|
||||
private void checkNativeAddress(long address) {
|
||||
if (ADDRESS_SIZE == 4) {
|
||||
// Accept both zero and sign extended pointers. A valid
|
||||
// pointer will, after the +1 below, either have produced
|
||||
// the value 0x0 or 0x1. Masking off the low bit allows
|
||||
// for testing against 0.
|
||||
if ((((address >> 32) + 1) & ~1) != 0) {
|
||||
throw invalidInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the validity of an offset, relative to a base object
|
||||
*
|
||||
* @param o the base object
|
||||
* @param offset the offset to check
|
||||
*
|
||||
* @throws RuntimeException if the size is invalid
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*/
|
||||
private void checkOffset(Object o, long offset) {
|
||||
if (ADDRESS_SIZE == 4) {
|
||||
// Note: this will also check for negative offsets
|
||||
if (!is32BitClean(offset)) {
|
||||
throw invalidInput();
|
||||
}
|
||||
} else if (offset < 0) {
|
||||
throw invalidInput();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the validity of a double-register pointer
|
||||
*
|
||||
* Note: This code deliberately does *not* check for NPE for (at
|
||||
* least) three reasons:
|
||||
*
|
||||
* 1) NPE is not just NULL/0 - there is a range of values all
|
||||
* resulting in an NPE, which is not trivial to check for
|
||||
*
|
||||
* 2) It is the responsibility of the callers of Unsafe methods
|
||||
* to verify the input, so throwing an exception here is not really
|
||||
* useful - passing in a NULL pointer is a critical error and the
|
||||
* must not expect an exception to be thrown anyway.
|
||||
*
|
||||
* 3) the actual operations will detect NULL pointers anyway by
|
||||
* means of traps and signals (like SIGSEGV).
|
||||
*
|
||||
* @param o Java heap object, or null
|
||||
* @param offset indication of where the variable resides in a Java heap
|
||||
* object, if any, else a memory address locating the variable
|
||||
* statically
|
||||
*
|
||||
* @throws RuntimeException if the pointer is invalid
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*/
|
||||
private void checkPointer(Object o, long offset) {
|
||||
if (o == null) {
|
||||
checkNativeAddress(offset);
|
||||
} else {
|
||||
checkOffset(o, offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a type is a primitive array type
|
||||
*
|
||||
* @param c the type to check
|
||||
*
|
||||
* @return true if the type is a primitive array type
|
||||
*/
|
||||
private void checkPrimitiveArray(Class<?> c) {
|
||||
Class<?> componentType = c.getComponentType();
|
||||
if (componentType == null || !componentType.isPrimitive()) {
|
||||
throw invalidInput();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a pointer is a valid primitive array type pointer
|
||||
*
|
||||
* Note: pointers off-heap are considered to be primitive arrays
|
||||
*
|
||||
* @throws RuntimeException if the pointer is invalid
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*/
|
||||
private void checkPrimitivePointer(Object o, long offset) {
|
||||
checkPointer(o, offset);
|
||||
|
||||
if (o != null) {
|
||||
// If on heap, it it must be a primitive array
|
||||
checkPrimitiveArray(o.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// wrappers for malloc, realloc, free:
|
||||
|
||||
/**
|
||||
@ -367,7 +539,16 @@ public final class Unsafe {
|
||||
* aligned for all value types. Dispose of this memory by calling {@link
|
||||
* #freeMemory}, or resize it with {@link #reallocateMemory}.
|
||||
*
|
||||
* @throws IllegalArgumentException if the size is negative or too large
|
||||
* <em>Note:</em> It is the resposibility of the caller to make
|
||||
* sure arguments are checked before the methods are called. While
|
||||
* some rudimentary checks are performed on the input, the checks
|
||||
* are best effort and when performance is an overriding priority,
|
||||
* as when methods of this class are optimized by the runtime
|
||||
* compiler, some or all checks (if any) may be elided. Hence, the
|
||||
* caller must not rely on the checks and corresponding
|
||||
* exceptions!
|
||||
*
|
||||
* @throws RuntimeException if the size is negative or too large
|
||||
* for the native size_t type
|
||||
*
|
||||
* @throws OutOfMemoryError if the allocation is refused by the system
|
||||
@ -375,7 +556,32 @@ public final class Unsafe {
|
||||
* @see #getByte(long)
|
||||
* @see #putByte(long, byte)
|
||||
*/
|
||||
public native long allocateMemory(long bytes);
|
||||
public long allocateMemory(long bytes) {
|
||||
allocateMemoryChecks(bytes);
|
||||
|
||||
if (bytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long p = allocateMemory0(bytes);
|
||||
if (p == 0) {
|
||||
throw new OutOfMemoryError();
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the arguments to allocateMemory
|
||||
*
|
||||
* @throws RuntimeException if the arguments are invalid
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*/
|
||||
private void allocateMemoryChecks(long bytes) {
|
||||
checkSize(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes a new block of native memory, to the given size in bytes. The
|
||||
@ -387,14 +593,50 @@ public final class Unsafe {
|
||||
* #reallocateMemory}. The address passed to this method may be null, in
|
||||
* which case an allocation will be performed.
|
||||
*
|
||||
* @throws IllegalArgumentException if the size is negative or too large
|
||||
* <em>Note:</em> It is the resposibility of the caller to make
|
||||
* sure arguments are checked before the methods are called. While
|
||||
* some rudimentary checks are performed on the input, the checks
|
||||
* are best effort and when performance is an overriding priority,
|
||||
* as when methods of this class are optimized by the runtime
|
||||
* compiler, some or all checks (if any) may be elided. Hence, the
|
||||
* caller must not rely on the checks and corresponding
|
||||
* exceptions!
|
||||
*
|
||||
* @throws RuntimeException if the size is negative or too large
|
||||
* for the native size_t type
|
||||
*
|
||||
* @throws OutOfMemoryError if the allocation is refused by the system
|
||||
*
|
||||
* @see #allocateMemory
|
||||
*/
|
||||
public native long reallocateMemory(long address, long bytes);
|
||||
public long reallocateMemory(long address, long bytes) {
|
||||
reallocateMemoryChecks(address, bytes);
|
||||
|
||||
if (bytes == 0) {
|
||||
freeMemory(address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
long p = (address == 0) ? allocateMemory0(bytes) : reallocateMemory0(address, bytes);
|
||||
if (p == 0) {
|
||||
throw new OutOfMemoryError();
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the arguments to reallocateMemory
|
||||
*
|
||||
* @throws RuntimeException if the arguments are invalid
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*/
|
||||
private void reallocateMemoryChecks(long address, long bytes) {
|
||||
checkPointer(null, address);
|
||||
checkSize(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all bytes in a given block of memory to a fixed value
|
||||
@ -411,9 +653,28 @@ public final class Unsafe {
|
||||
* If the effective address and length are (resp.) even modulo 4 or 2,
|
||||
* the stores take place in units of 'int' or 'short'.
|
||||
*
|
||||
* <em>Note:</em> It is the resposibility of the caller to make
|
||||
* sure arguments are checked before the methods are called. While
|
||||
* some rudimentary checks are performed on the input, the checks
|
||||
* are best effort and when performance is an overriding priority,
|
||||
* as when methods of this class are optimized by the runtime
|
||||
* compiler, some or all checks (if any) may be elided. Hence, the
|
||||
* caller must not rely on the checks and corresponding
|
||||
* exceptions!
|
||||
*
|
||||
* @throws RuntimeException if any of the arguments is invalid
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public native void setMemory(Object o, long offset, long bytes, byte value);
|
||||
public void setMemory(Object o, long offset, long bytes, byte value) {
|
||||
setMemoryChecks(o, offset, bytes, value);
|
||||
|
||||
if (bytes == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
setMemory0(o, offset, bytes, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all bytes in a given block of memory to a fixed value
|
||||
@ -426,6 +687,19 @@ public final class Unsafe {
|
||||
setMemory(null, address, bytes, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the arguments to setMemory
|
||||
*
|
||||
* @throws RuntimeException if the arguments are invalid
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*/
|
||||
private void setMemoryChecks(Object o, long offset, long bytes, byte value) {
|
||||
checkPrimitivePointer(o, offset);
|
||||
checkSize(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all bytes in a given block of memory to a copy of another
|
||||
* block.
|
||||
@ -441,12 +715,31 @@ public final class Unsafe {
|
||||
* If the effective addresses and length are (resp.) even modulo 4 or 2,
|
||||
* the transfer takes place in units of 'int' or 'short'.
|
||||
*
|
||||
* <em>Note:</em> It is the resposibility of the caller to make
|
||||
* sure arguments are checked before the methods are called. While
|
||||
* some rudimentary checks are performed on the input, the checks
|
||||
* are best effort and when performance is an overriding priority,
|
||||
* as when methods of this class are optimized by the runtime
|
||||
* compiler, some or all checks (if any) may be elided. Hence, the
|
||||
* caller must not rely on the checks and corresponding
|
||||
* exceptions!
|
||||
*
|
||||
* @throws RuntimeException if any of the arguments is invalid
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
@HotSpotIntrinsicCandidate
|
||||
public native void copyMemory(Object srcBase, long srcOffset,
|
||||
Object destBase, long destOffset,
|
||||
long bytes);
|
||||
public void copyMemory(Object srcBase, long srcOffset,
|
||||
Object destBase, long destOffset,
|
||||
long bytes) {
|
||||
copyMemoryChecks(srcBase, srcOffset, destBase, destOffset, bytes);
|
||||
|
||||
if (bytes == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
copyMemory0(srcBase, srcOffset, destBase, destOffset, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all bytes in a given block of memory to a copy of another
|
||||
* block. This provides a <em>single-register</em> addressing mode,
|
||||
@ -458,15 +751,22 @@ public final class Unsafe {
|
||||
copyMemory(null, srcAddress, null, destAddress, bytes);
|
||||
}
|
||||
|
||||
private boolean isPrimitiveArray(Class<?> c) {
|
||||
Class<?> componentType = c.getComponentType();
|
||||
return componentType != null && componentType.isPrimitive();
|
||||
/**
|
||||
* Validate the arguments to copyMemory
|
||||
*
|
||||
* @throws RuntimeException if any of the arguments is invalid
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*/
|
||||
private void copyMemoryChecks(Object srcBase, long srcOffset,
|
||||
Object destBase, long destOffset,
|
||||
long bytes) {
|
||||
checkSize(bytes);
|
||||
checkPrimitivePointer(srcBase, srcOffset);
|
||||
checkPrimitivePointer(destBase, destOffset);
|
||||
}
|
||||
|
||||
private native void copySwapMemory0(Object srcBase, long srcOffset,
|
||||
Object destBase, long destOffset,
|
||||
long bytes, long elemSize);
|
||||
|
||||
/**
|
||||
* Copies all elements from one block of memory to another block,
|
||||
* *unconditionally* byte swapping the elements on the fly.
|
||||
@ -476,39 +776,23 @@ public final class Unsafe {
|
||||
* as discussed in {@link #getInt(Object,long)}. When the object reference is null,
|
||||
* the offset supplies an absolute base address.
|
||||
*
|
||||
* <em>Note:</em> It is the resposibility of the caller to make
|
||||
* sure arguments are checked before the methods are called. While
|
||||
* some rudimentary checks are performed on the input, the checks
|
||||
* are best effort and when performance is an overriding priority,
|
||||
* as when methods of this class are optimized by the runtime
|
||||
* compiler, some or all checks (if any) may be elided. Hence, the
|
||||
* caller must not rely on the checks and corresponding
|
||||
* exceptions!
|
||||
*
|
||||
* @throws RuntimeException if any of the arguments is invalid
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
public void copySwapMemory(Object srcBase, long srcOffset,
|
||||
Object destBase, long destOffset,
|
||||
long bytes, long elemSize) {
|
||||
if (bytes < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (elemSize != 2 && elemSize != 4 && elemSize != 8) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (bytes % elemSize != 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if ((srcBase == null && srcOffset == 0) ||
|
||||
(destBase == null && destOffset == 0)) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
// Must be off-heap, or primitive heap arrays
|
||||
if (srcBase != null && (srcOffset < 0 || !isPrimitiveArray(srcBase.getClass()))) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (destBase != null && (destOffset < 0 || !isPrimitiveArray(destBase.getClass()))) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
// Sanity check size and offsets on 32-bit platforms. Most
|
||||
// significant 32 bits must be zero.
|
||||
if (ADDRESS_SIZE == 4 &&
|
||||
(bytes >>> 32 != 0 || srcOffset >>> 32 != 0 || destOffset >>> 32 != 0)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
copySwapMemoryChecks(srcBase, srcOffset, destBase, destOffset, bytes, elemSize);
|
||||
|
||||
if (bytes == 0) {
|
||||
return;
|
||||
@ -517,6 +801,22 @@ public final class Unsafe {
|
||||
copySwapMemory0(srcBase, srcOffset, destBase, destOffset, bytes, elemSize);
|
||||
}
|
||||
|
||||
private void copySwapMemoryChecks(Object srcBase, long srcOffset,
|
||||
Object destBase, long destOffset,
|
||||
long bytes, long elemSize) {
|
||||
checkSize(bytes);
|
||||
|
||||
if (elemSize != 2 && elemSize != 4 && elemSize != 8) {
|
||||
throw invalidInput();
|
||||
}
|
||||
if (bytes % elemSize != 0) {
|
||||
throw invalidInput();
|
||||
}
|
||||
|
||||
checkPrimitivePointer(srcBase, srcOffset);
|
||||
checkPrimitivePointer(destBase, destOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies all elements from one block of memory to another block, byte swapping the
|
||||
* elements on the fly.
|
||||
@ -535,9 +835,40 @@ public final class Unsafe {
|
||||
* #allocateMemory} or {@link #reallocateMemory}. The address passed to
|
||||
* this method may be null, in which case no action is taken.
|
||||
*
|
||||
* <em>Note:</em> It is the resposibility of the caller to make
|
||||
* sure arguments are checked before the methods are called. While
|
||||
* some rudimentary checks are performed on the input, the checks
|
||||
* are best effort and when performance is an overriding priority,
|
||||
* as when methods of this class are optimized by the runtime
|
||||
* compiler, some or all checks (if any) may be elided. Hence, the
|
||||
* caller must not rely on the checks and corresponding
|
||||
* exceptions!
|
||||
*
|
||||
* @throws RuntimeException if any of the arguments is invalid
|
||||
*
|
||||
* @see #allocateMemory
|
||||
*/
|
||||
public native void freeMemory(long address);
|
||||
public void freeMemory(long address) {
|
||||
freeMemoryChecks(address);
|
||||
|
||||
if (address == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
freeMemory0(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the arguments to freeMemory
|
||||
*
|
||||
* @throws RuntimeException if the arguments are invalid
|
||||
* (<em>Note:</em> after optimization, invalid inputs may
|
||||
* go undetected, which will lead to unpredictable
|
||||
* behavior)
|
||||
*/
|
||||
private void freeMemoryChecks(long address) {
|
||||
checkPointer(null, address);
|
||||
}
|
||||
|
||||
/// random queries
|
||||
|
||||
@ -546,7 +877,7 @@ public final class Unsafe {
|
||||
* {@link #staticFieldOffset}, {@link #objectFieldOffset},
|
||||
* or {@link #arrayBaseOffset}.
|
||||
*/
|
||||
public static final int INVALID_FIELD_OFFSET = -1;
|
||||
public static final int INVALID_FIELD_OFFSET = -1;
|
||||
|
||||
/**
|
||||
* Reports the location of a given field in the storage allocation of its
|
||||
@ -566,7 +897,13 @@ public final class Unsafe {
|
||||
* must preserve all bits of static field offsets.
|
||||
* @see #getInt(Object, long)
|
||||
*/
|
||||
public native long objectFieldOffset(Field f);
|
||||
public long objectFieldOffset(Field f) {
|
||||
if (f == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
return objectFieldOffset0(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the location of a given static field, in conjunction with {@link
|
||||
@ -585,7 +922,13 @@ public final class Unsafe {
|
||||
* this method reports its result as a long value.
|
||||
* @see #getInt(Object, long)
|
||||
*/
|
||||
public native long staticFieldOffset(Field f);
|
||||
public long staticFieldOffset(Field f) {
|
||||
if (f == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
return staticFieldOffset0(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the location of a given static field, in conjunction with {@link
|
||||
@ -597,7 +940,13 @@ public final class Unsafe {
|
||||
* not be used in any way except as argument to the get and put routines in
|
||||
* this class.
|
||||
*/
|
||||
public native Object staticFieldBase(Field f);
|
||||
public Object staticFieldBase(Field f) {
|
||||
if (f == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
return staticFieldBase0(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if the given class may need to be initialized. This is often
|
||||
@ -605,14 +954,26 @@ public final class Unsafe {
|
||||
* class.
|
||||
* @return false only if a call to {@code ensureClassInitialized} would have no effect
|
||||
*/
|
||||
public native boolean shouldBeInitialized(Class<?> c);
|
||||
public boolean shouldBeInitialized(Class<?> c) {
|
||||
if (c == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
return shouldBeInitialized0(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the given class has been initialized. This is often
|
||||
* needed in conjunction with obtaining the static field base of a
|
||||
* class.
|
||||
*/
|
||||
public native void ensureClassInitialized(Class<?> c);
|
||||
public void ensureClassInitialized(Class<?> c) {
|
||||
if (c == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
ensureClassInitialized0(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the offset of the first element in the storage allocation of a
|
||||
@ -624,7 +985,14 @@ public final class Unsafe {
|
||||
* @see #getInt(Object, long)
|
||||
* @see #putInt(Object, long, int)
|
||||
*/
|
||||
public native int arrayBaseOffset(Class<?> arrayClass);
|
||||
public int arrayBaseOffset(Class<?> arrayClass) {
|
||||
if (arrayClass == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
return arrayBaseOffset0(arrayClass);
|
||||
}
|
||||
|
||||
|
||||
/** The value of {@code arrayBaseOffset(boolean[].class)} */
|
||||
public static final int ARRAY_BOOLEAN_BASE_OFFSET
|
||||
@ -673,7 +1041,14 @@ public final class Unsafe {
|
||||
* @see #getInt(Object, long)
|
||||
* @see #putInt(Object, long, int)
|
||||
*/
|
||||
public native int arrayIndexScale(Class<?> arrayClass);
|
||||
public int arrayIndexScale(Class<?> arrayClass) {
|
||||
if (arrayClass == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
return arrayIndexScale0(arrayClass);
|
||||
}
|
||||
|
||||
|
||||
/** The value of {@code arrayIndexScale(boolean[].class)} */
|
||||
public static final int ARRAY_BOOLEAN_INDEX_SCALE
|
||||
@ -717,10 +1092,12 @@ public final class Unsafe {
|
||||
* other primitive types (as stored in native memory blocks) is determined
|
||||
* fully by their information content.
|
||||
*/
|
||||
public native int addressSize();
|
||||
public int addressSize() {
|
||||
return ADDRESS_SIZE;
|
||||
}
|
||||
|
||||
/** The value of {@code addressSize()} */
|
||||
public static final int ADDRESS_SIZE = theUnsafe.addressSize();
|
||||
public static final int ADDRESS_SIZE = theUnsafe.addressSize0();
|
||||
|
||||
/**
|
||||
* Reports the size in bytes of a native memory page (whatever that is).
|
||||
@ -735,9 +1112,22 @@ public final class Unsafe {
|
||||
* Tells the VM to define a class, without security checks. By default, the
|
||||
* class loader and protection domain come from the caller's class.
|
||||
*/
|
||||
public native Class<?> defineClass(String name, byte[] b, int off, int len,
|
||||
ClassLoader loader,
|
||||
ProtectionDomain protectionDomain);
|
||||
public Class<?> defineClass(String name, byte[] b, int off, int len,
|
||||
ClassLoader loader,
|
||||
ProtectionDomain protectionDomain) {
|
||||
if (b == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (len < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
return defineClass0(name, b, off, len, loader, protectionDomain);
|
||||
}
|
||||
|
||||
public native Class<?> defineClass0(String name, byte[] b, int off, int len,
|
||||
ClassLoader loader,
|
||||
ProtectionDomain protectionDomain);
|
||||
|
||||
/**
|
||||
* Defines a class but does not make it known to the class loader or system dictionary.
|
||||
@ -755,7 +1145,13 @@ public final class Unsafe {
|
||||
* @param data bytes of a class file
|
||||
* @param cpPatches where non-null entries exist, they replace corresponding CP entries in data
|
||||
*/
|
||||
public native Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches);
|
||||
public Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches) {
|
||||
if (hostClass == null || data == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
return defineAnonymousClass0(hostClass, data, cpPatches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates an instance but does not run any constructor.
|
||||
@ -765,6 +1161,59 @@ public final class Unsafe {
|
||||
public native Object allocateInstance(Class<?> cls)
|
||||
throws InstantiationException;
|
||||
|
||||
/**
|
||||
* Allocates an array of a given type, but does not do zeroing.
|
||||
* <p>
|
||||
* This method should only be used in the very rare cases where a high-performance code
|
||||
* overwrites the destination array completely, and compilers cannot assist in zeroing elimination.
|
||||
* In an overwhelming majority of cases, a normal Java allocation should be used instead.
|
||||
* <p>
|
||||
* Users of this method are <b>required</b> to overwrite the initial (garbage) array contents
|
||||
* before allowing untrusted code, or code in other threads, to observe the reference
|
||||
* to the newly allocated array. In addition, the publication of the array reference must be
|
||||
* safe according to the Java Memory Model requirements.
|
||||
* <p>
|
||||
* The safest approach to deal with an uninitialized array is to keep the reference to it in local
|
||||
* variable at least until the initialization is complete, and then publish it <b>once</b>, either
|
||||
* by writing it to a <em>volatile</em> field, or storing it into a <em>final</em> field in constructor,
|
||||
* or issuing a {@link #storeFence} before publishing the reference.
|
||||
* <p>
|
||||
* @implnote This method can only allocate primitive arrays, to avoid garbage reference
|
||||
* elements that could break heap integrity.
|
||||
*
|
||||
* @param componentType array component type to allocate
|
||||
* @param length array size to allocate
|
||||
* @throws IllegalArgumentException if component type is null, or not a primitive class;
|
||||
* or the length is negative
|
||||
*/
|
||||
public Object allocateUninitializedArray(Class<?> componentType, int length) {
|
||||
if (componentType == null) {
|
||||
throw new IllegalArgumentException("Component type is null");
|
||||
}
|
||||
if (!componentType.isPrimitive()) {
|
||||
throw new IllegalArgumentException("Component type is not primitive");
|
||||
}
|
||||
if (length < 0) {
|
||||
throw new IllegalArgumentException("Negative length");
|
||||
}
|
||||
return allocateUninitializedArray0(componentType, length);
|
||||
}
|
||||
|
||||
@HotSpotIntrinsicCandidate
|
||||
private Object allocateUninitializedArray0(Class<?> componentType, int length) {
|
||||
// These fallbacks provide zeroed arrays, but intrinsic is not required to
|
||||
// return the zeroed arrays.
|
||||
if (componentType == byte.class) return new byte[length];
|
||||
if (componentType == boolean.class) return new boolean[length];
|
||||
if (componentType == short.class) return new short[length];
|
||||
if (componentType == char.class) return new char[length];
|
||||
if (componentType == int.class) return new int[length];
|
||||
if (componentType == float.class) return new float[length];
|
||||
if (componentType == long.class) return new long[length];
|
||||
if (componentType == double.class) return new double[length];
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Throws the exception without telling the verifier. */
|
||||
public native void throwException(Throwable ee);
|
||||
|
||||
@ -1290,7 +1739,13 @@ public final class Unsafe {
|
||||
* @return the number of samples actually retrieved; or -1
|
||||
* if the load average is unobtainable.
|
||||
*/
|
||||
public native int getLoadAverage(double[] loadavg, int nelems);
|
||||
public int getLoadAverage(double[] loadavg, int nelems) {
|
||||
if (nelems < 0 || nelems > 3 || nelems > loadavg.length) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
return getLoadAverage0(loadavg, nelems);
|
||||
}
|
||||
|
||||
// The following contain CAS-based Java implementations used on
|
||||
// platforms not supporting native instructions
|
||||
@ -1718,9 +2173,6 @@ public final class Unsafe {
|
||||
}
|
||||
|
||||
// JVM interface methods
|
||||
private native boolean unalignedAccess0();
|
||||
private native boolean isBigEndian0();
|
||||
|
||||
// BE is true iff the native endianness of this platform is big.
|
||||
private static final boolean BE = theUnsafe.isBigEndian0();
|
||||
|
||||
@ -1820,4 +2272,26 @@ public final class Unsafe {
|
||||
private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n) ; }
|
||||
private static int convEndian(boolean big, int n) { return big == BE ? n : Integer.reverseBytes(n) ; }
|
||||
private static long convEndian(boolean big, long n) { return big == BE ? n : Long.reverseBytes(n) ; }
|
||||
|
||||
|
||||
|
||||
private native long allocateMemory0(long bytes);
|
||||
private native long reallocateMemory0(long address, long bytes);
|
||||
private native void freeMemory0(long address);
|
||||
private native void setMemory0(Object o, long offset, long bytes, byte value);
|
||||
@HotSpotIntrinsicCandidate
|
||||
private native void copyMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
|
||||
private native void copySwapMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize);
|
||||
private native long objectFieldOffset0(Field f);
|
||||
private native long staticFieldOffset0(Field f);
|
||||
private native Object staticFieldBase0(Field f);
|
||||
private native boolean shouldBeInitialized0(Class<?> c);
|
||||
private native void ensureClassInitialized0(Class<?> c);
|
||||
private native int arrayBaseOffset0(Class<?> arrayClass);
|
||||
private native int arrayIndexScale0(Class<?> arrayClass);
|
||||
private native int addressSize0();
|
||||
private native Class<?> defineAnonymousClass0(Class<?> hostClass, byte[] data, Object[] cpPatches);
|
||||
private native int getLoadAverage0(double[] loadavg, int nelems);
|
||||
private native boolean unalignedAccess0();
|
||||
private native boolean isBigEndian0();
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ public class ClassReader {
|
||||
public ClassReader(final byte[] b, final int off, final int len) {
|
||||
this.b = b;
|
||||
// checks the class version
|
||||
if (readShort(off + 6) > Opcodes.V1_8) {
|
||||
if (readShort(off + 6) > Opcodes.V1_9) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
// parses the constant pool
|
||||
@ -1199,7 +1199,14 @@ public class ClassReader {
|
||||
if (labels[label] == null) {
|
||||
readLabel(label, labels).status |= Label.DEBUG;
|
||||
}
|
||||
labels[label].line = readUnsignedShort(v + 12);
|
||||
Label l = labels[label];
|
||||
while (l.line > 0) {
|
||||
if (l.next == null) {
|
||||
l.next = new Label();
|
||||
}
|
||||
l = l.next;
|
||||
}
|
||||
l.line = readUnsignedShort(v + 12);
|
||||
v += 4;
|
||||
}
|
||||
}
|
||||
@ -1314,9 +1321,15 @@ public class ClassReader {
|
||||
// visits the label and line number for this offset, if any
|
||||
Label l = labels[offset];
|
||||
if (l != null) {
|
||||
Label next = l.next;
|
||||
l.next = null;
|
||||
mv.visitLabel(l);
|
||||
if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) {
|
||||
mv.visitLineNumber(l.line, l);
|
||||
while (next != null) {
|
||||
mv.visitLineNumber(next.line, l);
|
||||
next = next.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1857,8 +1870,7 @@ public class ClassReader {
|
||||
v += 2;
|
||||
break;
|
||||
case 'B': // pointer to CONSTANT_Byte
|
||||
av.visit(name,
|
||||
(byte) readInt(items[readUnsignedShort(v)]));
|
||||
av.visit(name, (byte) readInt(items[readUnsignedShort(v)]));
|
||||
v += 2;
|
||||
break;
|
||||
case 'Z': // pointer to CONSTANT_Boolean
|
||||
@ -1868,13 +1880,11 @@ public class ClassReader {
|
||||
v += 2;
|
||||
break;
|
||||
case 'S': // pointer to CONSTANT_Short
|
||||
av.visit(name,
|
||||
(short) readInt(items[readUnsignedShort(v)]));
|
||||
av.visit(name, (short) readInt(items[readUnsignedShort(v)]));
|
||||
v += 2;
|
||||
break;
|
||||
case 'C': // pointer to CONSTANT_Char
|
||||
av.visit(name,
|
||||
(char) readInt(items[readUnsignedShort(v)]));
|
||||
av.visit(name, (char) readInt(items[readUnsignedShort(v)]));
|
||||
v += 2;
|
||||
break;
|
||||
case 's': // pointer to CONSTANT_Utf8
|
||||
@ -2515,11 +2525,12 @@ public class ClassReader {
|
||||
int tag = readByte(index);
|
||||
int[] items = this.items;
|
||||
int cpIndex = items[readUnsignedShort(index + 1)];
|
||||
boolean itf = b[cpIndex - 1] == ClassWriter.IMETH;
|
||||
String owner = readClass(cpIndex, buf);
|
||||
cpIndex = items[readUnsignedShort(cpIndex + 2)];
|
||||
String name = readUTF8(cpIndex, buf);
|
||||
String desc = readUTF8(cpIndex + 2, buf);
|
||||
return new Handle(tag, owner, name, desc);
|
||||
return new Handle(tag, owner, name, desc, itf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1081,7 +1081,7 @@ public class ClassWriter extends ClassVisitor {
|
||||
}
|
||||
} else if (cst instanceof Handle) {
|
||||
Handle h = (Handle) cst;
|
||||
return newHandleItem(h.tag, h.owner, h.name, h.desc);
|
||||
return newHandleItem(h.tag, h.owner, h.name, h.desc, h.itf);
|
||||
} else {
|
||||
throw new IllegalArgumentException("value " + cst);
|
||||
}
|
||||
@ -1216,10 +1216,12 @@ public class ClassWriter extends ClassVisitor {
|
||||
* the name of the field or method.
|
||||
* @param desc
|
||||
* the descriptor of the field or method.
|
||||
* @param itf
|
||||
* true if the owner is an interface.
|
||||
* @return a new or an already existing method type reference item.
|
||||
*/
|
||||
Item newHandleItem(final int tag, final String owner, final String name,
|
||||
final String desc) {
|
||||
final String desc, final boolean itf) {
|
||||
key4.set(HANDLE_BASE + tag, owner, name, desc);
|
||||
Item result = get(key4);
|
||||
if (result == null) {
|
||||
@ -1228,8 +1230,7 @@ public class ClassWriter extends ClassVisitor {
|
||||
} else {
|
||||
put112(HANDLE,
|
||||
tag,
|
||||
newMethod(owner, name, desc,
|
||||
tag == Opcodes.H_INVOKEINTERFACE));
|
||||
newMethod(owner, name, desc, itf));
|
||||
}
|
||||
result = new Item(index++, key4);
|
||||
put(result);
|
||||
@ -1259,10 +1260,44 @@ public class ClassWriter extends ClassVisitor {
|
||||
* the descriptor of the field or method.
|
||||
* @return the index of a new or already existing method type reference
|
||||
* item.
|
||||
*
|
||||
* @deprecated this method is superseded by
|
||||
* {@link #newHandle(int, String, String, String, boolean)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public int newHandle(final int tag, final String owner, final String name,
|
||||
final String desc) {
|
||||
return newHandleItem(tag, owner, name, desc).index;
|
||||
return newHandle(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a handle to the constant pool of the class being build. Does nothing
|
||||
* if the constant pool already contains a similar item. <i>This method is
|
||||
* intended for {@link Attribute} sub classes, and is normally not needed by
|
||||
* class generators or adapters.</i>
|
||||
*
|
||||
* @param tag
|
||||
* the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
|
||||
* {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
|
||||
* {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
|
||||
* {@link Opcodes#H_INVOKESTATIC},
|
||||
* {@link Opcodes#H_INVOKESPECIAL},
|
||||
* {@link Opcodes#H_NEWINVOKESPECIAL} or
|
||||
* {@link Opcodes#H_INVOKEINTERFACE}.
|
||||
* @param owner
|
||||
* the internal name of the field or method owner class.
|
||||
* @param name
|
||||
* the name of the field or method.
|
||||
* @param desc
|
||||
* the descriptor of the field or method.
|
||||
* @param itf
|
||||
* true if the owner is an interface.
|
||||
* @return the index of a new or already existing method type reference
|
||||
* item.
|
||||
*/
|
||||
public int newHandle(final int tag, final String owner, final String name,
|
||||
final String desc, final boolean itf) {
|
||||
return newHandleItem(tag, owner, name, desc, itf).index;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1294,7 +1329,7 @@ public class ClassWriter extends ClassVisitor {
|
||||
|
||||
int hashCode = bsm.hashCode();
|
||||
bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
|
||||
bsm.desc));
|
||||
bsm.desc, bsm.isInterface()));
|
||||
|
||||
int argsLength = bsmArgs.length;
|
||||
bootstrapMethods.putShort(argsLength);
|
||||
|
@ -192,7 +192,7 @@ final class Frame {
|
||||
private static final int LOCAL = 0x2000000;
|
||||
|
||||
/**
|
||||
* Kind of the types that are relative to the stack of an input stack
|
||||
* Kind of the the types that are relative to the stack of an input stack
|
||||
* map frame. The value of such types is a position relatively to the top of
|
||||
* this stack.
|
||||
*/
|
||||
|
@ -93,6 +93,12 @@ public final class Handle {
|
||||
*/
|
||||
final String desc;
|
||||
|
||||
|
||||
/**
|
||||
* Indicate if the owner is an interface or not.
|
||||
*/
|
||||
final boolean itf;
|
||||
|
||||
/**
|
||||
* Constructs a new field or method handle.
|
||||
*
|
||||
@ -113,12 +119,44 @@ public final class Handle {
|
||||
* @param desc
|
||||
* the descriptor of the field or method designated by this
|
||||
* handle.
|
||||
*
|
||||
* @deprecated this constructor has been superseded
|
||||
* by {@link #Handle(int, String, String, String, boolean)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public Handle(int tag, String owner, String name, String desc) {
|
||||
this(tag, owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new field or method handle.
|
||||
*
|
||||
* @param tag
|
||||
* the kind of field or method designated by this Handle. Must be
|
||||
* {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
|
||||
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
|
||||
* {@link Opcodes#H_INVOKEVIRTUAL},
|
||||
* {@link Opcodes#H_INVOKESTATIC},
|
||||
* {@link Opcodes#H_INVOKESPECIAL},
|
||||
* {@link Opcodes#H_NEWINVOKESPECIAL} or
|
||||
* {@link Opcodes#H_INVOKEINTERFACE}.
|
||||
* @param owner
|
||||
* the internal name of the class that owns the field or method
|
||||
* designated by this handle.
|
||||
* @param name
|
||||
* the name of the field or method designated by this handle.
|
||||
* @param desc
|
||||
* the descriptor of the field or method designated by this
|
||||
* handle.
|
||||
* @param itf
|
||||
* true if the owner is an interface.
|
||||
*/
|
||||
public Handle(int tag, String owner, String name, String desc, boolean itf) {
|
||||
this.tag = tag;
|
||||
this.owner = owner;
|
||||
this.name = name;
|
||||
this.desc = desc;
|
||||
this.itf = itf;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,6 +202,17 @@ public final class Handle {
|
||||
return desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the owner of the field or method designated
|
||||
* by this handle is an interface.
|
||||
*
|
||||
* @return true if the owner of the field or method designated
|
||||
* by this handle is an interface.
|
||||
*/
|
||||
public boolean isInterface() {
|
||||
return itf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
@ -173,13 +222,13 @@ public final class Handle {
|
||||
return false;
|
||||
}
|
||||
Handle h = (Handle) obj;
|
||||
return tag == h.tag && owner.equals(h.owner) && name.equals(h.name)
|
||||
&& desc.equals(h.desc);
|
||||
return tag == h.tag && itf == h.itf && owner.equals(h.owner)
|
||||
&& name.equals(h.name) && desc.equals(h.desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return tag + owner.hashCode() * name.hashCode() * desc.hashCode();
|
||||
return tag + (itf? 64: 0) + owner.hashCode() * name.hashCode() * desc.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -187,13 +236,16 @@ public final class Handle {
|
||||
* representation is:
|
||||
*
|
||||
* <pre>
|
||||
* for a reference to a class:
|
||||
* owner '.' name desc ' ' '(' tag ')'
|
||||
* for a reference to an interface:
|
||||
* owner '.' name desc ' ' '(' tag ' ' itf ')'
|
||||
* </pre>
|
||||
*
|
||||
* . As this format is unambiguous, it can be parsed if necessary.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return owner + '.' + name + desc + " (" + tag + ')';
|
||||
return owner + '.' + name + desc + " (" + tag + (itf? " itf": "") + ')';
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,11 @@ public class Label {
|
||||
int status;
|
||||
|
||||
/**
|
||||
* The line number corresponding to this label, if known.
|
||||
* The line number corresponding to this label, if known. If there are
|
||||
* several lines, each line is stored in a separate label, all linked via
|
||||
* their next field (these links are created in ClassReader and removed just
|
||||
* before visitLabel is called, so that this does not impact the rest of the
|
||||
* code).
|
||||
*/
|
||||
int line;
|
||||
|
||||
@ -268,7 +272,8 @@ public class Label {
|
||||
* The next basic block in the basic block stack. This stack is used in the
|
||||
* main loop of the fix point algorithm used in the second step of the
|
||||
* control flow analysis algorithms. It is also used in
|
||||
* {@link #visitSubroutine} to avoid using a recursive method.
|
||||
* {@link #visitSubroutine} to avoid using a recursive method, and in
|
||||
* ClassReader to temporarily store multiple source lines for a label.
|
||||
*
|
||||
* @see MethodWriter#visitMaxs
|
||||
*/
|
||||
|
@ -62,15 +62,16 @@ package jdk.internal.org.objectweb.asm;
|
||||
* A visitor to visit a Java method. The methods of this class must be called in
|
||||
* the following order: ( <tt>visitParameter</tt> )* [
|
||||
* <tt>visitAnnotationDefault</tt> ] ( <tt>visitAnnotation</tt> |
|
||||
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* [
|
||||
* <tt>visitCode</tt> ( <tt>visitFrame</tt> | <tt>visit<i>X</i>Insn</tt> |
|
||||
* <tt>visitLabel</tt> | <tt>visitInsnAnnotation</tt> |
|
||||
* <tt>visitTryCatchBlock</tt> | <tt>visitTryCatchBlockAnnotation</tt> |
|
||||
* <tt>visitLocalVariable</tt> | <tt>visitLocalVariableAnnotation</tt> |
|
||||
* <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In
|
||||
* addition, the <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt> methods must
|
||||
* be called in the sequential order of the bytecode instructions of the visited
|
||||
* code, <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated
|
||||
* <tt>visitParameterAnnotation</tt> <tt>visitTypeAnnotation</tt> |
|
||||
* <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
|
||||
* <tt>visit<i>X</i>Insn</tt> | <tt>visitLabel</tt> |
|
||||
* <tt>visitInsnAnnotation</tt> | <tt>visitTryCatchBlock</tt> |
|
||||
* <tt>visitTryCatchAnnotation</tt> | <tt>visitLocalVariable</tt> |
|
||||
* <tt>visitLocalVariableAnnotation</tt> | <tt>visitLineNumber</tt> )*
|
||||
* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In addition, the
|
||||
* <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt> methods must be called in
|
||||
* the sequential order of the bytecode instructions of the visited code,
|
||||
* <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated
|
||||
* instruction, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the
|
||||
* labels passed as arguments have been visited,
|
||||
* <tt>visitTryCatchBlockAnnotation</tt> must be called <i>after</i> the
|
||||
|
@ -2061,7 +2061,7 @@ class MethodWriter extends MethodVisitor {
|
||||
}
|
||||
int size = 8;
|
||||
if (code.length > 0) {
|
||||
if (code.length > 65536) {
|
||||
if (code.length > 65535) {
|
||||
throw new RuntimeException("Method code too large!");
|
||||
}
|
||||
cw.newUTF8("Code");
|
||||
@ -2735,11 +2735,13 @@ class MethodWriter extends MethodVisitor {
|
||||
l = l.successor;
|
||||
}
|
||||
// Update the offsets in the uninitialized types
|
||||
for (i = 0; i < cw.typeTable.length; ++i) {
|
||||
Item item = cw.typeTable[i];
|
||||
if (item != null && item.type == ClassWriter.TYPE_UNINIT) {
|
||||
item.intVal = getNewOffset(allIndexes, allSizes, 0,
|
||||
item.intVal);
|
||||
if (cw.typeTable != null) {
|
||||
for (i = 0; i < cw.typeTable.length; ++i) {
|
||||
Item item = cw.typeTable[i];
|
||||
if (item != null && item.type == ClassWriter.TYPE_UNINIT) {
|
||||
item.intVal = getNewOffset(allIndexes, allSizes, 0,
|
||||
item.intVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
// The stack map frames are not serialized yet, so we don't need
|
||||
|
@ -87,6 +87,7 @@ public interface Opcodes {
|
||||
int V1_6 = 0 << 16 | 50;
|
||||
int V1_7 = 0 << 16 | 51;
|
||||
int V1_8 = 0 << 16 | 52;
|
||||
int V1_9 = 0 << 16 | 53;
|
||||
|
||||
// access flags
|
||||
|
||||
|
@ -654,7 +654,7 @@ public class Type {
|
||||
* @return the descriptor corresponding to this Java type.
|
||||
*/
|
||||
public String getDescriptor() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
getDescriptor(buf);
|
||||
return buf.toString();
|
||||
}
|
||||
@ -672,7 +672,7 @@ public class Type {
|
||||
*/
|
||||
public static String getMethodDescriptor(final Type returnType,
|
||||
final Type... argumentTypes) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append('(');
|
||||
for (int i = 0; i < argumentTypes.length; ++i) {
|
||||
argumentTypes[i].getDescriptor(buf);
|
||||
@ -689,7 +689,7 @@ public class Type {
|
||||
* @param buf
|
||||
* the string buffer to which the descriptor must be appended.
|
||||
*/
|
||||
private void getDescriptor(final StringBuffer buf) {
|
||||
private void getDescriptor(final StringBuilder buf) {
|
||||
if (this.buf == null) {
|
||||
// descriptor is in byte 3 of 'off' for primitive types (buf ==
|
||||
// null)
|
||||
@ -729,7 +729,7 @@ public class Type {
|
||||
* @return the descriptor corresponding to the given class.
|
||||
*/
|
||||
public static String getDescriptor(final Class<?> c) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
getDescriptor(buf, c);
|
||||
return buf.toString();
|
||||
}
|
||||
@ -743,7 +743,7 @@ public class Type {
|
||||
*/
|
||||
public static String getConstructorDescriptor(final Constructor<?> c) {
|
||||
Class<?>[] parameters = c.getParameterTypes();
|
||||
StringBuffer buf = new StringBuffer();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append('(');
|
||||
for (int i = 0; i < parameters.length; ++i) {
|
||||
getDescriptor(buf, parameters[i]);
|
||||
@ -760,7 +760,7 @@ public class Type {
|
||||
*/
|
||||
public static String getMethodDescriptor(final Method m) {
|
||||
Class<?>[] parameters = m.getParameterTypes();
|
||||
StringBuffer buf = new StringBuffer();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append('(');
|
||||
for (int i = 0; i < parameters.length; ++i) {
|
||||
getDescriptor(buf, parameters[i]);
|
||||
@ -778,7 +778,7 @@ public class Type {
|
||||
* @param c
|
||||
* the class whose descriptor must be computed.
|
||||
*/
|
||||
private static void getDescriptor(final StringBuffer buf, final Class<?> c) {
|
||||
private static void getDescriptor(final StringBuilder buf, final Class<?> c) {
|
||||
Class<?> d = c;
|
||||
while (true) {
|
||||
if (d.isPrimitive()) {
|
||||
|
@ -71,25 +71,25 @@ public class TypePath {
|
||||
* A type path step that steps into the element type of an array type. See
|
||||
* {@link #getStep getStep}.
|
||||
*/
|
||||
public static final int ARRAY_ELEMENT = 0;
|
||||
public final static int ARRAY_ELEMENT = 0;
|
||||
|
||||
/**
|
||||
* A type path step that steps into the nested type of a class type. See
|
||||
* {@link #getStep getStep}.
|
||||
*/
|
||||
public static final int INNER_TYPE = 1;
|
||||
public final static int INNER_TYPE = 1;
|
||||
|
||||
/**
|
||||
* A type path step that steps into the bound of a wildcard type. See
|
||||
* {@link #getStep getStep}.
|
||||
*/
|
||||
public static final int WILDCARD_BOUND = 2;
|
||||
public final static int WILDCARD_BOUND = 2;
|
||||
|
||||
/**
|
||||
* A type path step that steps into a type argument of a generic type. See
|
||||
* {@link #getStep getStep}.
|
||||
*/
|
||||
public static final int TYPE_ARGUMENT = 3;
|
||||
public final static int TYPE_ARGUMENT = 3;
|
||||
|
||||
/**
|
||||
* The byte array where the path is stored, in Java class file format.
|
||||
|
@ -74,133 +74,133 @@ public class TypeReference {
|
||||
* The sort of type references that target a type parameter of a generic
|
||||
* class. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int CLASS_TYPE_PARAMETER = 0x00;
|
||||
public final static int CLASS_TYPE_PARAMETER = 0x00;
|
||||
|
||||
/**
|
||||
* The sort of type references that target a type parameter of a generic
|
||||
* method. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int METHOD_TYPE_PARAMETER = 0x01;
|
||||
public final static int METHOD_TYPE_PARAMETER = 0x01;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the super class of a class or one
|
||||
* of the interfaces it implements. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int CLASS_EXTENDS = 0x10;
|
||||
public final static int CLASS_EXTENDS = 0x10;
|
||||
|
||||
/**
|
||||
* The sort of type references that target a bound of a type parameter of a
|
||||
* generic class. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int CLASS_TYPE_PARAMETER_BOUND = 0x11;
|
||||
public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11;
|
||||
|
||||
/**
|
||||
* The sort of type references that target a bound of a type parameter of a
|
||||
* generic method. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int METHOD_TYPE_PARAMETER_BOUND = 0x12;
|
||||
public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the type of a field. See
|
||||
* {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int FIELD = 0x13;
|
||||
public final static int FIELD = 0x13;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the return type of a method. See
|
||||
* {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int METHOD_RETURN = 0x14;
|
||||
public final static int METHOD_RETURN = 0x14;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the receiver type of a method.
|
||||
* See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int METHOD_RECEIVER = 0x15;
|
||||
public final static int METHOD_RECEIVER = 0x15;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the type of a formal parameter of
|
||||
* a method. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int METHOD_FORMAL_PARAMETER = 0x16;
|
||||
public final static int METHOD_FORMAL_PARAMETER = 0x16;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the type of an exception declared
|
||||
* in the throws clause of a method. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int THROWS = 0x17;
|
||||
public final static int THROWS = 0x17;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the type of a local variable in a
|
||||
* method. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int LOCAL_VARIABLE = 0x40;
|
||||
public final static int LOCAL_VARIABLE = 0x40;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the type of a resource variable
|
||||
* in a method. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int RESOURCE_VARIABLE = 0x41;
|
||||
public final static int RESOURCE_VARIABLE = 0x41;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the type of the exception of a
|
||||
* 'catch' clause in a method. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int EXCEPTION_PARAMETER = 0x42;
|
||||
public final static int EXCEPTION_PARAMETER = 0x42;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the type declared in an
|
||||
* 'instanceof' instruction. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int INSTANCEOF = 0x43;
|
||||
public final static int INSTANCEOF = 0x43;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the type of the object created by
|
||||
* a 'new' instruction. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int NEW = 0x44;
|
||||
public final static int NEW = 0x44;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the receiver type of a
|
||||
* constructor reference. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int CONSTRUCTOR_REFERENCE = 0x45;
|
||||
public final static int CONSTRUCTOR_REFERENCE = 0x45;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the receiver type of a method
|
||||
* reference. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int METHOD_REFERENCE = 0x46;
|
||||
public final static int METHOD_REFERENCE = 0x46;
|
||||
|
||||
/**
|
||||
* The sort of type references that target the type declared in an explicit
|
||||
* or implicit cast instruction. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int CAST = 0x47;
|
||||
public final static int CAST = 0x47;
|
||||
|
||||
/**
|
||||
* The sort of type references that target a type parameter of a generic
|
||||
* constructor in a constructor call. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
|
||||
public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
|
||||
|
||||
/**
|
||||
* The sort of type references that target a type parameter of a generic
|
||||
* method in a method call. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
|
||||
public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
|
||||
|
||||
/**
|
||||
* The sort of type references that target a type parameter of a generic
|
||||
* constructor in a constructor reference. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
|
||||
public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
|
||||
|
||||
/**
|
||||
* The sort of type references that target a type parameter of a generic
|
||||
* method in a method reference. See {@link #getSort getSort}.
|
||||
*/
|
||||
public static final int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
|
||||
public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
|
||||
|
||||
/**
|
||||
* The type reference value in Java class file format.
|
||||
|
@ -388,10 +388,10 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
|
||||
}
|
||||
break;
|
||||
case PUTFIELD:
|
||||
popValue();
|
||||
popValue();
|
||||
if (longOrDouble) {
|
||||
popValue();
|
||||
popValue();
|
||||
}
|
||||
break;
|
||||
// case GETFIELD:
|
||||
@ -619,7 +619,7 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at the beginning of the method or after super class class call in
|
||||
* Called at the beginning of the method or after super class call in
|
||||
* the constructor. <br>
|
||||
* <br>
|
||||
*
|
||||
|
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* ASM: a very small and fast Java bytecode manipulation framework
|
||||
* Copyright (c) 2000-2011 INRIA, France Telecom
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package jdk.internal.org.objectweb.asm.commons;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
|
||||
/**
|
||||
* An {@link AnnotationVisitor} adapter for type remapping.
|
||||
*
|
||||
* @author Eugene Kuleshov
|
||||
*/
|
||||
public class AnnotationRemapper extends AnnotationVisitor {
|
||||
|
||||
protected final Remapper remapper;
|
||||
|
||||
public AnnotationRemapper(final AnnotationVisitor av,
|
||||
final Remapper remapper) {
|
||||
this(Opcodes.ASM5, av, remapper);
|
||||
}
|
||||
|
||||
protected AnnotationRemapper(final int api, final AnnotationVisitor av,
|
||||
final Remapper remapper) {
|
||||
super(api, av);
|
||||
this.remapper = remapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(String name, Object value) {
|
||||
av.visit(name, remapper.mapValue(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnum(String name, String desc, String value) {
|
||||
av.visitEnum(name, remapper.mapDesc(desc), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String name, String desc) {
|
||||
AnnotationVisitor v = av.visitAnnotation(name, remapper.mapDesc(desc));
|
||||
return v == null ? null : (v == av ? this : new AnnotationRemapper(v,
|
||||
remapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitArray(String name) {
|
||||
AnnotationVisitor v = av.visitArray(name);
|
||||
return v == null ? null : (v == av ? this : new AnnotationRemapper(v,
|
||||
remapper));
|
||||
}
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* ASM: a very small and fast Java bytecode manipulation framework
|
||||
* Copyright (c) 2000-2011 INRIA, France Telecom
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package jdk.internal.org.objectweb.asm.commons;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
|
||||
import jdk.internal.org.objectweb.asm.ClassVisitor;
|
||||
import jdk.internal.org.objectweb.asm.FieldVisitor;
|
||||
import jdk.internal.org.objectweb.asm.MethodVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.TypePath;
|
||||
|
||||
/**
|
||||
* A {@link ClassVisitor} for type remapping.
|
||||
*
|
||||
* @author Eugene Kuleshov
|
||||
*/
|
||||
public class ClassRemapper extends ClassVisitor {
|
||||
|
||||
protected final Remapper remapper;
|
||||
|
||||
protected String className;
|
||||
|
||||
public ClassRemapper(final ClassVisitor cv, final Remapper remapper) {
|
||||
this(Opcodes.ASM5, cv, remapper);
|
||||
}
|
||||
|
||||
protected ClassRemapper(final int api, final ClassVisitor cv,
|
||||
final Remapper remapper) {
|
||||
super(api, cv);
|
||||
this.remapper = remapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature,
|
||||
String superName, String[] interfaces) {
|
||||
this.className = name;
|
||||
super.visit(version, access, remapper.mapType(name), remapper
|
||||
.mapSignature(signature, false), remapper.mapType(superName),
|
||||
interfaces == null ? null : remapper.mapTypes(interfaces));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||
AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
|
||||
visible);
|
||||
return av == null ? null : createAnnotationRemapper(av);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitTypeAnnotation(int typeRef,
|
||||
TypePath typePath, String desc, boolean visible) {
|
||||
AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
|
||||
remapper.mapDesc(desc), visible);
|
||||
return av == null ? null : createAnnotationRemapper(av);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldVisitor visitField(int access, String name, String desc,
|
||||
String signature, Object value) {
|
||||
FieldVisitor fv = super.visitField(access,
|
||||
remapper.mapFieldName(className, name, desc),
|
||||
remapper.mapDesc(desc), remapper.mapSignature(signature, true),
|
||||
remapper.mapValue(value));
|
||||
return fv == null ? null : createFieldRemapper(fv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc,
|
||||
String signature, String[] exceptions) {
|
||||
String newDesc = remapper.mapMethodDesc(desc);
|
||||
MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName(
|
||||
className, name, desc), newDesc, remapper.mapSignature(
|
||||
signature, false),
|
||||
exceptions == null ? null : remapper.mapTypes(exceptions));
|
||||
return mv == null ? null : createMethodRemapper(mv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInnerClass(String name, String outerName,
|
||||
String innerName, int access) {
|
||||
// TODO should innerName be changed?
|
||||
super.visitInnerClass(remapper.mapType(name), outerName == null ? null
|
||||
: remapper.mapType(outerName), innerName, access);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitOuterClass(String owner, String name, String desc) {
|
||||
super.visitOuterClass(remapper.mapType(owner), name == null ? null
|
||||
: remapper.mapMethodName(owner, name, desc),
|
||||
desc == null ? null : remapper.mapMethodDesc(desc));
|
||||
}
|
||||
|
||||
protected FieldVisitor createFieldRemapper(FieldVisitor fv) {
|
||||
return new FieldRemapper(fv, remapper);
|
||||
}
|
||||
|
||||
protected MethodVisitor createMethodRemapper(MethodVisitor mv) {
|
||||
return new MethodRemapper(mv, remapper);
|
||||
}
|
||||
|
||||
protected AnnotationVisitor createAnnotationRemapper(AnnotationVisitor av) {
|
||||
return new AnnotationRemapper(av, remapper);
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* ASM: a very small and fast Java bytecode manipulation framework
|
||||
* Copyright (c) 2000-2011 INRIA, France Telecom
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package jdk.internal.org.objectweb.asm.commons;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
|
||||
import jdk.internal.org.objectweb.asm.FieldVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.TypePath;
|
||||
|
||||
/**
|
||||
* A {@link FieldVisitor} adapter for type remapping.
|
||||
*
|
||||
* @author Eugene Kuleshov
|
||||
*/
|
||||
public class FieldRemapper extends FieldVisitor {
|
||||
|
||||
private final Remapper remapper;
|
||||
|
||||
public FieldRemapper(final FieldVisitor fv, final Remapper remapper) {
|
||||
this(Opcodes.ASM5, fv, remapper);
|
||||
}
|
||||
|
||||
protected FieldRemapper(final int api, final FieldVisitor fv,
|
||||
final Remapper remapper) {
|
||||
super(api, fv);
|
||||
this.remapper = remapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||
AnnotationVisitor av = fv.visitAnnotation(remapper.mapDesc(desc),
|
||||
visible);
|
||||
return av == null ? null : new AnnotationRemapper(av, remapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitTypeAnnotation(int typeRef,
|
||||
TypePath typePath, String desc, boolean visible) {
|
||||
AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
|
||||
remapper.mapDesc(desc), visible);
|
||||
return av == null ? null : new AnnotationRemapper(av, remapper);
|
||||
}
|
||||
}
|
@ -73,7 +73,7 @@ import jdk.internal.org.objectweb.asm.Type;
|
||||
*/
|
||||
public class InstructionAdapter extends MethodVisitor {
|
||||
|
||||
public static final Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;");
|
||||
public final static Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;");
|
||||
|
||||
/**
|
||||
* Creates a new {@link InstructionAdapter}. <i>Subclasses must not use this
|
||||
|
@ -104,11 +104,6 @@ public class LocalVariablesSorter extends MethodVisitor {
|
||||
*/
|
||||
protected int nextLocal;
|
||||
|
||||
/**
|
||||
* Indicates if at least one local variable has moved due to remapping.
|
||||
*/
|
||||
private boolean changed;
|
||||
|
||||
/**
|
||||
* Creates a new {@link LocalVariablesSorter}. <i>Subclasses must not use
|
||||
* this constructor</i>. Instead, they must use the
|
||||
@ -228,11 +223,6 @@ public class LocalVariablesSorter extends MethodVisitor {
|
||||
"ClassReader.accept() should be called with EXPAND_FRAMES flag");
|
||||
}
|
||||
|
||||
if (!changed) { // optimization for the case where mapping = identity
|
||||
mv.visitFrame(type, nLocal, local, nStack, stack);
|
||||
return;
|
||||
}
|
||||
|
||||
// creates a copy of newLocals
|
||||
Object[] oldLocals = new Object[newLocals.length];
|
||||
System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length);
|
||||
@ -328,7 +318,6 @@ public class LocalVariablesSorter extends MethodVisitor {
|
||||
int local = newLocalMapping(type);
|
||||
setLocalType(local, type);
|
||||
setFrameLocal(local, t);
|
||||
changed = true;
|
||||
return local;
|
||||
}
|
||||
|
||||
@ -396,9 +385,6 @@ public class LocalVariablesSorter extends MethodVisitor {
|
||||
} else {
|
||||
value--;
|
||||
}
|
||||
if (value != var) {
|
||||
changed = true;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* ASM: a very small and fast Java bytecode manipulation framework
|
||||
* Copyright (c) 2000-2011 INRIA, France Telecom
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package jdk.internal.org.objectweb.asm.commons;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Handle;
|
||||
import jdk.internal.org.objectweb.asm.Label;
|
||||
import jdk.internal.org.objectweb.asm.MethodVisitor;
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.TypePath;
|
||||
|
||||
/**
|
||||
* A {@link LocalVariablesSorter} for type mapping.
|
||||
*
|
||||
* @author Eugene Kuleshov
|
||||
*/
|
||||
public class MethodRemapper extends MethodVisitor {
|
||||
|
||||
protected final Remapper remapper;
|
||||
|
||||
public MethodRemapper(final MethodVisitor mv, final Remapper remapper) {
|
||||
this(Opcodes.ASM5, mv, remapper);
|
||||
}
|
||||
|
||||
protected MethodRemapper(final int api, final MethodVisitor mv,
|
||||
final Remapper remapper) {
|
||||
super(api, mv);
|
||||
this.remapper = remapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotationDefault() {
|
||||
AnnotationVisitor av = super.visitAnnotationDefault();
|
||||
return av == null ? av : new AnnotationRemapper(av, remapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||
AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
|
||||
visible);
|
||||
return av == null ? av : new AnnotationRemapper(av, remapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitTypeAnnotation(int typeRef,
|
||||
TypePath typePath, String desc, boolean visible) {
|
||||
AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
|
||||
remapper.mapDesc(desc), visible);
|
||||
return av == null ? av : new AnnotationRemapper(av, remapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitParameterAnnotation(int parameter,
|
||||
String desc, boolean visible) {
|
||||
AnnotationVisitor av = super.visitParameterAnnotation(parameter,
|
||||
remapper.mapDesc(desc), visible);
|
||||
return av == null ? av : new AnnotationRemapper(av, remapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFrame(int type, int nLocal, Object[] local, int nStack,
|
||||
Object[] stack) {
|
||||
super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack,
|
||||
remapEntries(nStack, stack));
|
||||
}
|
||||
|
||||
private Object[] remapEntries(int n, Object[] entries) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (entries[i] instanceof String) {
|
||||
Object[] newEntries = new Object[n];
|
||||
if (i > 0) {
|
||||
System.arraycopy(entries, 0, newEntries, 0, i);
|
||||
}
|
||||
do {
|
||||
Object t = entries[i];
|
||||
newEntries[i++] = t instanceof String ? remapper
|
||||
.mapType((String) t) : t;
|
||||
} while (i < n);
|
||||
return newEntries;
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, String owner, String name,
|
||||
String desc) {
|
||||
super.visitFieldInsn(opcode, remapper.mapType(owner),
|
||||
remapper.mapFieldName(owner, name, desc),
|
||||
remapper.mapDesc(desc));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void visitMethodInsn(final int opcode, final String owner,
|
||||
final String name, final String desc) {
|
||||
if (api >= Opcodes.ASM5) {
|
||||
super.visitMethodInsn(opcode, owner, name, desc);
|
||||
return;
|
||||
}
|
||||
doVisitMethodInsn(opcode, owner, name, desc,
|
||||
opcode == Opcodes.INVOKEINTERFACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodInsn(final int opcode, final String owner,
|
||||
final String name, final String desc, final boolean itf) {
|
||||
if (api < Opcodes.ASM5) {
|
||||
super.visitMethodInsn(opcode, owner, name, desc, itf);
|
||||
return;
|
||||
}
|
||||
doVisitMethodInsn(opcode, owner, name, desc, itf);
|
||||
}
|
||||
|
||||
private void doVisitMethodInsn(int opcode, String owner, String name,
|
||||
String desc, boolean itf) {
|
||||
// Calling super.visitMethodInsn requires to call the correct version
|
||||
// depending on this.api (otherwise infinite loops can occur). To
|
||||
// simplify and to make it easier to automatically remove the backward
|
||||
// compatibility code, we inline the code of the overridden method here.
|
||||
// IMPORTANT: THIS ASSUMES THAT visitMethodInsn IS NOT OVERRIDDEN IN
|
||||
// LocalVariableSorter.
|
||||
if (mv != null) {
|
||||
mv.visitMethodInsn(opcode, remapper.mapType(owner),
|
||||
remapper.mapMethodName(owner, name, desc),
|
||||
remapper.mapMethodDesc(desc), itf);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
|
||||
Object... bsmArgs) {
|
||||
for (int i = 0; i < bsmArgs.length; i++) {
|
||||
bsmArgs[i] = remapper.mapValue(bsmArgs[i]);
|
||||
}
|
||||
super.visitInvokeDynamicInsn(
|
||||
remapper.mapInvokeDynamicMethodName(name, desc),
|
||||
remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm),
|
||||
bsmArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeInsn(int opcode, String type) {
|
||||
super.visitTypeInsn(opcode, remapper.mapType(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLdcInsn(Object cst) {
|
||||
super.visitLdcInsn(remapper.mapValue(cst));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMultiANewArrayInsn(String desc, int dims) {
|
||||
super.visitMultiANewArrayInsn(remapper.mapDesc(desc), dims);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitInsnAnnotation(int typeRef,
|
||||
TypePath typePath, String desc, boolean visible) {
|
||||
AnnotationVisitor av = super.visitInsnAnnotation(typeRef, typePath,
|
||||
remapper.mapDesc(desc), visible);
|
||||
return av == null ? av : new AnnotationRemapper(av, remapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTryCatchBlock(Label start, Label end, Label handler,
|
||||
String type) {
|
||||
super.visitTryCatchBlock(start, end, handler, type == null ? null
|
||||
: remapper.mapType(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
|
||||
TypePath typePath, String desc, boolean visible) {
|
||||
AnnotationVisitor av = super.visitTryCatchAnnotation(typeRef, typePath,
|
||||
remapper.mapDesc(desc), visible);
|
||||
return av == null ? av : new AnnotationRemapper(av, remapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLocalVariable(String name, String desc, String signature,
|
||||
Label start, Label end, int index) {
|
||||
super.visitLocalVariable(name, remapper.mapDesc(desc),
|
||||
remapper.mapSignature(signature, true), start, end, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
|
||||
TypePath typePath, Label[] start, Label[] end, int[] index,
|
||||
String desc, boolean visible) {
|
||||
AnnotationVisitor av = super.visitLocalVariableAnnotation(typeRef,
|
||||
typePath, start, end, index, remapper.mapDesc(desc), visible);
|
||||
return av == null ? av : new AnnotationRemapper(av, remapper);
|
||||
}
|
||||
}
|
@ -168,17 +168,19 @@ public abstract class Remapper {
|
||||
Handle h = (Handle) value;
|
||||
return new Handle(h.getTag(), mapType(h.getOwner()), mapMethodName(
|
||||
h.getOwner(), h.getName(), h.getDesc()),
|
||||
mapMethodDesc(h.getDesc()));
|
||||
mapMethodDesc(h.getDesc()), h.isInterface());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param signature
|
||||
* signature for mapper
|
||||
* @param typeSignature
|
||||
* true if signature is a FieldTypeSignature, such as the
|
||||
* signature parameter of the ClassVisitor.visitField or
|
||||
* MethodVisitor.visitLocalVariable methods
|
||||
* @return signature rewritten as a string
|
||||
*/
|
||||
public String mapSignature(String signature, boolean typeSignature) {
|
||||
if (signature == null) {
|
||||
@ -186,7 +188,7 @@ public abstract class Remapper {
|
||||
}
|
||||
SignatureReader r = new SignatureReader(signature);
|
||||
SignatureWriter w = new SignatureWriter();
|
||||
SignatureVisitor a = createRemappingSignatureAdapter(w);
|
||||
SignatureVisitor a = createSignatureRemapper(w);
|
||||
if (typeSignature) {
|
||||
r.acceptType(a);
|
||||
} else {
|
||||
@ -195,9 +197,18 @@ public abstract class Remapper {
|
||||
return w.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #createSignatureRemapper} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
protected SignatureVisitor createRemappingSignatureAdapter(
|
||||
SignatureVisitor v) {
|
||||
return new RemappingSignatureAdapter(v, this);
|
||||
return new SignatureRemapper(v, this);
|
||||
}
|
||||
|
||||
protected SignatureVisitor createSignatureRemapper(
|
||||
SignatureVisitor v) {
|
||||
return createRemappingSignatureAdapter(v);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -245,6 +256,10 @@ public abstract class Remapper {
|
||||
|
||||
/**
|
||||
* Map type name to the new name. Subclasses can override.
|
||||
*
|
||||
* @param typeName
|
||||
* the type name
|
||||
* @return new name, default implementation is the identity.
|
||||
*/
|
||||
public String map(String typeName) {
|
||||
return typeName;
|
||||
|
@ -65,8 +65,10 @@ import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
/**
|
||||
* An {@link AnnotationVisitor} adapter for type remapping.
|
||||
*
|
||||
* //@deprecated use {@link AnnotationRemapper} instead.
|
||||
* @author Eugene Kuleshov
|
||||
*/
|
||||
//@Deprecated
|
||||
public class RemappingAnnotationAdapter extends AnnotationVisitor {
|
||||
|
||||
protected final Remapper remapper;
|
||||
|
@ -69,8 +69,10 @@ import jdk.internal.org.objectweb.asm.TypePath;
|
||||
/**
|
||||
* A {@link ClassVisitor} for type remapping.
|
||||
*
|
||||
* @deprecated use {@link ClassRemapper} instead.
|
||||
* @author Eugene Kuleshov
|
||||
*/
|
||||
@Deprecated
|
||||
public class RemappingClassAdapter extends ClassVisitor {
|
||||
|
||||
protected final Remapper remapper;
|
||||
|
@ -67,8 +67,10 @@ import jdk.internal.org.objectweb.asm.TypePath;
|
||||
/**
|
||||
* A {@link FieldVisitor} adapter for type remapping.
|
||||
*
|
||||
* @deprecated use {@link FieldRemapper} instead.
|
||||
* @author Eugene Kuleshov
|
||||
*/
|
||||
@Deprecated
|
||||
public class RemappingFieldAdapter extends FieldVisitor {
|
||||
|
||||
private final Remapper remapper;
|
||||
|
@ -69,8 +69,10 @@ import jdk.internal.org.objectweb.asm.TypePath;
|
||||
/**
|
||||
* A {@link LocalVariablesSorter} for type mapping.
|
||||
*
|
||||
* //@deprecated use {@link MethodRemapper} instead.
|
||||
* @author Eugene Kuleshov
|
||||
*/
|
||||
//@Deprecated
|
||||
public class RemappingMethodAdapter extends LocalVariablesSorter {
|
||||
|
||||
protected final Remapper remapper;
|
||||
|
@ -65,8 +65,10 @@ import jdk.internal.org.objectweb.asm.signature.SignatureVisitor;
|
||||
/**
|
||||
* A {@link SignatureVisitor} adapter for type mapping.
|
||||
*
|
||||
* @deprecated use {@link SignatureRemapper} instead.
|
||||
* @author Eugene Kuleshov
|
||||
*/
|
||||
@Deprecated
|
||||
public class RemappingSignatureAdapter extends SignatureVisitor {
|
||||
|
||||
private final SignatureVisitor v;
|
||||
|
@ -234,7 +234,7 @@ public class SerialVersionUIDAdder extends ClassVisitor {
|
||||
public void visit(final int version, final int access, final String name,
|
||||
final String signature, final String superName,
|
||||
final String[] interfaces) {
|
||||
computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0;
|
||||
computeSVUID = (access & Opcodes.ACC_ENUM) == 0;
|
||||
|
||||
if (computeSVUID) {
|
||||
this.name = name;
|
||||
@ -396,6 +396,11 @@ public class SerialVersionUIDAdder extends ClassVisitor {
|
||||
/*
|
||||
* 2. The class modifiers written as a 32-bit integer.
|
||||
*/
|
||||
int access = this.access;
|
||||
if ((access & Opcodes.ACC_INTERFACE) != 0) {
|
||||
access = (svuidMethods.size() > 0) ? (access | Opcodes.ACC_ABSTRACT)
|
||||
: (access & ~Opcodes.ACC_ABSTRACT);
|
||||
}
|
||||
dos.writeInt(access
|
||||
& (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL
|
||||
| Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT));
|
||||
|
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is available under and governed by the GNU General Public
|
||||
* License version 2 only, as published by the Free Software Foundation.
|
||||
* However, the following notice accompanied the original version of this
|
||||
* file:
|
||||
*
|
||||
* ASM: a very small and fast Java bytecode manipulation framework
|
||||
* Copyright (c) 2000-2011 INRIA, France Telecom
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package jdk.internal.org.objectweb.asm.commons;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.signature.SignatureVisitor;
|
||||
|
||||
/**
|
||||
* A {@link SignatureVisitor} adapter for type mapping.
|
||||
*
|
||||
* @author Eugene Kuleshov
|
||||
*/
|
||||
public class SignatureRemapper extends SignatureVisitor {
|
||||
|
||||
private final SignatureVisitor v;
|
||||
|
||||
private final Remapper remapper;
|
||||
|
||||
private Stack<String> classNames = new Stack<String>();
|
||||
|
||||
public SignatureRemapper(final SignatureVisitor v, final Remapper remapper) {
|
||||
this(Opcodes.ASM5, v, remapper);
|
||||
}
|
||||
|
||||
protected SignatureRemapper(final int api, final SignatureVisitor v,
|
||||
final Remapper remapper) {
|
||||
super(api);
|
||||
this.v = v;
|
||||
this.remapper = remapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClassType(String name) {
|
||||
classNames.push(name);
|
||||
v.visitClassType(remapper.mapType(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInnerClassType(String name) {
|
||||
String outerClassName = classNames.pop();
|
||||
String className = outerClassName + '$' + name;
|
||||
classNames.push(className);
|
||||
String remappedOuter = remapper.mapType(outerClassName) + '$';
|
||||
String remappedName = remapper.mapType(className);
|
||||
int index = remappedName.startsWith(remappedOuter) ? remappedOuter
|
||||
.length() : remappedName.lastIndexOf('$') + 1;
|
||||
v.visitInnerClassType(remappedName.substring(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFormalTypeParameter(String name) {
|
||||
v.visitFormalTypeParameter(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeVariable(String name) {
|
||||
v.visitTypeVariable(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitArrayType() {
|
||||
v.visitArrayType();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitBaseType(char descriptor) {
|
||||
v.visitBaseType(descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitClassBound() {
|
||||
v.visitClassBound();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitExceptionType() {
|
||||
v.visitExceptionType();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitInterface() {
|
||||
v.visitInterface();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitInterfaceBound() {
|
||||
v.visitInterfaceBound();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitParameterType() {
|
||||
v.visitParameterType();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitReturnType() {
|
||||
v.visitReturnType();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitSuperclass() {
|
||||
v.visitSuperclass();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeArgument() {
|
||||
v.visitTypeArgument();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitTypeArgument(char wildcard) {
|
||||
v.visitTypeArgument(wildcard);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
v.visitEnd();
|
||||
classNames.pop();
|
||||
}
|
||||
}
|
@ -85,6 +85,12 @@ public class SimpleRemapper extends Remapper {
|
||||
return s == null ? name : s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapInvokeDynamicMethodName(String name, String desc) {
|
||||
String s = map('.' + name + desc);
|
||||
return s == null ? name : s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapFieldName(String owner, String name, String desc) {
|
||||
String s = map(owner + '.' + name);
|
||||
|
@ -68,7 +68,7 @@ import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
* <ul>
|
||||
* <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt>
|
||||
* <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
|
||||
* <tt>visitSuperClass</tt> <tt>visitInterface</tt>* )</li>
|
||||
* <tt>visitSuperclass</tt> <tt>visitInterface</tt>* )</li>
|
||||
* <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt>
|
||||
* <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
|
||||
* <tt>visitParameterType</tt>* <tt>visitReturnType</tt>
|
||||
@ -88,17 +88,17 @@ public abstract class SignatureVisitor {
|
||||
/**
|
||||
* Wildcard for an "extends" type argument.
|
||||
*/
|
||||
public static final char EXTENDS = '+';
|
||||
public final static char EXTENDS = '+';
|
||||
|
||||
/**
|
||||
* Wildcard for a "super" type argument.
|
||||
*/
|
||||
public static final char SUPER = '-';
|
||||
public final static char SUPER = '-';
|
||||
|
||||
/**
|
||||
* Wildcard for a normal type argument.
|
||||
*/
|
||||
public static final char INSTANCEOF = '=';
|
||||
public final static char INSTANCEOF = '=';
|
||||
|
||||
/**
|
||||
* The ASM API version implemented by this visitor. The value of this field
|
||||
|
@ -69,9 +69,9 @@ import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
public class SignatureWriter extends SignatureVisitor {
|
||||
|
||||
/**
|
||||
* Buffer used to construct the signature.
|
||||
* Builder used to construct the signature.
|
||||
*/
|
||||
private final StringBuffer buf = new StringBuffer();
|
||||
private final StringBuilder buf = new StringBuilder();
|
||||
|
||||
/**
|
||||
* Indicates if the signature contains formal type parameters.
|
||||
|
@ -205,6 +205,9 @@ public class InsnList {
|
||||
/**
|
||||
* Returns an iterator over the instructions in this list.
|
||||
*
|
||||
* @param index
|
||||
* index of instruction for the iterator to start at
|
||||
*
|
||||
* @return an iterator over the instructions in this list.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -856,7 +856,11 @@ public class ASMifier extends Printer {
|
||||
buf.append("{\n").append("av0 = ").append(name)
|
||||
.append(".visitLocalVariableAnnotation(");
|
||||
buf.append(typeRef);
|
||||
buf.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
|
||||
if (typePath == null) {
|
||||
buf.append(", null, ");
|
||||
} else {
|
||||
buf.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
|
||||
}
|
||||
buf.append("new Label[] {");
|
||||
for (int i = 0; i < start.length; ++i) {
|
||||
buf.append(i == 0 ? " " : ", ");
|
||||
@ -934,7 +938,11 @@ public class ASMifier extends Printer {
|
||||
buf.append("{\n").append("av0 = ").append(name).append(".")
|
||||
.append(method).append("(");
|
||||
buf.append(typeRef);
|
||||
buf.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
|
||||
if (typePath == null) {
|
||||
buf.append(", null, ");
|
||||
} else {
|
||||
buf.append(", TypePath.fromString(\"").append(typePath).append("\"), ");
|
||||
}
|
||||
appendConstant(desc);
|
||||
buf.append(", ").append(visible).append(");\n");
|
||||
text.add(buf.toString());
|
||||
|
@ -437,6 +437,9 @@ public class CheckMethodAdapter extends MethodVisitor {
|
||||
* will not perform any data flow check (see
|
||||
* {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)}).
|
||||
*
|
||||
* @param api
|
||||
* the ASM API version implemented by this CheckMethodAdapter.
|
||||
* Must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
|
||||
* @param mv
|
||||
* the method visitor to which this adapter must delegate calls.
|
||||
* @param labels
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -74,34 +74,36 @@ import jdk.internal.org.objectweb.asm.TypePath;
|
||||
* visitor chain to trace the class that is visited at a given point in this
|
||||
* chain. This may be useful for debugging purposes.
|
||||
* <p>
|
||||
* The trace printed when visiting the {@code Hello} class is the following:
|
||||
* The trace printed when visiting the <tt>Hello</tt> class is the following:
|
||||
* <p>
|
||||
* <blockquote>
|
||||
*
|
||||
* <pre>{@code
|
||||
* <pre>
|
||||
* // class version 49.0 (49) // access flags 0x21 public class Hello {
|
||||
*
|
||||
* // compiled from: Hello.java
|
||||
*
|
||||
* // access flags 0x1 public <init> ()V ALOAD 0 INVOKESPECIAL
|
||||
* java/lang/Object <init> ()V RETURN MAXSTACK = 1 MAXLOCALS = 1
|
||||
* // access flags 0x1 public <init> ()V ALOAD 0 INVOKESPECIAL
|
||||
* java/lang/Object <init> ()V RETURN MAXSTACK = 1 MAXLOCALS = 1
|
||||
*
|
||||
* // access flags 0x9 public static main ([Ljava/lang/String;)V GETSTATIC
|
||||
* java/lang/System out Ljava/io/PrintStream; LDC "hello"
|
||||
* java/lang/System out Ljava/io/PrintStream; LDC "hello"
|
||||
* INVOKEVIRTUAL java/io/PrintStream println (Ljava/lang/String;)V RETURN
|
||||
* MAXSTACK = 2 MAXLOCALS = 1 }
|
||||
* }</pre>
|
||||
* </pre>
|
||||
*
|
||||
* </blockquote> where {@code Hello} is defined by:
|
||||
* </blockquote> where <tt>Hello</tt> is defined by:
|
||||
* <p>
|
||||
* <blockquote>
|
||||
*
|
||||
* <pre>{@code
|
||||
* <pre>
|
||||
* public class Hello {
|
||||
*
|
||||
* public static void main(String[] args) {
|
||||
* System.out.println("hello");
|
||||
* System.out.println("hello");
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
* </pre>
|
||||
*
|
||||
* </blockquote>
|
||||
*
|
||||
@ -135,7 +137,7 @@ public final class TraceClassVisitor extends ClassVisitor {
|
||||
*
|
||||
* @param cv
|
||||
* the {@link ClassVisitor} to which this visitor delegates
|
||||
* calls. May be {@code null}.
|
||||
* calls. May be <tt>null</tt>.
|
||||
* @param pw
|
||||
* the print writer to be used to print the class.
|
||||
*/
|
||||
@ -148,7 +150,7 @@ public final class TraceClassVisitor extends ClassVisitor {
|
||||
*
|
||||
* @param cv
|
||||
* the {@link ClassVisitor} to which this visitor delegates
|
||||
* calls. May be {@code null}.
|
||||
* calls. May be <tt>null</tt>.
|
||||
* @param p
|
||||
* the object that actually converts visit events into text.
|
||||
* @param pw
|
||||
|
@ -70,7 +70,7 @@ import jdk.internal.org.objectweb.asm.signature.SignatureVisitor;
|
||||
*/
|
||||
public final class TraceSignatureVisitor extends SignatureVisitor {
|
||||
|
||||
private final StringBuffer declaration;
|
||||
private final StringBuilder declaration;
|
||||
|
||||
private boolean isInterface;
|
||||
|
||||
@ -82,9 +82,9 @@ public final class TraceSignatureVisitor extends SignatureVisitor {
|
||||
|
||||
private boolean seenInterface;
|
||||
|
||||
private StringBuffer returnType;
|
||||
private StringBuilder returnType;
|
||||
|
||||
private StringBuffer exceptions;
|
||||
private StringBuilder exceptions;
|
||||
|
||||
/**
|
||||
* Stack used to keep track of class types that have arguments. Each element
|
||||
@ -106,10 +106,10 @@ public final class TraceSignatureVisitor extends SignatureVisitor {
|
||||
public TraceSignatureVisitor(final int access) {
|
||||
super(Opcodes.ASM5);
|
||||
isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
|
||||
this.declaration = new StringBuffer();
|
||||
this.declaration = new StringBuilder();
|
||||
}
|
||||
|
||||
private TraceSignatureVisitor(final StringBuffer buf) {
|
||||
private TraceSignatureVisitor(final StringBuilder buf) {
|
||||
super(Opcodes.ASM5);
|
||||
this.declaration = buf;
|
||||
}
|
||||
@ -175,14 +175,14 @@ public final class TraceSignatureVisitor extends SignatureVisitor {
|
||||
declaration.append('(');
|
||||
}
|
||||
declaration.append(')');
|
||||
returnType = new StringBuffer();
|
||||
returnType = new StringBuilder();
|
||||
return new TraceSignatureVisitor(returnType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SignatureVisitor visitExceptionType() {
|
||||
if (exceptions == null) {
|
||||
exceptions = new StringBuffer();
|
||||
exceptions = new StringBuilder();
|
||||
} else {
|
||||
exceptions.append(", ");
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
Path: .
|
||||
Working Copy Root Path: /hudson/jobs/objectweb-init/workspace/asm-svn-2014-10-15
|
||||
Working Copy Root Path: /hudson/jobs/objectweb-init/workspace/asm-svn-2016-01-25
|
||||
URL: file:///svnroot/asm/trunk/asm
|
||||
Repository Root: file:///svnroot/asm
|
||||
Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9
|
||||
Revision: 1772
|
||||
Revision: 1795
|
||||
Node Kind: directory
|
||||
Schedule: normal
|
||||
Last Changed Author: ebruneton
|
||||
Last Changed Rev: 1772
|
||||
Last Changed Date: 2014-09-06 09:13:07 +0200 (Sat, 06 Sep 2014)
|
||||
Last Changed Rev: 1795
|
||||
Last Changed Date: 2016-01-24 14:17:10 +0100 (Sun, 24 Jan 2016)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
@ -115,10 +115,31 @@ final class RSAClientKeyExchange extends HandshakeMessage {
|
||||
|
||||
byte[] encoded = null;
|
||||
try {
|
||||
boolean needFailover = false;
|
||||
Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
|
||||
boolean needFailover = !KeyUtil.isOracleJCEProvider(
|
||||
cipher.getProvider().getName());
|
||||
try {
|
||||
// Try UNWRAP_MODE mode firstly.
|
||||
cipher.init(Cipher.UNWRAP_MODE, privateKey,
|
||||
new TlsRsaPremasterSecretParameterSpec(
|
||||
maxVersion.v, currentVersion.v),
|
||||
generator);
|
||||
|
||||
// The provider selection can be delayed, please don't call
|
||||
// any Cipher method before the call to Cipher.init().
|
||||
needFailover = !KeyUtil.isOracleJCEProvider(
|
||||
cipher.getProvider().getName());
|
||||
} catch (InvalidKeyException | UnsupportedOperationException iue) {
|
||||
if (debug != null && Debug.isOn("handshake")) {
|
||||
System.out.println("The Cipher provider " +
|
||||
cipher.getProvider().getName() +
|
||||
" caused exception: " + iue.getMessage());
|
||||
}
|
||||
|
||||
needFailover = true;
|
||||
}
|
||||
|
||||
if (needFailover) {
|
||||
// Use DECRYPT_MODE and dispose the previous initialization.
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
boolean failed = false;
|
||||
try {
|
||||
@ -134,10 +155,7 @@ final class RSAClientKeyExchange extends HandshakeMessage {
|
||||
maxVersion.v, currentVersion.v,
|
||||
encoded, generator);
|
||||
} else {
|
||||
cipher.init(Cipher.UNWRAP_MODE, privateKey,
|
||||
new TlsRsaPremasterSecretParameterSpec(
|
||||
maxVersion.v, currentVersion.v),
|
||||
generator);
|
||||
// the cipher should have been initialized
|
||||
preMaster = (SecretKey)cipher.unwrap(encrypted,
|
||||
"TlsRsaPremasterSecret", Cipher.SECRET_KEY);
|
||||
}
|
||||
|
@ -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
|
||||
@ -365,17 +365,6 @@ public final class SSLSocketImpl extends BaseSSLSocketImpl {
|
||||
/* Class and subclass dynamic debugging support */
|
||||
private static final Debug debug = Debug.getInstance("ssl");
|
||||
|
||||
/*
|
||||
* Is it the first application record to write?
|
||||
*/
|
||||
private boolean isFirstAppOutputRecord = true;
|
||||
|
||||
/*
|
||||
* If AppOutputStream needs to delay writes of small packets, we
|
||||
* will use this to store the data until we actually do the write.
|
||||
*/
|
||||
private ByteArrayOutputStream heldRecordBuffer = null;
|
||||
|
||||
/*
|
||||
* Whether local cipher suites preference in server side should be
|
||||
* honored during handshaking?
|
||||
@ -998,9 +987,21 @@ public final class SSLSocketImpl extends BaseSSLSocketImpl {
|
||||
Plaintext plainText = null;
|
||||
while (((state = getConnectionState()) != cs_CLOSED) &&
|
||||
(state != cs_ERROR) && (state != cs_APP_CLOSED)) {
|
||||
// clean the buffer
|
||||
|
||||
/*
|
||||
* clean the buffer and check if it is too small, e.g. because
|
||||
* the AppInputStream did not have the chance to see the
|
||||
* current packet length but rather something like that of the
|
||||
* handshake before. In that case we return 0 at this point to
|
||||
* give the caller the chance to adjust the buffer.
|
||||
*/
|
||||
if (buffer != null) {
|
||||
buffer.clear();
|
||||
|
||||
if (buffer.remaining() <
|
||||
inputRecord.bytesInCompletePacket(sockInput)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1408,7 +1408,7 @@ InflateFully(jzfile *zip, jzentry *entry, void *buf, char **msg)
|
||||
case Z_OK:
|
||||
break;
|
||||
case Z_STREAM_END:
|
||||
if (count != 0 || strm.total_out != entry->size) {
|
||||
if (count != 0 || strm.total_out != (uInt)entry->size) {
|
||||
*msg = "inflateFully: Unexpected end of stream";
|
||||
inflateEnd(&strm);
|
||||
return JNI_FALSE;
|
||||
@ -1528,7 +1528,7 @@ ZIP_InflateFully(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pm
|
||||
case Z_OK:
|
||||
break;
|
||||
case Z_STREAM_END:
|
||||
if (strm.total_out != outLen) {
|
||||
if (strm.total_out != (uInt)outLen) {
|
||||
*pmsg = "INFLATER_inflateFully: Unexpected end of stream";
|
||||
inflateEnd(&strm);
|
||||
return JNI_FALSE;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 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,10 +23,6 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
@ -77,21 +73,6 @@ static jfieldID backupResult_bytesTransferred;
|
||||
static jfieldID backupResult_context;
|
||||
|
||||
|
||||
/**
|
||||
* Win32 APIs not available in Windows XP
|
||||
*/
|
||||
typedef HANDLE (WINAPI* FindFirstStream_Proc)(LPCWSTR, STREAM_INFO_LEVELS, LPVOID, DWORD);
|
||||
typedef BOOL (WINAPI* FindNextStream_Proc)(HANDLE, LPVOID);
|
||||
|
||||
typedef BOOLEAN (WINAPI* CreateSymbolicLinkProc) (LPCWSTR, LPCWSTR, DWORD);
|
||||
typedef BOOL (WINAPI* GetFinalPathNameByHandleProc) (HANDLE, LPWSTR, DWORD, DWORD);
|
||||
|
||||
static FindFirstStream_Proc FindFirstStream_func;
|
||||
static FindNextStream_Proc FindNextStream_func;
|
||||
|
||||
static CreateSymbolicLinkProc CreateSymbolicLink_func;
|
||||
static GetFinalPathNameByHandleProc GetFinalPathNameByHandle_func;
|
||||
|
||||
static void throwWindowsException(JNIEnv* env, DWORD lastError) {
|
||||
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
|
||||
"(I)V", lastError);
|
||||
@ -108,7 +89,6 @@ JNIEXPORT void JNICALL
|
||||
Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
|
||||
{
|
||||
jclass clazz;
|
||||
HMODULE h;
|
||||
|
||||
clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstFile");
|
||||
CHECK_NULL(clazz);
|
||||
@ -175,24 +155,6 @@ Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
|
||||
CHECK_NULL(backupResult_bytesTransferred);
|
||||
backupResult_context = (*env)->GetFieldID(env, clazz, "context", "J");
|
||||
CHECK_NULL(backupResult_context);
|
||||
|
||||
// get handle to kernel32
|
||||
if (GetModuleHandleExW((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
|
||||
(LPCWSTR)&CreateFileW, &h) != 0)
|
||||
{
|
||||
// requires Windows Server 2003 or newer
|
||||
FindFirstStream_func =
|
||||
(FindFirstStream_Proc)GetProcAddress(h, "FindFirstStreamW");
|
||||
FindNextStream_func =
|
||||
(FindNextStream_Proc)GetProcAddress(h, "FindNextStreamW");
|
||||
|
||||
// requires Windows Vista or newer
|
||||
CreateSymbolicLink_func =
|
||||
(CreateSymbolicLinkProc)GetProcAddress(h, "CreateSymbolicLinkW");
|
||||
GetFinalPathNameByHandle_func =
|
||||
(GetFinalPathNameByHandleProc)GetProcAddress(h, "GetFinalPathNameByHandleW");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
@ -404,12 +366,7 @@ Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstStream0(JNIEnv* env, jclass thi
|
||||
LPCWSTR lpFileName = jlong_to_ptr(address);
|
||||
HANDLE handle;
|
||||
|
||||
if (FindFirstStream_func == NULL) {
|
||||
JNU_ThrowInternalError(env, "Should not get here");
|
||||
return;
|
||||
}
|
||||
|
||||
handle = (*FindFirstStream_func)(lpFileName, FindStreamInfoStandard, &data, 0);
|
||||
handle = FindFirstStreamW(lpFileName, FindStreamInfoStandard, &data, 0);
|
||||
if (handle != INVALID_HANDLE_VALUE) {
|
||||
jstring name = (*env)->NewString(env, data.cStreamName, (jsize)wcslen(data.cStreamName));
|
||||
if (name == NULL)
|
||||
@ -433,12 +390,7 @@ Java_sun_nio_fs_WindowsNativeDispatcher_FindNextStream(JNIEnv* env, jclass this,
|
||||
WIN32_FIND_STREAM_DATA data;
|
||||
HANDLE h = (HANDLE)jlong_to_ptr(handle);
|
||||
|
||||
if (FindNextStream_func == NULL) {
|
||||
JNU_ThrowInternalError(env, "Should not get here");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((*FindNextStream_func)(h, &data) != 0) {
|
||||
if (FindNextStreamW(h, &data) != 0) {
|
||||
return (*env)->NewString(env, data.cStreamName, (jsize)wcslen(data.cStreamName));
|
||||
} else {
|
||||
if (GetLastError() != ERROR_HANDLE_EOF)
|
||||
@ -1087,13 +1039,8 @@ Java_sun_nio_fs_WindowsNativeDispatcher_CreateSymbolicLink0(JNIEnv* env,
|
||||
LPCWSTR link = jlong_to_ptr(linkAddress);
|
||||
LPCWSTR target = jlong_to_ptr(targetAddress);
|
||||
|
||||
if (CreateSymbolicLink_func == NULL) {
|
||||
JNU_ThrowInternalError(env, "Should not get here");
|
||||
return;
|
||||
}
|
||||
|
||||
/* On Windows 64-bit this appears to succeed even when there is insufficient privileges */
|
||||
if ((*CreateSymbolicLink_func)(link, target, (DWORD)flags) == 0)
|
||||
if (CreateSymbolicLinkW(link, target, (DWORD)flags) == 0)
|
||||
throwWindowsException(env, GetLastError());
|
||||
}
|
||||
|
||||
@ -1155,12 +1102,7 @@ Java_sun_nio_fs_WindowsNativeDispatcher_GetFinalPathNameByHandle(JNIEnv* env,
|
||||
HANDLE h = (HANDLE)jlong_to_ptr(handle);
|
||||
DWORD len;
|
||||
|
||||
if (GetFinalPathNameByHandle_func == NULL) {
|
||||
JNU_ThrowInternalError(env, "Should not get here");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = (*GetFinalPathNameByHandle_func)(h, path, MAX_PATH, 0);
|
||||
len = GetFinalPathNameByHandleW(h, path, MAX_PATH, 0);
|
||||
if (len > 0) {
|
||||
if (len < MAX_PATH) {
|
||||
rv = (*env)->NewString(env, (const jchar *)path, (jsize)len);
|
||||
@ -1168,7 +1110,7 @@ Java_sun_nio_fs_WindowsNativeDispatcher_GetFinalPathNameByHandle(JNIEnv* env,
|
||||
len += 1; /* return length does not include terminator */
|
||||
lpBuf = (WCHAR*)malloc(len * sizeof(WCHAR));
|
||||
if (lpBuf != NULL) {
|
||||
len = (*GetFinalPathNameByHandle_func)(h, lpBuf, len, 0);
|
||||
len = GetFinalPathNameByHandleW(h, lpBuf, len, 0);
|
||||
if (len > 0) {
|
||||
rv = (*env)->NewString(env, (const jchar *)lpBuf, (jsize)len);
|
||||
} else {
|
||||
|
@ -24,7 +24,6 @@
|
||||
package java.net.http;
|
||||
|
||||
import java.util.Locale;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
/**
|
||||
* -Djava.net.HttpClient.log=errors,requests,headers,frames[:type:type2:..],content
|
||||
@ -35,9 +34,11 @@ import sun.util.logging.PlatformLogger;
|
||||
*
|
||||
* Logger name is "java.net.http.HttpClient"
|
||||
*/
|
||||
class Log {
|
||||
// implements System.Logger in order to be skipped when printing the caller's
|
||||
// information
|
||||
abstract class Log implements System.Logger {
|
||||
|
||||
final static String logProp = "java.net.http.HttpClient.log";
|
||||
static final String logProp = "java.net.http.HttpClient.log";
|
||||
|
||||
public static final int OFF = 0;
|
||||
public static final int ERRORS = 0x1;
|
||||
@ -55,7 +56,7 @@ class Log {
|
||||
public static final int ALL = CONTROL| DATA | WINDOW_UPDATES;
|
||||
static int frametypes;
|
||||
|
||||
static sun.util.logging.PlatformLogger logger;
|
||||
static final System.Logger logger;
|
||||
|
||||
static {
|
||||
String s = Utils.getNetProperty(logProp);
|
||||
@ -111,7 +112,9 @@ class Log {
|
||||
}
|
||||
}
|
||||
if (logging != OFF) {
|
||||
logger = PlatformLogger.getLogger("java.net.http.HttpClient");
|
||||
logger = System.getLogger("java.net.http.HttpClient");
|
||||
} else {
|
||||
logger = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,34 +140,38 @@ class Log {
|
||||
|
||||
static void logError(String s) {
|
||||
if (errors())
|
||||
logger.info("ERROR: " + s);
|
||||
logger.log(Level.INFO, "ERROR: " + s);
|
||||
}
|
||||
|
||||
static void logError(Throwable t) {
|
||||
if (errors()) {
|
||||
String s = Utils.stackTrace(t);
|
||||
logger.info("ERROR: " + s);
|
||||
logger.log(Level.INFO, "ERROR: " + s);
|
||||
}
|
||||
}
|
||||
|
||||
static void logSSL(String s) {
|
||||
if (ssl())
|
||||
logger.info("SSL: " + s);
|
||||
logger.log(Level.INFO, "SSL: " + s);
|
||||
}
|
||||
|
||||
static void logRequest(String s) {
|
||||
if (requests())
|
||||
logger.info("REQUEST: " + s);
|
||||
logger.log(Level.INFO, "REQUEST: " + s);
|
||||
}
|
||||
|
||||
static void logResponse(String s) {
|
||||
if (requests())
|
||||
logger.info("RESPONSE: " + s);
|
||||
logger.log(Level.INFO, "RESPONSE: " + s);
|
||||
}
|
||||
|
||||
static void logHeaders(String s) {
|
||||
if (headers())
|
||||
logger.info("HEADERS: " + s);
|
||||
logger.log(Level.INFO, "HEADERS: " + s);
|
||||
}
|
||||
|
||||
// not instantiable
|
||||
private Log() {}
|
||||
|
||||
// END HTTP2
|
||||
}
|
||||
|
@ -155,9 +155,13 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
|
||||
|
||||
@Override
|
||||
public void configure(Map<String, String> config) {
|
||||
priorityList = Arrays.stream(config.get(NAME).split(","))
|
||||
.map(Locale.LanguageRange::new)
|
||||
.collect(Collectors.toList());
|
||||
try {
|
||||
priorityList = Arrays.stream(config.get(NAME).split(","))
|
||||
.map(Locale.LanguageRange::new)
|
||||
.collect(Collectors.toList());
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new PluginException(iae.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -168,7 +172,7 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
|
||||
// jdk.localedata module validation
|
||||
Set<String> packages = module.getAllPackages();
|
||||
if (!packages.containsAll(LOCALEDATA_PACKAGES)) {
|
||||
throw new PluginException("Missing locale data packages in jdk.localedata:\n\t" +
|
||||
throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".missingpackages") +
|
||||
LOCALEDATA_PACKAGES.stream()
|
||||
.filter(pn -> !packages.contains(pn))
|
||||
.collect(Collectors.joining(",\n\t")));
|
||||
@ -186,6 +190,10 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
|
||||
|
||||
filtered = filterLocales(available);
|
||||
|
||||
if (filtered.isEmpty()) {
|
||||
throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".nomatchinglocales"));
|
||||
}
|
||||
|
||||
try {
|
||||
String value = META_FILES + filtered.stream()
|
||||
.map(s -> includeLocaleFilePatterns(s))
|
||||
|
@ -68,9 +68,18 @@ zip.argument=[comma separated list of resource paths]
|
||||
|
||||
zip.description=ZIP Compression
|
||||
|
||||
include-locales.argument=<langtag>[,<langtag>]*
|
||||
include-locales.argument=\
|
||||
<langtag>[,<langtag>]*
|
||||
|
||||
include-locales.description=BCP 47 language tags separated by a comma, allowing locale matching\ndefined in RFC 4647. eg: en,ja,*-IN
|
||||
include-locales.description=\
|
||||
BCP 47 language tags separated by a comma, allowing locale matching\n\
|
||||
defined in RFC 4647. eg: en,ja,*-IN
|
||||
|
||||
include-locales.missingpackages=\
|
||||
Missing locale data packages in jdk.localedata:\n\t
|
||||
|
||||
include-locales.nomatchinglocales=\
|
||||
No matching locales found. Check the specified pattern.
|
||||
|
||||
main.status.ok=Functional.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, 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
|
||||
@ -67,7 +67,7 @@ public interface RuntimeConstants {
|
||||
/* Class File Constants */
|
||||
int JAVA_MAGIC = 0xcafebabe;
|
||||
int JAVA_MIN_SUPPORTED_VERSION = 45;
|
||||
int JAVA_MAX_SUPPORTED_VERSION = 52;
|
||||
int JAVA_MAX_SUPPORTED_VERSION = 53;
|
||||
int JAVA_MAX_SUPPORTED_MINOR_VERSION = 0;
|
||||
|
||||
/* Generate class file version for 1.1 by default */
|
||||
|
@ -32,6 +32,7 @@ tier1 = \
|
||||
-java/util/WeakHashMap/GCDuringIteration.java \
|
||||
-java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \
|
||||
-java/util/concurrent/forkjoin/FJExceptionTableLeak.java \
|
||||
-java/util/TimeZone/Bug6772689.java \
|
||||
sun/nio/cs/ISO8859x.java \
|
||||
java/nio/Buffer \
|
||||
com/sun/crypto/provider/Cipher \
|
||||
@ -42,6 +43,7 @@ tier2 = \
|
||||
java/util/WeakHashMap/GCDuringIteration.java \
|
||||
java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java \
|
||||
java/util/concurrent/forkjoin/FJExceptionTableLeak.java \
|
||||
java/util/TimeZone/Bug6772689.java \
|
||||
:jdk_io \
|
||||
:jdk_nio \
|
||||
-sun/nio/cs/ISO8859x.java \
|
||||
@ -492,7 +494,8 @@ needs_jdk = \
|
||||
sun/reflect/CallerSensitive/MissingCallerSensitive.java \
|
||||
sun/security/util/Resources/NewNamesFormat.java \
|
||||
vm/verifier/defaultMethods/DefaultMethodRegressionTestsRun.java \
|
||||
javax/xml/ws/clientjar/TestWsImport.java
|
||||
javax/xml/ws/clientjar/TestWsImport.java \
|
||||
javax/xml/bind/xjc/8145039/JaxbMarshallTest.java
|
||||
|
||||
# JRE adds further tests to compact3
|
||||
#
|
||||
|
46
jdk/test/com/sun/jdi/BadAgentPath.java
Normal file
46
jdk/test/com/sun/jdi/BadAgentPath.java
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 jdk.testlibrary.OutputAnalyzer;
|
||||
import jdk.testlibrary.ProcessTools;
|
||||
import jdk.testlibrary.Utils;
|
||||
|
||||
/* @test
|
||||
* @bug 8147456
|
||||
* @summary Check that providing a non-existing -agentpath gives a proper error.
|
||||
* @author Sharath Ballal
|
||||
*
|
||||
* @library /lib/testlibrary
|
||||
* @modules java.management
|
||||
* @build jdk.testlibrary.*
|
||||
* @build BadAgentPath
|
||||
* @run driver BadAgentPath
|
||||
*/
|
||||
|
||||
public class BadAgentPath {
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
OutputAnalyzer output = ProcessTools.executeTestJvm("-agentpath:/badAgent/agent", "-version");
|
||||
output.shouldContain("Could not find agent library /badAgent/agent");
|
||||
}
|
||||
}
|
80
jdk/test/java/lang/invoke/t8150782/TestAccessClass.java
Normal file
80
jdk/test/java/lang/invoke/t8150782/TestAccessClass.java
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @compile TestAccessClass.java TestCls.java
|
||||
* @run testng/othervm -ea -esa test.java.lang.invoke.t8150782.TestAccessClass
|
||||
*/
|
||||
package test.java.lang.invoke.t8150782;
|
||||
|
||||
import java.lang.invoke.*;
|
||||
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
|
||||
import static org.testng.AssertJUnit.*;
|
||||
|
||||
import org.testng.annotations.*;
|
||||
|
||||
public class TestAccessClass {
|
||||
|
||||
private static boolean initializedClass1;
|
||||
|
||||
private static class Class1 {
|
||||
static {
|
||||
initializedClass1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializerNotRun() throws IllegalAccessException {
|
||||
lookup().accessClass(Class1.class);
|
||||
assertFalse(initializedClass1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsSameClass() throws IllegalAccessException, ClassNotFoundException {
|
||||
Class<?> aClass = lookup().accessClass(Class1.class);
|
||||
assertEquals(Class1.class, aClass);
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
Object[][] illegalAccessAccess() {
|
||||
return new Object[][] {
|
||||
{publicLookup(), Class1.class},
|
||||
{publicLookup(), TestCls.getPrivateSIC()}
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "illegalAccessAccess", expectedExceptions = {IllegalAccessException.class})
|
||||
public void illegalAccessExceptionTest(Lookup lookup, Class<?> klass) throws IllegalAccessException, ClassNotFoundException {
|
||||
lookup.accessClass(klass);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void okAccess() throws IllegalAccessException {
|
||||
lookup().accessClass(TestCls.getPrivateSIC());
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,9 +22,17 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package test.java.lang.invoke.t8150782;
|
||||
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
|
||||
public class TestCls {
|
||||
|
||||
public static final Lookup LOOKUP = lookup();
|
||||
|
||||
private static class PrivateSIC {}
|
||||
public static Class getPrivateSIC() { return PrivateSIC.class; }
|
||||
public static Lookup getLookupForPrivateSIC() { return lookup(); }
|
||||
|
||||
module jdk.deploy.osx {
|
||||
requires java.desktop;
|
||||
requires java.scripting;
|
||||
}
|
||||
|
90
jdk/test/java/lang/invoke/t8150782/TestFindClass.java
Normal file
90
jdk/test/java/lang/invoke/t8150782/TestFindClass.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @compile TestFindClass.java TestCls.java
|
||||
* @run testng/othervm -ea -esa test.java.lang.invoke.t8150782.TestFindClass
|
||||
*/
|
||||
package test.java.lang.invoke.t8150782;
|
||||
|
||||
import java.lang.invoke.*;
|
||||
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
|
||||
import static org.testng.AssertJUnit.*;
|
||||
|
||||
import org.testng.annotations.*;
|
||||
|
||||
public class TestFindClass {
|
||||
|
||||
private static final String PACKAGE_PREFIX = "test.java.lang.invoke.t8150782.";
|
||||
|
||||
private static boolean initializedClass1;
|
||||
|
||||
private static class Class1 {
|
||||
static {
|
||||
initializedClass1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initializerNotRun() throws IllegalAccessException, ClassNotFoundException {
|
||||
lookup().findClass(PACKAGE_PREFIX + "TestFindClass$Class1");
|
||||
assertFalse(initializedClass1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsRequestedClass() throws IllegalAccessException, ClassNotFoundException {
|
||||
Class<?> aClass = lookup().findClass(PACKAGE_PREFIX + "TestFindClass$Class1");
|
||||
assertEquals(Class1.class, aClass);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = {ClassNotFoundException.class})
|
||||
public void classNotFoundExceptionTest() throws IllegalAccessException, ClassNotFoundException {
|
||||
lookup().findClass(PACKAGE_PREFIX + "TestFindClass$NonExistent");
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
Object[][] illegalAccessFind() {
|
||||
return new Object[][] {
|
||||
{publicLookup(), PACKAGE_PREFIX + "TestFindClass$Class1"},
|
||||
{publicLookup(), PACKAGE_PREFIX + "TestCls$PrivateSIC"}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Assertion: @throws IllegalAccessException if the class is not accessible, using the allowed access modes.
|
||||
*/
|
||||
@Test(dataProvider = "illegalAccessFind", expectedExceptions = {ClassNotFoundException.class})
|
||||
public void illegalAccessExceptionTest(Lookup lookup, String className) throws IllegalAccessException, ClassNotFoundException {
|
||||
lookup.findClass(className);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void okAccess() throws IllegalAccessException, ClassNotFoundException {
|
||||
lookup().findClass(PACKAGE_PREFIX + "TestCls$PrivateSIC");
|
||||
}
|
||||
|
||||
}
|
70
jdk/test/java/lang/invoke/t8150782/TestLookup.java
Normal file
70
jdk/test/java/lang/invoke/t8150782/TestLookup.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @compile TestLookup.java TestCls.java
|
||||
* @run testng/othervm -ea -esa test.java.lang.invoke.t8150782.TestLookup
|
||||
*/
|
||||
package test.java.lang.invoke.t8150782;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static java.lang.invoke.MethodHandles.*;
|
||||
|
||||
import static org.testng.AssertJUnit.*;
|
||||
|
||||
public class TestLookup {
|
||||
|
||||
@Test
|
||||
public void testClassLoaderChange() {
|
||||
Lookup lookup = lookup();
|
||||
assertNotNull(lookup.lookupClass().getClassLoader());
|
||||
Lookup lookup2 = lookup.in(Object.class);
|
||||
assertNull(lookup2.lookupClass().getClassLoader());
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = {ClassNotFoundException.class})
|
||||
public void testPublicCannotLoadUserClass() throws IllegalAccessException, ClassNotFoundException {
|
||||
Lookup lookup = publicLookup();
|
||||
lookup.findClass("test.java.lang.invoke.t8150782.TestCls");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicCanLoadSystemClass() throws IllegalAccessException, ClassNotFoundException {
|
||||
Lookup lookup = publicLookup();
|
||||
lookup.findClass("java.util.HashMap");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicInChangesClassLoader() {
|
||||
Lookup lookup = publicLookup();
|
||||
// Temporarily exclude until 8148697 is resolved, specifically:
|
||||
// "publicLookup changed so that the lookup class is in an unnamed module"
|
||||
//assertNull(lookup.lookupClass().getClassLoader());
|
||||
Lookup lookup2 = lookup.in(TestCls.class);
|
||||
assertNotNull(lookup2.lookupClass().getClassLoader());
|
||||
}
|
||||
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
/**
|
||||
* @test
|
||||
* @build ModuleSetAccessibleTest
|
||||
* @modules java.base/sun.misc
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @run testng ModuleSetAccessibleTest
|
||||
* @summary Test java.lang.reflect.AccessibleObject with modules
|
||||
*/
|
||||
@ -38,7 +38,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Module;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,6 +23,7 @@
|
||||
|
||||
/* @test
|
||||
* @bug 4460583 4470470 4840199 6419424 6710579 6596323 6824135 6395224 7142919
|
||||
* 8151582
|
||||
* @run main/othervm AsyncCloseAndInterrupt
|
||||
* @summary Comprehensive test of asynchronous closing and interruption
|
||||
* @author Mark Reinhold
|
||||
@ -89,7 +90,7 @@ public class AsyncCloseAndInterrupt {
|
||||
|
||||
private static void initRefuser() throws IOException {
|
||||
refuser = ServerSocketChannel.open();
|
||||
refuser.socket().bind(wildcardAddress);
|
||||
refuser.bind(wildcardAddress, 1); // use minimum backlog
|
||||
}
|
||||
|
||||
// Dead pipe source and sink
|
||||
@ -349,7 +350,7 @@ public class AsyncCloseAndInterrupt {
|
||||
|
||||
static final Op CONNECT = new Op("connect") {
|
||||
void setup() {
|
||||
waitPump("connect wait for pumping refuser ...");
|
||||
waitPump("connect waiting for pumping refuser ...");
|
||||
}
|
||||
void doIO(InterruptibleChannel ich) throws IOException {
|
||||
SocketChannel sc = (SocketChannel)ich;
|
||||
@ -361,7 +362,7 @@ public class AsyncCloseAndInterrupt {
|
||||
|
||||
static final Op FINISH_CONNECT = new Op("finishConnect") {
|
||||
void setup() {
|
||||
waitPump("finishConnect wait for pumping refuser ...");
|
||||
waitPump("finishConnect waiting for pumping refuser ...");
|
||||
}
|
||||
void doIO(InterruptibleChannel ich) throws IOException {
|
||||
SocketChannel sc = (SocketChannel)ich;
|
||||
@ -498,12 +499,11 @@ public class AsyncCloseAndInterrupt {
|
||||
private static volatile boolean pumpReady = false;
|
||||
|
||||
private static void waitPump(String msg){
|
||||
pumpReady = false;
|
||||
log.println(msg);
|
||||
|
||||
while (!pumpReady){
|
||||
sleep(200);
|
||||
}
|
||||
log.println(msg + " done");
|
||||
}
|
||||
|
||||
// Create a pump thread dedicated to saturate refuser's connection backlog
|
||||
@ -520,28 +520,34 @@ public class AsyncCloseAndInterrupt {
|
||||
|
||||
// Saturate the refuser's connection backlog so that further connection
|
||||
// attempts will be blocked
|
||||
pumpReady = false;
|
||||
while (!pumpDone) {
|
||||
SocketChannel sc = SocketChannel.open();
|
||||
sc.configureBlocking(false);
|
||||
boolean connected = sc.connect(refuser.socket().getLocalSocketAddress());
|
||||
|
||||
// Assume that the connection backlog is saturated if a
|
||||
// client cannot connect to the refuser within 50 miliseconds
|
||||
// client cannot connect to the refuser within 50 milliseconds
|
||||
long start = System.currentTimeMillis();
|
||||
while (!connected && (System.currentTimeMillis() - start < 50)) {
|
||||
while (!pumpReady && !connected
|
||||
&& (System.currentTimeMillis() - start < 50)) {
|
||||
connected = sc.finishConnect();
|
||||
}
|
||||
|
||||
if (connected) {
|
||||
// Retain so that finalizer doesn't close
|
||||
refuserClients.add(sc);
|
||||
pumpReady = false;
|
||||
} else {
|
||||
sc.close();
|
||||
pumpReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (SocketChannel sc : refuserClients) {
|
||||
sc.close();
|
||||
}
|
||||
refuser.close();
|
||||
|
||||
log.println("Stop pumping refuser ...");
|
||||
return refuserClients.size();
|
||||
}
|
||||
@ -565,8 +571,6 @@ public class AsyncCloseAndInterrupt {
|
||||
sleep(50);
|
||||
} while (!t.ready);
|
||||
|
||||
sleep(100);
|
||||
|
||||
switch (test) {
|
||||
|
||||
case TEST_INTR:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,6 +23,7 @@
|
||||
|
||||
/* @test
|
||||
* @bug 7200742
|
||||
* @key intermittent
|
||||
* @summary Test that Selector doesn't spin when changing interest ops
|
||||
*/
|
||||
|
||||
|
@ -761,6 +761,7 @@ public class TCKZonedDateTime extends AbstractDateTimeTest {
|
||||
{"2012-06-30T12:30:40-01:00[UT-01:00]", 2012, 6, 30, 12, 30, 40, 0, "UT-01:00"},
|
||||
{"2012-06-30T12:30:40-01:00[UTC-01:00]", 2012, 6, 30, 12, 30, 40, 0, "UTC-01:00"},
|
||||
{"2012-06-30T12:30:40+01:00[Europe/London]", 2012, 6, 30, 12, 30, 40, 0, "Europe/London"},
|
||||
{"2012-06-30T12:30:40+01", 2012, 6, 30, 12, 30, 40, 0, "+01:00"},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -59,11 +59,13 @@
|
||||
*/
|
||||
package tck.java.time.format;
|
||||
|
||||
import static java.time.format.DateTimeFormatter.BASIC_ISO_DATE;
|
||||
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
|
||||
import static java.time.temporal.ChronoField.HOUR_OF_DAY;
|
||||
import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
|
||||
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
|
||||
import static java.time.temporal.ChronoField.NANO_OF_SECOND;
|
||||
import static java.time.temporal.ChronoField.OFFSET_SECONDS;
|
||||
import static java.time.temporal.ChronoField.YEAR;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
@ -73,6 +75,7 @@ import java.time.YearMonth;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.format.SignStyle;
|
||||
import java.time.format.TextStyle;
|
||||
import java.time.temporal.Temporal;
|
||||
@ -339,6 +342,18 @@ public class TCKDateTimeFormatterBuilder {
|
||||
{"+HH", 2, 0, 45, "+02"},
|
||||
{"+HH", 2, 30, 45, "+02"},
|
||||
|
||||
{"+HHmm", 2, 0, 0, "+02"},
|
||||
{"+HHmm", -2, 0, 0, "-02"},
|
||||
{"+HHmm", 2, 30, 0, "+0230"},
|
||||
{"+HHmm", 2, 0, 45, "+02"},
|
||||
{"+HHmm", 2, 30, 45, "+0230"},
|
||||
|
||||
{"+HH:mm", 2, 0, 0, "+02"},
|
||||
{"+HH:mm", -2, 0, 0, "-02"},
|
||||
{"+HH:mm", 2, 30, 0, "+02:30"},
|
||||
{"+HH:mm", 2, 0, 45, "+02"},
|
||||
{"+HH:mm", 2, 30, 45, "+02:30"},
|
||||
|
||||
{"+HHMM", 2, 0, 0, "+0200"},
|
||||
{"+HHMM", -2, 0, 0, "-0200"},
|
||||
{"+HHMM", 2, 30, 0, "+0230"},
|
||||
@ -374,6 +389,20 @@ public class TCKDateTimeFormatterBuilder {
|
||||
{"+HH:MM:SS", 2, 30, 0, "+02:30:00"},
|
||||
{"+HH:MM:SS", 2, 0, 45, "+02:00:45"},
|
||||
{"+HH:MM:SS", 2, 30, 45, "+02:30:45"},
|
||||
|
||||
{"+HHmmss", 2, 0, 0, "+02"},
|
||||
{"+HHmmss", -2, 0, 0, "-02"},
|
||||
{"+HHmmss", 2, 30, 0, "+0230"},
|
||||
{"+HHmmss", 2, 0, 45, "+020045"},
|
||||
{"+HHmmss", 2, 30, 45, "+023045"},
|
||||
|
||||
{"+HH:mm:ss", 2, 0, 0, "+02"},
|
||||
{"+HH:mm:ss", -2, 0, 0, "-02"},
|
||||
{"+HH:mm:ss", 2, 30, 0, "+02:30"},
|
||||
{"+HH:mm:ss", 2, 0, 45, "+02:00:45"},
|
||||
{"+HH:mm:ss", 2, 30, 45, "+02:30:45"},
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@ -878,4 +907,82 @@ public class TCKDateTimeFormatterBuilder {
|
||||
assertEquals(parsed.getLong(MINUTE_OF_HOUR), 30L);
|
||||
}
|
||||
|
||||
@DataProvider(name="lenientOffsetParseData")
|
||||
Object[][] data_lenient_offset_parse() {
|
||||
return new Object[][] {
|
||||
{"+HH", "+01", 3600},
|
||||
{"+HH", "+0101", 3660},
|
||||
{"+HH", "+010101", 3661},
|
||||
{"+HH", "+01", 3600},
|
||||
{"+HH", "+01:01", 3660},
|
||||
{"+HH", "+01:01:01", 3661},
|
||||
{"+HHmm", "+01", 3600},
|
||||
{"+HHmm", "+0101", 3660},
|
||||
{"+HHmm", "+010101", 3661},
|
||||
{"+HH:mm", "+01", 3600},
|
||||
{"+HH:mm", "+01:01", 3660},
|
||||
{"+HH:mm", "+01:01:01", 3661},
|
||||
{"+HHMM", "+01", 3600},
|
||||
{"+HHMM", "+0101", 3660},
|
||||
{"+HHMM", "+010101", 3661},
|
||||
{"+HH:MM", "+01", 3600},
|
||||
{"+HH:MM", "+01:01", 3660},
|
||||
{"+HH:MM", "+01:01:01", 3661},
|
||||
{"+HHMMss", "+01", 3600},
|
||||
{"+HHMMss", "+0101", 3660},
|
||||
{"+HHMMss", "+010101", 3661},
|
||||
{"+HH:MM:ss", "+01", 3600},
|
||||
{"+HH:MM:ss", "+01:01", 3660},
|
||||
{"+HH:MM:ss", "+01:01:01", 3661},
|
||||
{"+HHMMSS", "+01", 3600},
|
||||
{"+HHMMSS", "+0101", 3660},
|
||||
{"+HHMMSS", "+010101", 3661},
|
||||
{"+HH:MM:SS", "+01", 3600},
|
||||
{"+HH:MM:SS", "+01:01", 3660},
|
||||
{"+HH:MM:SS", "+01:01:01", 3661},
|
||||
{"+HHmmss", "+01", 3600},
|
||||
{"+HHmmss", "+0101", 3660},
|
||||
{"+HHmmss", "+010101", 3661},
|
||||
{"+HH:mm:ss", "+01", 3600},
|
||||
{"+HH:mm:ss", "+01:01", 3660},
|
||||
{"+HH:mm:ss", "+01:01:01", 3661},
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider="lenientOffsetParseData")
|
||||
public void test_lenient_offset_parse_1(String pattern, String offset, int offsetSeconds) {
|
||||
assertEquals(new DateTimeFormatterBuilder().parseLenient().appendOffset(pattern, "Z").toFormatter().parse(offset).get(OFFSET_SECONDS),
|
||||
offsetSeconds);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_lenient_offset_parse_2() {
|
||||
assertEquals(new DateTimeFormatterBuilder().parseLenient().appendOffsetId().toFormatter().parse("+01").get(OFFSET_SECONDS),
|
||||
3600);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions=DateTimeParseException.class)
|
||||
public void test_strict_appendOffsetId() {
|
||||
assertEquals(new DateTimeFormatterBuilder().appendOffsetId().toFormatter().parse("+01").get(OFFSET_SECONDS),
|
||||
3600);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions=DateTimeParseException.class)
|
||||
public void test_strict_appendOffset_1() {
|
||||
assertEquals(new DateTimeFormatterBuilder().appendOffset("+HH:MM:ss", "Z").toFormatter().parse("+01").get(OFFSET_SECONDS),
|
||||
3600);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions=DateTimeParseException.class)
|
||||
public void test_strict_appendOffset_2() {
|
||||
assertEquals(new DateTimeFormatterBuilder().appendOffset("+HHMMss", "Z").toFormatter().parse("+01").get(OFFSET_SECONDS),
|
||||
3600);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_basic_iso_date() {
|
||||
assertEquals(BASIC_ISO_DATE.parse("20021231+01").get(OFFSET_SECONDS), 3600);
|
||||
assertEquals(BASIC_ISO_DATE.parse("20021231+0101").get(OFFSET_SECONDS), 3660);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -199,6 +199,30 @@ public class TCKOffsetPrinterParser {
|
||||
{"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-00:23:00"},
|
||||
{"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-01:23:45"},
|
||||
{"+HH:MM:SS", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00:00:45"},
|
||||
|
||||
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
|
||||
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+01"},
|
||||
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+01:23"},
|
||||
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+00:23"},
|
||||
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+01:23:45"},
|
||||
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00:00:45"},
|
||||
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-01"},
|
||||
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-01:23"},
|
||||
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-00:23"},
|
||||
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-01:23:45"},
|
||||
{"+HH:mm:ss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-00:00:45"},
|
||||
|
||||
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_UTC, "Z"},
|
||||
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0100, "+01"},
|
||||
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0123, "+0123"},
|
||||
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P0023, "+0023"},
|
||||
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P012345, "+012345"},
|
||||
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_P000045, "+000045"},
|
||||
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0100, "-01"},
|
||||
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0123, "-0123"},
|
||||
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M0023, "-0023"},
|
||||
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M012345, "-012345"},
|
||||
{"+HHmmss", "Z", DT_2012_06_30_12_30_40, OFFSET_M000045, "-000045"},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -79,19 +79,24 @@ import java.time.YearMonth;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.chrono.Chronology;
|
||||
import java.time.chrono.ThaiBuddhistChronology;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.format.DecimalStyle;
|
||||
import java.time.format.SignStyle;
|
||||
import java.time.format.TextStyle;
|
||||
import java.time.temporal.Temporal;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Test DateTimeFormatter.
|
||||
* @bug 8085887
|
||||
*/
|
||||
@Test
|
||||
public class TestDateTimeFormatter {
|
||||
@ -196,4 +201,75 @@ public class TestDateTimeFormatter {
|
||||
assertTrue(msg.contains("11:30:56"), msg);
|
||||
}
|
||||
|
||||
@DataProvider(name="nozone_exception_cases")
|
||||
Object[][] exceptionCases() {
|
||||
return new Object[][] {
|
||||
{LocalDateTime.of(2000, 1, 1, 1, 1), "z", "ZoneId"},
|
||||
{OffsetDateTime.of(2000, 1, 1, 3, 3, 3, 0, ZoneOffset.ofTotalSeconds(60)), "z", "ZoneId"},
|
||||
};
|
||||
}
|
||||
|
||||
// Test cases that should throw an exception with a cogent message
|
||||
// containing the Type being queried and the Temporal being queried.
|
||||
@Test(dataProvider="nozone_exception_cases")
|
||||
public void test_throws_message(Temporal temporal, String pattern, String queryName) {
|
||||
DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pattern);
|
||||
try {
|
||||
fmt.format(temporal);
|
||||
fail("Format using \"" + pattern + "\" with " +
|
||||
temporal + " should have failed");
|
||||
} catch (DateTimeException dte) {
|
||||
String msg = dte.getMessage();
|
||||
// Verify message contains the type that is missing and the temporal value
|
||||
assertTrue(msg.contains(queryName),
|
||||
String.format("\"%s\" missing from %s", queryName, msg));
|
||||
String s = temporal.toString();
|
||||
assertTrue(msg.contains(s),
|
||||
String.format("\"%s\" missing from %s", s, msg));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Test cases that should throw an exception with a cogent message when missing the Chronology
|
||||
@Test
|
||||
public void test_throws_message_chrono() {
|
||||
Chronology chrono = ThaiBuddhistChronology.INSTANCE;
|
||||
DateTimeFormatter fmt = new DateTimeFormatterBuilder().appendZoneId().toFormatter()
|
||||
.withChronology(chrono);
|
||||
LocalTime now = LocalTime.now();
|
||||
try {
|
||||
fmt.format(now);
|
||||
fail("Format using appendZoneId() should have failed");
|
||||
} catch (DateTimeException dte) {
|
||||
String msg = dte.getMessage();
|
||||
// Verify message contains the type that is missing and the temporal value
|
||||
assertTrue(msg.contains("ZoneId"),
|
||||
String.format("\"%s\" missing from %s", "ZoneId", msg));
|
||||
assertTrue(msg.contains(chrono.toString()),
|
||||
String.format("\"%s\" missing from %s", chrono.toString(), msg));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Test cases that should throw an exception with a cogent message when missing the ZoneId
|
||||
@Test
|
||||
public void test_throws_message_zone() {
|
||||
ZoneId zone = ZoneId.of("Pacific/Honolulu");
|
||||
DateTimeFormatter fmt = new DateTimeFormatterBuilder().appendChronologyId().toFormatter()
|
||||
.withZone(zone);
|
||||
LocalTime now = LocalTime.now();
|
||||
try {
|
||||
fmt.format(now);
|
||||
fail("Format using appendChronologyId() should have failed");
|
||||
} catch (DateTimeException dte) {
|
||||
String msg = dte.getMessage();
|
||||
// Verify message contains the type that is missing and the temporal value
|
||||
assertTrue(msg.contains("Chronology"),
|
||||
String.format("\"%s\" missing from %s", "Chronology", msg));
|
||||
assertTrue(msg.contains(zone.toString()),
|
||||
String.format("\"%s\" missing from %s", zone.toString(), msg));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
@ -52,6 +52,7 @@ import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8148748
|
||||
* @summary Spliterator last-binding and fail-fast tests
|
||||
* @run testng SpliteratorLateBindingFailFastTest
|
||||
*/
|
||||
@ -120,8 +121,8 @@ public class SpliteratorLateBindingFailFastTest {
|
||||
}
|
||||
|
||||
void addList(Function<Collection<T>, ? extends List<T>> l) {
|
||||
// @@@ If collection is instance of List then add sub-list tests
|
||||
addCollection(l);
|
||||
addCollection(l.andThen(list -> list.subList(0, list.size())));
|
||||
}
|
||||
|
||||
void addMap(Function<Map<T, T>, ? extends Map<T, T>> mapConstructor) {
|
||||
|
@ -24,6 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 6772689
|
||||
* @key intermittent
|
||||
* @summary Test for standard-to-daylight transitions at midnight:
|
||||
* date stays on the given day.
|
||||
*/
|
||||
|
@ -101,9 +101,6 @@ public class SSLSocketSSLEngineTemplate {
|
||||
private static final boolean debug = false;
|
||||
private final SSLContext sslc;
|
||||
private SSLEngine serverEngine; // server-side SSLEngine
|
||||
private SSLSocket sslSocket; // client-side socket
|
||||
private ServerSocket serverSocket; // server-side Socket, generates the...
|
||||
private Socket socket; // server-side socket that will read
|
||||
|
||||
private final byte[] serverMsg =
|
||||
"Hi there Client, I'm a Server.".getBytes();
|
||||
@ -217,132 +214,128 @@ public class SSLSocketSSLEngineTemplate {
|
||||
private void runTest(boolean direct) throws Exception {
|
||||
boolean serverClose = direct;
|
||||
|
||||
serverSocket = new ServerSocket();
|
||||
serverSocket.setReuseAddress(false);
|
||||
serverSocket.bind(null);
|
||||
int port = serverSocket.getLocalPort();
|
||||
Thread thread = createClientThread(port, serverClose);
|
||||
// generates the server-side Socket
|
||||
try (ServerSocket serverSocket = new ServerSocket()) {
|
||||
serverSocket.setReuseAddress(false);
|
||||
serverSocket.bind(null);
|
||||
int port = serverSocket.getLocalPort();
|
||||
Thread thread = createClientThread(port, serverClose);
|
||||
|
||||
socket = serverSocket.accept();
|
||||
socket.setSoTimeout(500);
|
||||
serverSocket.close();
|
||||
createSSLEngine();
|
||||
createBuffers(direct);
|
||||
|
||||
createSSLEngine();
|
||||
createBuffers(direct);
|
||||
// server-side socket that will read
|
||||
try (Socket socket = serverSocket.accept()) {
|
||||
socket.setSoTimeout(500);
|
||||
|
||||
try {
|
||||
boolean closed = false;
|
||||
// will try to read one more time in case client message
|
||||
// is fragmented to multiple pieces
|
||||
boolean retry = true;
|
||||
boolean closed = false;
|
||||
// will try to read one more time in case client message
|
||||
// is fragmented to multiple pieces
|
||||
boolean retry = true;
|
||||
|
||||
InputStream is = socket.getInputStream();
|
||||
OutputStream os = socket.getOutputStream();
|
||||
InputStream is = socket.getInputStream();
|
||||
OutputStream os = socket.getOutputStream();
|
||||
|
||||
SSLEngineResult serverResult; // results from last operation
|
||||
SSLEngineResult serverResult; // results from last operation
|
||||
|
||||
/*
|
||||
* Examining the SSLEngineResults could be much more involved,
|
||||
* and may alter the overall flow of the application.
|
||||
*
|
||||
* For example, if we received a BUFFER_OVERFLOW when trying
|
||||
* to write to the output pipe, we could reallocate a larger
|
||||
* pipe, but instead we wait for the peer to drain it.
|
||||
*/
|
||||
byte[] inbound = new byte[8192];
|
||||
byte[] outbound = new byte[8192];
|
||||
/*
|
||||
* Examining the SSLEngineResults could be much more involved,
|
||||
* and may alter the overall flow of the application.
|
||||
*
|
||||
* For example, if we received a BUFFER_OVERFLOW when trying
|
||||
* to write to the output pipe, we could reallocate a larger
|
||||
* pipe, but instead we wait for the peer to drain it.
|
||||
*/
|
||||
byte[] inbound = new byte[8192];
|
||||
byte[] outbound = new byte[8192];
|
||||
|
||||
while (!isEngineClosed(serverEngine)) {
|
||||
int len;
|
||||
while (!isEngineClosed(serverEngine)) {
|
||||
int len;
|
||||
|
||||
// Inbound data
|
||||
log("================");
|
||||
// Inbound data
|
||||
log("================");
|
||||
|
||||
// Read from the Client side.
|
||||
try {
|
||||
len = is.read(inbound);
|
||||
if (len == -1) {
|
||||
throw new Exception("Unexpected EOF");
|
||||
}
|
||||
cTOs.put(inbound, 0, len);
|
||||
} catch (SocketTimeoutException ste) {
|
||||
// swallow. Nothing yet, probably waiting on us.
|
||||
}
|
||||
|
||||
cTOs.flip();
|
||||
|
||||
serverResult = serverEngine.unwrap(cTOs, serverIn);
|
||||
log("server unwrap: ", serverResult);
|
||||
runDelegatedTasks(serverResult, serverEngine);
|
||||
cTOs.compact();
|
||||
|
||||
// Outbound data
|
||||
log("----");
|
||||
|
||||
serverResult = serverEngine.wrap(serverOut, sTOc);
|
||||
log("server wrap: ", serverResult);
|
||||
runDelegatedTasks(serverResult, serverEngine);
|
||||
|
||||
sTOc.flip();
|
||||
|
||||
if ((len = sTOc.remaining()) != 0) {
|
||||
sTOc.get(outbound, 0, len);
|
||||
os.write(outbound, 0, len);
|
||||
// Give the other side a chance to process
|
||||
}
|
||||
|
||||
sTOc.compact();
|
||||
|
||||
if (!closed && (serverOut.remaining() == 0)) {
|
||||
closed = true;
|
||||
|
||||
/*
|
||||
* We'll alternate initiatating the shutdown.
|
||||
* When the server initiates, it will take one more
|
||||
* loop, but tests the orderly shutdown.
|
||||
*/
|
||||
if (serverClose) {
|
||||
serverEngine.closeOutbound();
|
||||
}
|
||||
serverIn.flip();
|
||||
|
||||
/*
|
||||
* A sanity check to ensure we got what was sent.
|
||||
*/
|
||||
if (serverIn.remaining() != clientMsg.length) {
|
||||
if (retry && serverIn.remaining() < clientMsg.length) {
|
||||
log("Need to read more from client");
|
||||
retry = false;
|
||||
continue;
|
||||
} else {
|
||||
throw new Exception("Client: Data length error");
|
||||
// Read from the Client side.
|
||||
try {
|
||||
len = is.read(inbound);
|
||||
if (len == -1) {
|
||||
throw new Exception("Unexpected EOF");
|
||||
}
|
||||
cTOs.put(inbound, 0, len);
|
||||
} catch (SocketTimeoutException ste) {
|
||||
// swallow. Nothing yet, probably waiting on us.
|
||||
}
|
||||
|
||||
for (int i = 0; i < clientMsg.length; i++) {
|
||||
if (clientMsg[i] != serverIn.get()) {
|
||||
throw new Exception("Client: Data content error");
|
||||
}
|
||||
cTOs.flip();
|
||||
|
||||
serverResult = serverEngine.unwrap(cTOs, serverIn);
|
||||
log("server unwrap: ", serverResult);
|
||||
runDelegatedTasks(serverResult, serverEngine);
|
||||
cTOs.compact();
|
||||
|
||||
// Outbound data
|
||||
log("----");
|
||||
|
||||
serverResult = serverEngine.wrap(serverOut, sTOc);
|
||||
log("server wrap: ", serverResult);
|
||||
runDelegatedTasks(serverResult, serverEngine);
|
||||
|
||||
sTOc.flip();
|
||||
|
||||
if ((len = sTOc.remaining()) != 0) {
|
||||
sTOc.get(outbound, 0, len);
|
||||
os.write(outbound, 0, len);
|
||||
// Give the other side a chance to process
|
||||
}
|
||||
serverIn.compact();
|
||||
|
||||
sTOc.compact();
|
||||
|
||||
if (!closed && (serverOut.remaining() == 0)) {
|
||||
closed = true;
|
||||
|
||||
/*
|
||||
* We'll alternate initiatating the shutdown.
|
||||
* When the server initiates, it will take one more
|
||||
* loop, but tests the orderly shutdown.
|
||||
*/
|
||||
if (serverClose) {
|
||||
serverEngine.closeOutbound();
|
||||
}
|
||||
serverIn.flip();
|
||||
|
||||
/*
|
||||
* A sanity check to ensure we got what was sent.
|
||||
*/
|
||||
if (serverIn.remaining() != clientMsg.length) {
|
||||
if (retry &&
|
||||
serverIn.remaining() < clientMsg.length) {
|
||||
log("Need to read more from client");
|
||||
retry = false;
|
||||
continue;
|
||||
} else {
|
||||
throw new Exception(
|
||||
"Client: Data length error");
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < clientMsg.length; i++) {
|
||||
if (clientMsg[i] != serverIn.get()) {
|
||||
throw new Exception(
|
||||
"Client: Data content error");
|
||||
}
|
||||
}
|
||||
serverIn.compact();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
serverException = e;
|
||||
} finally {
|
||||
// Wait for the client to join up with us.
|
||||
if (thread != null) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
serverException = e;
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
socket.close();
|
||||
}
|
||||
|
||||
// Wait for the client to join up with us.
|
||||
if (thread != null) {
|
||||
thread.join();
|
||||
}
|
||||
|
||||
if (sslSocket != null) {
|
||||
sslSocket.close();
|
||||
}
|
||||
|
||||
if (serverException != null) {
|
||||
if (clientException != null) {
|
||||
serverException.initCause(clientException);
|
||||
@ -369,11 +362,9 @@ public class SSLSocketSSLEngineTemplate {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(1000); // Give server time to finish setup.
|
||||
|
||||
sslSocket = (SSLSocket) sslc.getSocketFactory().
|
||||
createSocket("localhost", port);
|
||||
// client-side socket
|
||||
try (SSLSocket sslSocket = (SSLSocket)sslc.getSocketFactory().
|
||||
createSocket("localhost", port)) {
|
||||
OutputStream os = sslSocket.getOutputStream();
|
||||
InputStream is = sslSocket.getInputStream();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2015, 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
|
||||
@ -85,26 +85,26 @@ public class SSLSocketTemplate {
|
||||
*/
|
||||
void doServerSide() throws Exception {
|
||||
SSLServerSocketFactory sslssf =
|
||||
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
|
||||
SSLServerSocket sslServerSocket =
|
||||
(SSLServerSocket) sslssf.createServerSocket(serverPort);
|
||||
(SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
|
||||
try (SSLServerSocket sslServerSocket =
|
||||
(SSLServerSocket)sslssf.createServerSocket(serverPort)) {
|
||||
|
||||
serverPort = sslServerSocket.getLocalPort();
|
||||
serverPort = sslServerSocket.getLocalPort();
|
||||
|
||||
/*
|
||||
* Signal Client, we're ready for his connect.
|
||||
*/
|
||||
serverReady = true;
|
||||
/*
|
||||
* Signal Client, we're ready for his connect.
|
||||
*/
|
||||
serverReady = true;
|
||||
|
||||
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
|
||||
InputStream sslIS = sslSocket.getInputStream();
|
||||
OutputStream sslOS = sslSocket.getOutputStream();
|
||||
try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
|
||||
InputStream sslIS = sslSocket.getInputStream();
|
||||
OutputStream sslOS = sslSocket.getOutputStream();
|
||||
|
||||
sslIS.read();
|
||||
sslOS.write(85);
|
||||
sslOS.flush();
|
||||
|
||||
sslSocket.close();
|
||||
sslIS.read();
|
||||
sslOS.write(85);
|
||||
sslOS.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -123,18 +123,17 @@ public class SSLSocketTemplate {
|
||||
}
|
||||
|
||||
SSLSocketFactory sslsf =
|
||||
(SSLSocketFactory) SSLSocketFactory.getDefault();
|
||||
SSLSocket sslSocket = (SSLSocket)
|
||||
sslsf.createSocket("localhost", serverPort);
|
||||
(SSLSocketFactory)SSLSocketFactory.getDefault();
|
||||
try (SSLSocket sslSocket =
|
||||
(SSLSocket)sslsf.createSocket("localhost", serverPort)) {
|
||||
|
||||
InputStream sslIS = sslSocket.getInputStream();
|
||||
OutputStream sslOS = sslSocket.getOutputStream();
|
||||
InputStream sslIS = sslSocket.getInputStream();
|
||||
OutputStream sslOS = sslSocket.getOutputStream();
|
||||
|
||||
sslOS.write(280);
|
||||
sslOS.flush();
|
||||
sslIS.read();
|
||||
|
||||
sslSocket.close();
|
||||
sslOS.write(280);
|
||||
sslOS.flush();
|
||||
sslIS.read();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
158
jdk/test/javax/xml/bind/xjc/8145039/JaxbMarshallTest.java
Normal file
158
jdk/test/javax/xml/bind/xjc/8145039/JaxbMarshallTest.java
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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 8145039
|
||||
* @summary Check that marshalling of xjc generated class doesn't throw
|
||||
* ClassCast exception.
|
||||
* @modules javax.xml.bind
|
||||
* @library /lib/testlibrary
|
||||
* @run testng/othervm JaxbMarshallTest
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.Marshaller;
|
||||
import jdk.testlibrary.JDKToolLauncher;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class JaxbMarshallTest {
|
||||
|
||||
@BeforeTest
|
||||
public void setUp() throws IOException {
|
||||
// Create test directory inside scratch
|
||||
testWorkDir = Paths.get(System.getProperty("user.dir", "."));
|
||||
// Save its URL
|
||||
testWorkDirUrl = testWorkDir.toUri().toURL();
|
||||
// Get test source directory path
|
||||
testSrcDir = Paths.get(System.getProperty("test.src", "."));
|
||||
// Get path of xjc result folder
|
||||
xjcResultDir = testWorkDir.resolve(TEST_PACKAGE);
|
||||
// Copy schema document file to scratch directory
|
||||
Files.copy(testSrcDir.resolve(XSD_FILENAME), testWorkDir.resolve(XSD_FILENAME), REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Test does the following steps to reproduce problem reported by 8145039:
|
||||
* 1. Copy test schema to JTREG scratch folder
|
||||
* 2. Run xjc on test schema file
|
||||
* 3. Compile generated java files with test javac
|
||||
* 4. Marshall the new list instance to ensure that
|
||||
* ClassCastException is not thrown
|
||||
*/
|
||||
@Test
|
||||
public void marshallClassCastExceptionTest() throws Exception {
|
||||
JAXBContext jaxbContext;
|
||||
Marshaller marshaller;
|
||||
URLClassLoader jaxbContextClassLoader;
|
||||
// Generate java classes by xjc
|
||||
runXjc(XSD_FILENAME);
|
||||
// Compile xjc generated java files
|
||||
compileXjcGeneratedClasses();
|
||||
|
||||
// Create JAXB context based on xjc generated package.
|
||||
// Need to create URL class loader ot make compiled classes discoverable
|
||||
// by JAXB context
|
||||
jaxbContextClassLoader = URLClassLoader.newInstance(new URL[] {testWorkDirUrl});
|
||||
jaxbContext = JAXBContext.newInstance( TEST_PACKAGE, jaxbContextClassLoader);
|
||||
|
||||
// Create instance of Xjc generated data type.
|
||||
// Java classes were compiled during the test execution hence reflection
|
||||
// is needed here
|
||||
Class classLongListClass = jaxbContextClassLoader.loadClass(TEST_CLASS);
|
||||
Object objectLongListClass = classLongListClass.newInstance();
|
||||
// Get 'getIn' method object
|
||||
Method getInMethod = classLongListClass.getMethod( GET_LIST_METHOD, (Class [])null );
|
||||
// Invoke 'getIn' method
|
||||
List<Long> inList = (List<Long>)getInMethod.invoke(objectLongListClass);
|
||||
// Add values into the jaxb object list
|
||||
inList.add(Long.valueOf(0));
|
||||
inList.add(Long.valueOf(43));
|
||||
inList.add(Long.valueOf(1000000123));
|
||||
|
||||
// Marshall constructed complex type variable to standard output.
|
||||
// In case of failure the ClassCastException will be thrown
|
||||
marshaller = jaxbContext.createMarshaller();
|
||||
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
|
||||
marshaller.marshal(objectLongListClass, System.out);
|
||||
}
|
||||
|
||||
// Compile schema file into java classes definitions
|
||||
void runXjc(String xsdFileName) throws Exception {
|
||||
// Prepare process builder to run schemagen tool and save its output
|
||||
JDKToolLauncher xjcLauncher = JDKToolLauncher.createUsingTestJDK("xjc");
|
||||
xjcLauncher.addToolArg(xsdFileName);
|
||||
System.out.println("Executing xjc command: " + Arrays.asList(xjcLauncher.getCommand()));
|
||||
ProcessBuilder pb = new ProcessBuilder(xjcLauncher.getCommand());
|
||||
// Set xjc work directory with the input java file
|
||||
pb.directory(testWorkDir.toFile());
|
||||
pb.inheritIO();
|
||||
Process p = pb.start();
|
||||
p.waitFor();
|
||||
p.destroy();
|
||||
}
|
||||
|
||||
// Compile java classes with javac tool
|
||||
void compileXjcGeneratedClasses() throws Exception {
|
||||
JDKToolLauncher javacLauncher = JDKToolLauncher.createUsingTestJDK("javac");
|
||||
javacLauncher.addToolArg(xjcResultDir.resolve("ObjectFactory.java").toString());
|
||||
javacLauncher.addToolArg(xjcResultDir.resolve("TypesLongList.java").toString());
|
||||
javacLauncher.addToolArg(xjcResultDir.resolve("package-info.java").toString());
|
||||
System.out.println("Compiling xjc generated classes: " + Arrays.asList(javacLauncher.getCommand()));
|
||||
ProcessBuilder pb = new ProcessBuilder(javacLauncher.getCommand());
|
||||
pb.inheritIO();
|
||||
pb.directory(testWorkDir.toFile());
|
||||
Process p = pb.start();
|
||||
p.waitFor();
|
||||
p.destroy();
|
||||
}
|
||||
|
||||
// Test schema filename
|
||||
static final String XSD_FILENAME = "testSchema.xsd";
|
||||
// Package of java classes generated by xjc
|
||||
static final String TEST_PACKAGE = "testns_package";
|
||||
// Name of generated java class
|
||||
static final String TEST_CLASS = TEST_PACKAGE+".TypesLongList";
|
||||
// Method to get the list from xjc generated class
|
||||
static final String GET_LIST_METHOD = "getIn";
|
||||
// Test working directory
|
||||
Path testWorkDir;
|
||||
// Test working directory URL
|
||||
URL testWorkDirUrl;
|
||||
// Directory with test src
|
||||
Path testSrcDir;
|
||||
// Directory with java files generated by xjc
|
||||
Path xjcResultDir;
|
||||
}
|
21
jdk/test/javax/xml/bind/xjc/8145039/testSchema.xsd
Normal file
21
jdk/test/javax/xml/bind/xjc/8145039/testSchema.xsd
Normal file
@ -0,0 +1,21 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:tns="http://testns_package"
|
||||
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
|
||||
targetNamespace="http://testns_package">
|
||||
<!-- Simple type list -->
|
||||
<xsd:simpleType name="LongList">
|
||||
<xsd:list>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:unsignedInt"/>
|
||||
</xsd:simpleType>
|
||||
</xsd:list>
|
||||
</xsd:simpleType>
|
||||
<!--- Complex test type -->
|
||||
<xsd:element name="typesLongList">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="in" type="tns:LongList"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
@ -23,14 +23,16 @@
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8080679
|
||||
* @modules jdk.internal.le/jdk.internal.jline.console
|
||||
* @bug 8080679 8131913
|
||||
* @modules jdk.internal.le/jdk.internal.jline
|
||||
* jdk.internal.le/jdk.internal.jline.console
|
||||
* @summary Verify ConsoleReader.stripAnsi strips escape sequences from its input correctly.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import jdk.internal.jline.UnsupportedTerminal;
|
||||
import jdk.internal.jline.console.ConsoleReader;
|
||||
|
||||
public class StripAnsiTest {
|
||||
@ -41,7 +43,7 @@ public class StripAnsiTest {
|
||||
void run() throws Exception {
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ConsoleReader reader = new ConsoleReader(in, out);
|
||||
ConsoleReader reader = new ConsoleReader(in, out, new UnsupportedTerminal());
|
||||
|
||||
String withAnsi = "0\033[s1\033[2J2\033[37;4m3";
|
||||
String expected = "0123";
|
||||
|
607
jdk/test/jdk/internal/misc/Unsafe/CopyCommon.java
Normal file
607
jdk/test/jdk/internal/misc/Unsafe/CopyCommon.java
Normal file
@ -0,0 +1,607 @@
|
||||
/*
|
||||
* 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 jdk.internal.misc.Unsafe;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Helper class to support testing of Unsafe.copyMemory and Unsafe.copySwapMemory
|
||||
*/
|
||||
public class CopyCommon {
|
||||
private static final boolean DEBUG = Boolean.getBoolean("CopyCommon.DEBUG");
|
||||
|
||||
public static final long KB = 1024;
|
||||
public static final long MB = KB * 1024;
|
||||
public static final long GB = MB * 1024;
|
||||
|
||||
static final int SMALL_COPY_SIZE = 32;
|
||||
static final int BASE_ALIGNMENT = 16;
|
||||
|
||||
protected static final Unsafe UNSAFE;
|
||||
|
||||
static {
|
||||
try {
|
||||
Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
UNSAFE = (jdk.internal.misc.Unsafe) f.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to get Unsafe instance.", e);
|
||||
}
|
||||
}
|
||||
|
||||
static long alignDown(long value, long alignment) {
|
||||
return value & ~(alignment - 1);
|
||||
}
|
||||
|
||||
static long alignUp(long value, long alignment) {
|
||||
return (value + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
static boolean isAligned(long value, long alignment) {
|
||||
return value == alignDown(value, alignment);
|
||||
}
|
||||
|
||||
CopyCommon() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate verification data for a given offset
|
||||
*
|
||||
* The verification data is used to verify that the correct bytes
|
||||
* have indeed been copied and byte swapped.
|
||||
*
|
||||
* The data is generated based on the offset (in bytes) into the
|
||||
* source buffer. For a native buffer the offset is relative to
|
||||
* the base pointer. For a heap array it is relative to the
|
||||
* address of the first array element.
|
||||
*
|
||||
* This method will return the result of doing an elementSize byte
|
||||
* read starting at offset (in bytes).
|
||||
*
|
||||
* @param offset offset into buffer
|
||||
* @param elemSize size (in bytes) of the element
|
||||
*
|
||||
* @return the verification data, only the least significant
|
||||
* elemSize*8 bits are set, zero extended
|
||||
*/
|
||||
private long getVerificationDataForOffset(long offset, long elemSize) {
|
||||
byte[] bytes = new byte[(int)elemSize];
|
||||
|
||||
for (long i = 0; i < elemSize; i++) {
|
||||
bytes[(int)i] = (byte)(offset + i);
|
||||
}
|
||||
|
||||
long o = UNSAFE.arrayBaseOffset(byte[].class);
|
||||
|
||||
switch ((int)elemSize) {
|
||||
case 1: return Byte.toUnsignedLong(UNSAFE.getByte(bytes, o));
|
||||
case 2: return Short.toUnsignedLong(UNSAFE.getShortUnaligned(bytes, o));
|
||||
case 4: return Integer.toUnsignedLong(UNSAFE.getIntUnaligned(bytes, o));
|
||||
case 8: return UNSAFE.getLongUnaligned(bytes, o);
|
||||
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify byte swapped data
|
||||
*
|
||||
* @param ptr the data to verify
|
||||
* @param srcOffset the srcOffset (in bytes) from which the copy started,
|
||||
* used as key to regenerate the verification data
|
||||
* @param dstOffset the offset (in bytes) in the array at which to start
|
||||
* the verification, relative to the first element in the array
|
||||
* @param size size (in bytes) of data to to verify
|
||||
* @param elemSize size (in bytes) of the individual array elements
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
private void verifySwappedData(GenericPointer ptr, long srcOffset, long dstOffset, long size, long elemSize) {
|
||||
for (long offset = 0; offset < size; offset += elemSize) {
|
||||
long expectedUnswapped = getVerificationDataForOffset(srcOffset + offset, elemSize);
|
||||
long expected = byteSwap(expectedUnswapped, elemSize);
|
||||
|
||||
long actual = getArrayElem(ptr, dstOffset + offset, elemSize);
|
||||
|
||||
if (expected != actual) {
|
||||
throw new RuntimeException("srcOffset: 0x" + Long.toHexString(srcOffset) +
|
||||
" dstOffset: 0x" + Long.toHexString(dstOffset) +
|
||||
" size: 0x" + Long.toHexString(size) +
|
||||
" offset: 0x" + Long.toHexString(offset) +
|
||||
" expectedUnswapped: 0x" + Long.toHexString(expectedUnswapped) +
|
||||
" expected: 0x" + Long.toHexString(expected) +
|
||||
" != actual: 0x" + Long.toHexString(actual));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an array with verification friendly data
|
||||
*
|
||||
* @param ptr pointer to the data to initialize
|
||||
* @param size size (in bytes) of the data
|
||||
* @param elemSize size (in bytes) of the individual elements
|
||||
*/
|
||||
private void initVerificationData(GenericPointer ptr, long size, long elemSize) {
|
||||
for (long offset = 0; offset < size; offset++) {
|
||||
byte data = (byte)getVerificationDataForOffset(offset, 1);
|
||||
|
||||
if (ptr.isOnHeap()) {
|
||||
UNSAFE.putByte(ptr.getObject(), ptr.getOffset() + offset, data);
|
||||
} else {
|
||||
UNSAFE.putByte(ptr.getOffset() + offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a primitive array
|
||||
*
|
||||
* @param size size (in bytes) of all the array elements (elemSize * length)
|
||||
* @param elemSize the size of the array elements
|
||||
*
|
||||
* @return a newly allocated primitive array
|
||||
*/
|
||||
Object allocArray(long size, long elemSize) {
|
||||
int length = (int)(size / elemSize);
|
||||
|
||||
switch ((int)elemSize) {
|
||||
case 1: return new byte[length];
|
||||
case 2: return new short[length];
|
||||
case 4: return new int[length];
|
||||
case 8: return new long[length];
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid element size: " + elemSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a primitive array entry
|
||||
*
|
||||
* @param ptr pointer to the data
|
||||
* @param offset offset (in bytes) of the array element, relative to the first element in the array
|
||||
*
|
||||
* @return the array element, as an unsigned long
|
||||
*/
|
||||
private long getArrayElem(GenericPointer ptr, long offset, long elemSize) {
|
||||
if (ptr.isOnHeap()) {
|
||||
Object o = ptr.getObject();
|
||||
int index = (int)(offset / elemSize);
|
||||
|
||||
if (o instanceof short[]) {
|
||||
short[] arr = (short[])o;
|
||||
return Short.toUnsignedLong(arr[index]);
|
||||
} else if (o instanceof int[]) {
|
||||
int[] arr = (int[])o;
|
||||
return Integer.toUnsignedLong(arr[index]);
|
||||
} else if (o instanceof long[]) {
|
||||
long[] arr = (long[])o;
|
||||
return arr[index];
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid object type: " + o.getClass().getName());
|
||||
}
|
||||
} else {
|
||||
long addr = ptr.getOffset() + offset;
|
||||
|
||||
switch ((int)elemSize) {
|
||||
case 1: return Byte.toUnsignedLong(UNSAFE.getByte(addr));
|
||||
case 2: return Short.toUnsignedLong(UNSAFE.getShortUnaligned(null, addr));
|
||||
case 4: return Integer.toUnsignedLong(UNSAFE.getIntUnaligned(null, addr));
|
||||
case 8: return UNSAFE.getLongUnaligned(null, addr);
|
||||
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void putValue(long addr, long elemSize, long value) {
|
||||
switch ((int)elemSize) {
|
||||
case 1: UNSAFE.putByte(addr, (byte)value); break;
|
||||
case 2: UNSAFE.putShortUnaligned(null, addr, (short)value); break;
|
||||
case 4: UNSAFE.putIntUnaligned(null, addr, (int)value); break;
|
||||
case 8: UNSAFE.putLongUnaligned(null, addr, value); break;
|
||||
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the elements for an array
|
||||
*
|
||||
* @param o a primitive heap array
|
||||
*
|
||||
* @return the size (in bytes) of the individual array elements
|
||||
*/
|
||||
private long getArrayElemSize(Object o) {
|
||||
if (o instanceof short[]) {
|
||||
return 2;
|
||||
} else if (o instanceof int[]) {
|
||||
return 4;
|
||||
} else if (o instanceof long[]) {
|
||||
return 8;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid object type: " + o.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Byte swap a value
|
||||
*
|
||||
* @param value the value to swap, only the bytes*8 least significant bits are used
|
||||
* @param size size (in bytes) of the value
|
||||
*
|
||||
* @return the byte swapped value in the bytes*8 least significant bits
|
||||
*/
|
||||
private long byteSwap(long value, long size) {
|
||||
switch ((int)size) {
|
||||
case 2: return Short.toUnsignedLong(Short.reverseBytes((short)value));
|
||||
case 4: return Integer.toUnsignedLong(Integer.reverseBytes((int)value));
|
||||
case 8: return Long.reverseBytes(value);
|
||||
default: throw new IllegalArgumentException("Invalid element size: " + size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify data which has *not* been byte swapped
|
||||
*
|
||||
* @param ptr the data to verify
|
||||
* @param startOffset the offset (in bytes) at which to start the verification
|
||||
* @param size size (in bytes) of the data to verify
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
private void verifyUnswappedData(GenericPointer ptr, long startOffset, long srcOffset, long size) {
|
||||
for (long i = 0; i < size; i++) {
|
||||
byte expected = (byte)getVerificationDataForOffset(srcOffset + i, 1);
|
||||
|
||||
byte actual;
|
||||
if (ptr.isOnHeap()) {
|
||||
actual = UNSAFE.getByte(ptr.getObject(), ptr.getOffset() + startOffset + i);
|
||||
} else {
|
||||
actual = UNSAFE.getByte(ptr.getOffset() + startOffset + i);
|
||||
}
|
||||
|
||||
if (expected != actual) {
|
||||
throw new RuntimeException("startOffset: 0x" + Long.toHexString(startOffset) +
|
||||
" srcOffset: 0x" + Long.toHexString(srcOffset) +
|
||||
" size: 0x" + Long.toHexString(size) +
|
||||
" i: 0x" + Long.toHexString(i) +
|
||||
" expected: 0x" + Long.toHexString(expected) +
|
||||
" != actual: 0x" + Long.toHexString(actual));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy and byte swap data from the source to the destination
|
||||
*
|
||||
* This method will pre-populate the whole source and destination
|
||||
* buffers with verification friendly data. It will then copy data
|
||||
* to fill part of the destination buffer with data from the
|
||||
* source, optionally byte swapping the copied elements on the
|
||||
* fly. Some space (padding) will be left before and after the
|
||||
* data in the destination buffer, which should not be
|
||||
* touched/overwritten by the copy call.
|
||||
*
|
||||
* Note: Both source and destination buffers will be overwritten!
|
||||
*
|
||||
* @param src source buffer to copy from
|
||||
* @param srcOffset the offset (in bytes) in the source buffer, relative to
|
||||
* the first array element, at which to start reading data
|
||||
* @param dst destination buffer to copy to
|
||||
* @param dstOffset the offset (in bytes) in the destination
|
||||
* buffer, relative to the first array element, at which to
|
||||
* start writing data
|
||||
* @param bufSize the size (in bytes) of the src and dst arrays
|
||||
* @param copyBytes the size (in bytes) of the copy to perform,
|
||||
* must be a multiple of elemSize
|
||||
* @param elemSize the size (in bytes) of the elements
|
||||
* @param swap true if elements should be byte swapped
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
void testCopyGeneric(GenericPointer src, long srcOffset,
|
||||
GenericPointer dst, long dstOffset,
|
||||
long bufSize, long copyBytes, long elemSize, boolean swap) {
|
||||
if (swap) {
|
||||
if (!isAligned(copyBytes, elemSize)) {
|
||||
throw new IllegalArgumentException(
|
||||
"copyBytes (" + copyBytes + ") must be a multiple of elemSize (" + elemSize + ")");
|
||||
}
|
||||
if (src.isOnHeap() && !isAligned(srcOffset, elemSize)) {
|
||||
throw new IllegalArgumentException(
|
||||
"srcOffset (" + srcOffset + ") must be a multiple of elemSize (" + elemSize + ")");
|
||||
}
|
||||
if (dst.isOnHeap() && !isAligned(dstOffset, elemSize)) {
|
||||
throw new IllegalArgumentException(
|
||||
"dstOffset (" + dstOffset + ") must be a multiple of elemSize (" + elemSize + ")");
|
||||
}
|
||||
}
|
||||
|
||||
if (srcOffset + copyBytes > bufSize) {
|
||||
throw new IllegalArgumentException(
|
||||
"srcOffset (" + srcOffset + ") + copyBytes (" + copyBytes + ") > bufSize (" + bufSize + ")");
|
||||
}
|
||||
if (dstOffset + copyBytes > bufSize) {
|
||||
throw new IllegalArgumentException(
|
||||
"dstOffset (" + dstOffset + ") + copyBytes (" + copyBytes + ") > bufSize (" + bufSize + ")");
|
||||
}
|
||||
|
||||
// Initialize the whole source buffer with a verification friendly pattern (no 0x00 bytes)
|
||||
initVerificationData(src, bufSize, elemSize);
|
||||
if (!src.equals(dst)) {
|
||||
initVerificationData(dst, bufSize, elemSize);
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println("===before===");
|
||||
for (int offset = 0; offset < bufSize; offset += elemSize) {
|
||||
long srcValue = getArrayElem(src, offset, elemSize);
|
||||
long dstValue = getArrayElem(dst, offset, elemSize);
|
||||
|
||||
System.out.println("offs=0x" + Long.toHexString(Integer.toUnsignedLong(offset)) +
|
||||
" src=0x" + Long.toHexString(srcValue) +
|
||||
" dst=0x" + Long.toHexString(dstValue));
|
||||
}
|
||||
}
|
||||
|
||||
if (swap) {
|
||||
// Copy & swap data into the middle of the destination buffer
|
||||
UNSAFE.copySwapMemory(src.getObject(),
|
||||
src.getOffset() + srcOffset,
|
||||
dst.getObject(),
|
||||
dst.getOffset() + dstOffset,
|
||||
copyBytes,
|
||||
elemSize);
|
||||
} else {
|
||||
// Copy & swap data into the middle of the destination buffer
|
||||
UNSAFE.copyMemory(src.getObject(),
|
||||
src.getOffset() + srcOffset,
|
||||
dst.getObject(),
|
||||
dst.getOffset() + dstOffset,
|
||||
copyBytes);
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println("===after===");
|
||||
for (int offset = 0; offset < bufSize; offset += elemSize) {
|
||||
long srcValue = getArrayElem(src, offset, elemSize);
|
||||
long dstValue = getArrayElem(dst, offset, elemSize);
|
||||
|
||||
System.out.println("offs=0x" + Long.toHexString(Integer.toUnsignedLong(offset)) +
|
||||
" src=0x" + Long.toHexString(srcValue) +
|
||||
" dst=0x" + Long.toHexString(dstValue));
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the the front padding is unchanged
|
||||
verifyUnswappedData(dst, 0, 0, dstOffset);
|
||||
|
||||
if (swap) {
|
||||
// Verify swapped data
|
||||
verifySwappedData(dst, srcOffset, dstOffset, copyBytes, elemSize);
|
||||
} else {
|
||||
// Verify copied/unswapped data
|
||||
verifyUnswappedData(dst, dstOffset, srcOffset, copyBytes);
|
||||
}
|
||||
|
||||
// Verify that the back padding is unchanged
|
||||
long frontAndCopyBytes = dstOffset + copyBytes;
|
||||
long trailingBytes = bufSize - frontAndCopyBytes;
|
||||
verifyUnswappedData(dst, frontAndCopyBytes, frontAndCopyBytes, trailingBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test various configurations of copying and optionally swapping data
|
||||
*
|
||||
* @param src the source buffer to copy from
|
||||
* @param dst the destination buffer to copy to
|
||||
* @param size size (in bytes) of the buffers
|
||||
* @param elemSize size (in bytes) of the individual elements
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
public void testBufferPair(GenericPointer src, GenericPointer dst, long size, long elemSize, boolean swap) {
|
||||
// offset in source from which to start reading data
|
||||
for (long srcOffset = 0; srcOffset < size; srcOffset += (src.isOnHeap() ? elemSize : 1)) {
|
||||
|
||||
// offset in destination at which to start writing data
|
||||
for (int dstOffset = 0; dstOffset < size; dstOffset += (dst.isOnHeap() ? elemSize : 1)) {
|
||||
|
||||
// number of bytes to copy
|
||||
long maxCopyBytes = Math.min(size - srcOffset, size - dstOffset);
|
||||
for (long copyBytes = 0; copyBytes < maxCopyBytes; copyBytes += elemSize) {
|
||||
try {
|
||||
testCopyGeneric(src, srcOffset, dst, dstOffset, size, copyBytes, elemSize, swap);
|
||||
} catch (RuntimeException e) {
|
||||
// Wrap the exception in another exception to catch the relevant configuration data
|
||||
throw new RuntimeException("testBufferPair: " +
|
||||
"src=" + src +
|
||||
" dst=" + dst +
|
||||
" elemSize=0x" + Long.toHexString(elemSize) +
|
||||
" copyBytes=0x" + Long.toHexString(copyBytes) +
|
||||
" srcOffset=0x" + Long.toHexString(srcOffset) +
|
||||
" dstOffset=0x" + Long.toHexString(dstOffset) +
|
||||
" swap=" + swap,
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test copying between various permutations of buffers
|
||||
*
|
||||
* @param buffers buffers to permute (src x dst)
|
||||
* @param size size (in bytes) of buffers
|
||||
* @param elemSize size (in bytes) of individual elements
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
public void testPermuteBuffers(GenericPointer[] buffers, long size, long elemSize, boolean swap) {
|
||||
System.out.println("testPermuteBuffers(buffers, " + size + ", " + elemSize + ", " + swap + ")");
|
||||
for (int srcIndex = 0; srcIndex < buffers.length; srcIndex++) {
|
||||
for (int dstIndex = 0; dstIndex < buffers.length; dstIndex++) {
|
||||
testBufferPair(buffers[srcIndex], buffers[dstIndex], size, elemSize, swap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test copying of a specific element size
|
||||
*
|
||||
* @param size size (in bytes) of buffers to allocate
|
||||
* @param elemSize size (in bytes) of individual elements
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
private void testElemSize(long size, long elemSize, boolean swap) {
|
||||
long buf1Raw = 0;
|
||||
long buf2Raw = 0;
|
||||
|
||||
try {
|
||||
buf1Raw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
|
||||
long buf1 = alignUp(buf1Raw, BASE_ALIGNMENT);
|
||||
|
||||
buf2Raw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
|
||||
long buf2 = alignUp(buf2Raw, BASE_ALIGNMENT);
|
||||
|
||||
GenericPointer[] buffers = {
|
||||
new GenericPointer(buf1),
|
||||
new GenericPointer(buf2),
|
||||
new GenericPointer(allocArray(size, elemSize)),
|
||||
new GenericPointer(allocArray(size, elemSize))
|
||||
};
|
||||
|
||||
testPermuteBuffers(buffers, size, elemSize, swap);
|
||||
} finally {
|
||||
if (buf1Raw != 0) {
|
||||
UNSAFE.freeMemory(buf1Raw);
|
||||
}
|
||||
if (buf2Raw != 0) {
|
||||
UNSAFE.freeMemory(buf2Raw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that small copies work
|
||||
*/
|
||||
void testSmallCopy(boolean swap) {
|
||||
int smallBufSize = SMALL_COPY_SIZE;
|
||||
int minElemSize = swap ? 2 : 1;
|
||||
int maxElemSize = swap ? 8 : 1;
|
||||
|
||||
// Test various element types and heap/native combinations
|
||||
for (long elemSize = minElemSize; elemSize <= maxElemSize; elemSize <<= 1) {
|
||||
testElemSize(smallBufSize, elemSize, swap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that large copies work
|
||||
*/
|
||||
void testLargeCopy(boolean swap) {
|
||||
long size = 2 * GB + 8;
|
||||
long bufRaw = 0;
|
||||
|
||||
// Check that a large native copy succeeds
|
||||
try {
|
||||
try {
|
||||
bufRaw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
|
||||
} catch (OutOfMemoryError e) {
|
||||
// Accept failure, skip test
|
||||
return;
|
||||
}
|
||||
|
||||
long buf = alignUp(bufRaw, BASE_ALIGNMENT);
|
||||
|
||||
if (swap) {
|
||||
UNSAFE.copySwapMemory(null, buf, null, buf, size, 8);
|
||||
} else {
|
||||
UNSAFE.copyMemory(null, buf, null, buf, size);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("copy of large buffer failed (swap=" + swap + ")");
|
||||
} finally {
|
||||
if (bufRaw != 0) {
|
||||
UNSAFE.freeMemory(bufRaw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to represent a "pointer" - either a heap array or
|
||||
* a pointer to a native buffer.
|
||||
*
|
||||
* In the case of a native pointer, the Object is null and the offset is
|
||||
* the absolute address of the native buffer.
|
||||
*
|
||||
* In the case of a heap object, the Object is a primitive array, and
|
||||
* the offset will be set to the base offset to the first element, meaning
|
||||
* the object and the offset together form a double-register pointer.
|
||||
*/
|
||||
static class GenericPointer {
|
||||
private final Object o;
|
||||
private final long offset;
|
||||
|
||||
private GenericPointer(Object o, long offset) {
|
||||
this.o = o;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "GenericPointer(o={" + o + "}, offset=0x" + Long.toHexString(offset) + ")";
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof GenericPointer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GenericPointer otherp = (GenericPointer)other;
|
||||
|
||||
return o == otherp.o && offset == otherp.offset;
|
||||
}
|
||||
|
||||
GenericPointer(Object o) {
|
||||
this(o, UNSAFE.arrayBaseOffset(o.getClass()));
|
||||
}
|
||||
|
||||
GenericPointer(long offset) {
|
||||
this(null, offset);
|
||||
}
|
||||
|
||||
public boolean isOnHeap() {
|
||||
return o != null;
|
||||
}
|
||||
|
||||
public Object getObject() {
|
||||
return o;
|
||||
}
|
||||
|
||||
public long getOffset() {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
}
|
138
jdk/test/jdk/internal/misc/Unsafe/CopyMemory.java
Normal file
138
jdk/test/jdk/internal/misc/Unsafe/CopyMemory.java
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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 jdk.internal.misc.Unsafe;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test Unsafe.copyMemory
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*/
|
||||
public class CopyMemory extends CopyCommon {
|
||||
private CopyMemory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Run positive tests
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
private void testPositive() {
|
||||
testSmallCopy(false);
|
||||
testLargeCopy(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run negative tests, testing corner cases and the various exceptions
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
private void testNegative() {
|
||||
long bufRaw = 0;
|
||||
|
||||
try {
|
||||
bufRaw = UNSAFE.allocateMemory(1024);
|
||||
long buf = CopyCommon.alignUp(bufRaw, CopyCommon.BASE_ALIGNMENT);
|
||||
short[] arr = new short[16];
|
||||
|
||||
// Check illegal sizes
|
||||
System.out.println("Testing negative size");
|
||||
try {
|
||||
UNSAFE.copyMemory(null, buf, null, buf, -1);
|
||||
throw new RuntimeException("copyMemory failed to throw IAE for size=-1");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
System.out.println("Testing negative srcOffset");
|
||||
try {
|
||||
// Check that negative srcOffset throws an IAE
|
||||
UNSAFE.copyMemory(arr, -1, arr, UNSAFE.arrayBaseOffset(arr.getClass()), 16);
|
||||
throw new RuntimeException("copyMemory failed to throw IAE for srcOffset=-1");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
System.out.println("Testing negative destOffset");
|
||||
try {
|
||||
// Check that negative dstOffset throws an IAE
|
||||
UNSAFE.copyMemory(arr, UNSAFE.arrayBaseOffset(arr.getClass()), arr, -1, 16);
|
||||
throw new RuntimeException("copyMemory failed to throw IAE for destOffset=-1");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
System.out.println("Testing reference array");
|
||||
try {
|
||||
// Check that a reference array destination throws IAE
|
||||
UNSAFE.copyMemory(null, buf, new Object[16], UNSAFE.arrayBaseOffset(Object[].class), 16);
|
||||
throw new RuntimeException("copyMemory failed to throw IAE");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
// Check that invalid source & dest pointers throw IAEs (only relevant on 32-bit platforms)
|
||||
if (UNSAFE.addressSize() == 4) {
|
||||
long invalidPtr = (long)1 << 35; // Pick a random bit in upper 32 bits
|
||||
|
||||
try {
|
||||
// Check that an invalid (not 32-bit clean) source pointer throws IAE
|
||||
UNSAFE.copyMemory(null, invalidPtr, null, buf, 16);
|
||||
throw new RuntimeException("copyMemory failed to throw IAE for srcOffset 0x" +
|
||||
Long.toHexString(invalidPtr));
|
||||
} catch (IllegalArgumentException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
try {
|
||||
// Check that an invalid (not 32-bit clean) source pointer throws IAE
|
||||
UNSAFE.copyMemory(null, buf, null, invalidPtr, 16);
|
||||
throw new RuntimeException("copyMemory failed to throw IAE for destOffset 0x" +
|
||||
Long.toHexString(invalidPtr));
|
||||
} catch (IllegalArgumentException e) {
|
||||
// good
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (bufRaw != 0) {
|
||||
UNSAFE.freeMemory(bufRaw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all tests
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
private void test() {
|
||||
testPositive();
|
||||
testNegative();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
CopyMemory cs = new CopyMemory();
|
||||
cs.test();
|
||||
}
|
||||
}
|
@ -29,507 +29,18 @@ import java.lang.reflect.Field;
|
||||
* @summary Test Unsafe.copySwapMemory
|
||||
* @modules java.base/jdk.internal.misc
|
||||
*/
|
||||
public class CopySwap {
|
||||
private static final boolean DEBUG = Boolean.getBoolean("CopySwap.DEBUG");
|
||||
|
||||
public static final long KB = 1024;
|
||||
public static final long MB = KB * 1024;
|
||||
public static final long GB = MB * 1024;
|
||||
|
||||
private static final Unsafe UNSAFE;
|
||||
private static final int SMALL_COPY_SIZE = 32;
|
||||
private static final int BASE_ALIGNMENT = 16;
|
||||
|
||||
static {
|
||||
try {
|
||||
Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
UNSAFE = (jdk.internal.misc.Unsafe) f.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to get Unsafe instance.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static long alignDown(long value, long alignment) {
|
||||
return value & ~(alignment - 1);
|
||||
}
|
||||
|
||||
private static long alignUp(long value, long alignment) {
|
||||
return (value + alignment - 1) & ~(alignment - 1);
|
||||
}
|
||||
|
||||
private static boolean isAligned(long value, long alignment) {
|
||||
return value == alignDown(value, alignment);
|
||||
}
|
||||
|
||||
public class CopySwap extends CopyCommon {
|
||||
private CopySwap() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate verification data for a given offset
|
||||
*
|
||||
* The verification data is used to verify that the correct bytes
|
||||
* have indeed been copied and byte swapped.
|
||||
*
|
||||
* The data is generated based on the offset (in bytes) into the
|
||||
* source buffer. For a native buffer the offset is relative to
|
||||
* the base pointer. For a heap array it is relative to the
|
||||
* address of the first array element.
|
||||
*
|
||||
* This method will return the result of doing an elementSize byte
|
||||
* read starting at offset (in bytes).
|
||||
*
|
||||
* @param offset offset into buffer
|
||||
* @param elemSize size (in bytes) of the element
|
||||
*
|
||||
* @return the verification data, only the least significant
|
||||
* elemSize*8 bits are set, zero extended
|
||||
*/
|
||||
private long getVerificationDataForOffset(long offset, long elemSize) {
|
||||
byte[] bytes = new byte[(int)elemSize];
|
||||
|
||||
for (long i = 0; i < elemSize; i++) {
|
||||
bytes[(int)i] = (byte)(offset + i);
|
||||
}
|
||||
|
||||
long o = UNSAFE.arrayBaseOffset(byte[].class);
|
||||
|
||||
switch ((int)elemSize) {
|
||||
case 1: return Byte.toUnsignedLong(UNSAFE.getByte(bytes, o));
|
||||
case 2: return Short.toUnsignedLong(UNSAFE.getShortUnaligned(bytes, o));
|
||||
case 4: return Integer.toUnsignedLong(UNSAFE.getIntUnaligned(bytes, o));
|
||||
case 8: return UNSAFE.getLongUnaligned(bytes, o);
|
||||
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify byte swapped data
|
||||
*
|
||||
* @param ptr the data to verify
|
||||
* @param srcOffset the srcOffset (in bytes) from which the copy started,
|
||||
* used as key to regenerate the verification data
|
||||
* @param dstOffset the offset (in bytes) in the array at which to start
|
||||
* the verification, relative to the first element in the array
|
||||
* @param size size (in bytes) of data to to verify
|
||||
* @param elemSize size (in bytes) of the individual array elements
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
private void verifySwappedData(GenericPointer ptr, long srcOffset, long dstOffset, long size, long elemSize) {
|
||||
for (long offset = 0; offset < size; offset += elemSize) {
|
||||
long expectedUnswapped = getVerificationDataForOffset(srcOffset + offset, elemSize);
|
||||
long expected = byteSwap(expectedUnswapped, elemSize);
|
||||
|
||||
long actual = getArrayElem(ptr, dstOffset + offset, elemSize);
|
||||
|
||||
if (expected != actual) {
|
||||
throw new RuntimeException("srcOffset: 0x" + Long.toHexString(srcOffset) +
|
||||
" dstOffset: 0x" + Long.toHexString(dstOffset) +
|
||||
" size: 0x" + Long.toHexString(size) +
|
||||
" offset: 0x" + Long.toHexString(offset) +
|
||||
" expectedUnswapped: 0x" + Long.toHexString(expectedUnswapped) +
|
||||
" expected: 0x" + Long.toHexString(expected) +
|
||||
" != actual: 0x" + Long.toHexString(actual));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an array with verification friendly data
|
||||
*
|
||||
* @param ptr pointer to the data to initialize
|
||||
* @param size size (in bytes) of the data
|
||||
* @param elemSize size (in bytes) of the individual elements
|
||||
*/
|
||||
private void initVerificationData(GenericPointer ptr, long size, long elemSize) {
|
||||
for (long offset = 0; offset < size; offset++) {
|
||||
byte data = (byte)getVerificationDataForOffset(offset, 1);
|
||||
|
||||
if (ptr.isOnHeap()) {
|
||||
UNSAFE.putByte(ptr.getObject(), ptr.getOffset() + offset, data);
|
||||
} else {
|
||||
UNSAFE.putByte(ptr.getOffset() + offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a primitive array
|
||||
*
|
||||
* @param size size (in bytes) of all the array elements (elemSize * length)
|
||||
* @param elemSize the size of the array elements
|
||||
*
|
||||
* @return a newly allocated primitive array
|
||||
*/
|
||||
Object allocArray(long size, long elemSize) {
|
||||
int length = (int)(size / elemSize);
|
||||
|
||||
switch ((int)elemSize) {
|
||||
case 2: return new short[length];
|
||||
case 4: return new int[length];
|
||||
case 8: return new long[length];
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid element size: " + elemSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of a primitive array entry
|
||||
*
|
||||
* @param ptr pointer to the data
|
||||
* @param offset offset (in bytes) of the array element, relative to the first element in the array
|
||||
*
|
||||
* @return the array element, as an unsigned long
|
||||
*/
|
||||
private long getArrayElem(GenericPointer ptr, long offset, long elemSize) {
|
||||
if (ptr.isOnHeap()) {
|
||||
Object o = ptr.getObject();
|
||||
int index = (int)(offset / elemSize);
|
||||
|
||||
if (o instanceof short[]) {
|
||||
short[] arr = (short[])o;
|
||||
return Short.toUnsignedLong(arr[index]);
|
||||
} else if (o instanceof int[]) {
|
||||
int[] arr = (int[])o;
|
||||
return Integer.toUnsignedLong(arr[index]);
|
||||
} else if (o instanceof long[]) {
|
||||
long[] arr = (long[])o;
|
||||
return arr[index];
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid object type: " + o.getClass().getName());
|
||||
}
|
||||
} else {
|
||||
long addr = ptr.getOffset() + offset;
|
||||
|
||||
switch ((int)elemSize) {
|
||||
case 1: return Byte.toUnsignedLong(UNSAFE.getByte(addr));
|
||||
case 2: return Short.toUnsignedLong(UNSAFE.getShortUnaligned(null, addr));
|
||||
case 4: return Integer.toUnsignedLong(UNSAFE.getIntUnaligned(null, addr));
|
||||
case 8: return UNSAFE.getLongUnaligned(null, addr);
|
||||
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void putValue(long addr, long elemSize, long value) {
|
||||
switch ((int)elemSize) {
|
||||
case 1: UNSAFE.putByte(addr, (byte)value); break;
|
||||
case 2: UNSAFE.putShortUnaligned(null, addr, (short)value); break;
|
||||
case 4: UNSAFE.putIntUnaligned(null, addr, (int)value); break;
|
||||
case 8: UNSAFE.putLongUnaligned(null, addr, value); break;
|
||||
default: throw new IllegalArgumentException("Invalid element size: " + elemSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the elements for an array
|
||||
*
|
||||
* @param o a primitive heap array
|
||||
*
|
||||
* @return the size (in bytes) of the individual array elements
|
||||
*/
|
||||
private long getArrayElemSize(Object o) {
|
||||
if (o instanceof short[]) {
|
||||
return 2;
|
||||
} else if (o instanceof int[]) {
|
||||
return 4;
|
||||
} else if (o instanceof long[]) {
|
||||
return 8;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid object type: " + o.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Byte swap a value
|
||||
*
|
||||
* @param value the value to swap, only the bytes*8 least significant bits are used
|
||||
* @param size size (in bytes) of the value
|
||||
*
|
||||
* @return the byte swapped value in the bytes*8 least significant bits
|
||||
*/
|
||||
private long byteSwap(long value, long size) {
|
||||
switch ((int)size) {
|
||||
case 2: return Short.toUnsignedLong(Short.reverseBytes((short)value));
|
||||
case 4: return Integer.toUnsignedLong(Integer.reverseBytes((int)value));
|
||||
case 8: return Long.reverseBytes(value);
|
||||
default: throw new IllegalArgumentException("Invalid element size: " + size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify data in a heap array which has *not* been byte swapped
|
||||
*
|
||||
* @param ptr the data to verify
|
||||
* @param startOffset the offset (in bytes) at which to start the verification
|
||||
* @param size size (in bytes) of the data to verify
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
private void verifyUnswappedData(GenericPointer ptr, long startOffset, long size) {
|
||||
for (long elemOffset = startOffset; elemOffset < startOffset + size; elemOffset++) {
|
||||
byte expected = (byte)getVerificationDataForOffset(elemOffset, 1);
|
||||
|
||||
byte actual;
|
||||
if (ptr.isOnHeap()) {
|
||||
actual = UNSAFE.getByte(ptr.getObject(), ptr.getOffset() + elemOffset);
|
||||
} else {
|
||||
actual = UNSAFE.getByte(ptr.getOffset() + elemOffset);
|
||||
}
|
||||
|
||||
if (expected != actual) {
|
||||
throw new RuntimeException("startOffset: 0x" + Long.toHexString(startOffset) +
|
||||
" size: 0x" + Long.toHexString(size) +
|
||||
" elemOffset: 0x" + Long.toHexString(elemOffset) +
|
||||
" expected: 0x" + Long.toHexString(expected) +
|
||||
" != actual: 0x" + Long.toHexString(actual));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy and byte swap data from the source to the destination
|
||||
*
|
||||
* This method will pre-populate the whole source and destination
|
||||
* buffers with verification friendly data. It will then use
|
||||
* copySwapMemory to fill part of the destination buffer with
|
||||
* swapped data from the source. Some space (padding) will be
|
||||
* left before and after the data in the destination buffer, which
|
||||
* should not be touched/overwritten by the copy call.
|
||||
*
|
||||
* Note: Both source and destination buffers will be overwritten!
|
||||
*
|
||||
* @param src source buffer to copy from
|
||||
* @param srcOffset the offset (in bytes) in the source buffer, relative to
|
||||
* the first array element, at which to start reading data
|
||||
* @param dst destination buffer to copy to
|
||||
* @param dstOffset the offset (in bytes) in the destination
|
||||
* buffer, relative to the first array element, at which to
|
||||
* start writing data
|
||||
* @param bufSize the size (in bytes) of the src and dst arrays
|
||||
* @param copyBytes the size (in bytes) of the copy to perform,
|
||||
* must be a multiple of elemSize
|
||||
* @param elemSize the size (in bytes) of the elements to byte swap
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
private void testCopySwap(GenericPointer src, long srcOffset,
|
||||
GenericPointer dst, long dstOffset,
|
||||
long bufSize, long copyBytes, long elemSize) {
|
||||
if (!isAligned(copyBytes, elemSize)) {
|
||||
throw new IllegalArgumentException(
|
||||
"copyBytes (" + copyBytes + ") must be a multiple of elemSize (" + elemSize + ")");
|
||||
}
|
||||
if (src.isOnHeap() && !isAligned(srcOffset, elemSize)) {
|
||||
throw new IllegalArgumentException(
|
||||
"srcOffset (" + srcOffset + ") must be a multiple of elemSize (" + elemSize + ")");
|
||||
}
|
||||
if (dst.isOnHeap() && !isAligned(dstOffset, elemSize)) {
|
||||
throw new IllegalArgumentException(
|
||||
"dstOffset (" + dstOffset + ") must be a multiple of elemSize (" + elemSize + ")");
|
||||
}
|
||||
if (srcOffset + copyBytes > bufSize) {
|
||||
throw new IllegalArgumentException(
|
||||
"srcOffset (" + srcOffset + ") + copyBytes (" + copyBytes + ") > bufSize (" + bufSize + ")");
|
||||
}
|
||||
if (dstOffset + copyBytes > bufSize) {
|
||||
throw new IllegalArgumentException(
|
||||
"dstOffset (" + dstOffset + ") + copyBytes (" + copyBytes + ") > bufSize (" + bufSize + ")");
|
||||
}
|
||||
|
||||
// Initialize the whole source buffer with a verification friendly pattern (no 0x00 bytes)
|
||||
initVerificationData(src, bufSize, elemSize);
|
||||
if (!src.equals(dst)) {
|
||||
initVerificationData(dst, bufSize, elemSize);
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println("===before===");
|
||||
for (int offset = 0; offset < bufSize; offset += elemSize) {
|
||||
long srcValue = getArrayElem(src, offset, elemSize);
|
||||
long dstValue = getArrayElem(dst, offset, elemSize);
|
||||
|
||||
System.out.println("offs=0x" + Long.toHexString(Integer.toUnsignedLong(offset)) +
|
||||
" src=0x" + Long.toHexString(srcValue) +
|
||||
" dst=0x" + Long.toHexString(dstValue));
|
||||
}
|
||||
}
|
||||
|
||||
// Copy & swap data into the middle of the destination buffer
|
||||
UNSAFE.copySwapMemory(src.getObject(),
|
||||
src.getOffset() + srcOffset,
|
||||
dst.getObject(),
|
||||
dst.getOffset() + dstOffset,
|
||||
copyBytes,
|
||||
elemSize);
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println("===after===");
|
||||
for (int offset = 0; offset < bufSize; offset += elemSize) {
|
||||
long srcValue = getArrayElem(src, offset, elemSize);
|
||||
long dstValue = getArrayElem(dst, offset, elemSize);
|
||||
|
||||
System.out.println("offs=0x" + Long.toHexString(Integer.toUnsignedLong(offset)) +
|
||||
" src=0x" + Long.toHexString(srcValue) +
|
||||
" dst=0x" + Long.toHexString(dstValue));
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the the front padding is unchanged
|
||||
verifyUnswappedData(dst, 0, dstOffset);
|
||||
|
||||
// Verify swapped data
|
||||
verifySwappedData(dst, srcOffset, dstOffset, copyBytes, elemSize);
|
||||
|
||||
// Verify that the back back padding is unchanged
|
||||
long frontAndDataBytes = dstOffset + copyBytes;
|
||||
long trailingBytes = bufSize - frontAndDataBytes;
|
||||
verifyUnswappedData(dst, frontAndDataBytes, trailingBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test various configurations copy-swapping from one buffer to the other
|
||||
*
|
||||
* @param src the source buffer to copy from
|
||||
* @param dst the destination buffer to copy to
|
||||
* @param size size (in bytes) of the buffers
|
||||
* @param elemSize size (in bytes) of the individual elements
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
public void testBufferPair(GenericPointer src, GenericPointer dst, long size, long elemSize) {
|
||||
// offset in source from which to start reading data
|
||||
for (long srcOffset = 0; srcOffset < size; srcOffset += (src.isOnHeap() ? elemSize : 1)) {
|
||||
|
||||
// offset in destination at which to start writing data
|
||||
for (int dstOffset = 0; dstOffset < size; dstOffset += (dst.isOnHeap() ? elemSize : 1)) {
|
||||
|
||||
// number of bytes to copy
|
||||
long maxCopyBytes = Math.min(size - srcOffset, size - dstOffset);
|
||||
for (long copyBytes = 0; copyBytes < maxCopyBytes; copyBytes += elemSize) {
|
||||
try {
|
||||
testCopySwap(src, srcOffset, dst, dstOffset, size, copyBytes, elemSize);
|
||||
} catch (RuntimeException e) {
|
||||
// Wrap the exception in another exception to catch the relevant configuration data
|
||||
throw new RuntimeException("testBufferPair: " +
|
||||
"src=" + src +
|
||||
" dst=" + dst +
|
||||
" elemSize=0x" + Long.toHexString(elemSize) +
|
||||
" copyBytes=0x" + Long.toHexString(copyBytes) +
|
||||
" srcOffset=0x" + Long.toHexString(srcOffset) +
|
||||
" dstOffset=0x" + Long.toHexString(dstOffset),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test copying between various permutations of buffers
|
||||
*
|
||||
* @param buffers buffers to permute (src x dst)
|
||||
* @param size size (in bytes) of buffers
|
||||
* @param elemSize size (in bytes) of individual elements
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
public void testPermuteBuffers(GenericPointer[] buffers, long size, long elemSize) {
|
||||
for (int srcIndex = 0; srcIndex < buffers.length; srcIndex++) {
|
||||
for (int dstIndex = 0; dstIndex < buffers.length; dstIndex++) {
|
||||
testBufferPair(buffers[srcIndex], buffers[dstIndex], size, elemSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test copying of a specific element size
|
||||
*
|
||||
* @param size size (in bytes) of buffers to allocate
|
||||
* @param elemSize size (in bytes) of individual elements
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
private void testElemSize(long size, long elemSize) {
|
||||
long buf1Raw = 0;
|
||||
long buf2Raw = 0;
|
||||
|
||||
try {
|
||||
buf1Raw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
|
||||
long buf1 = alignUp(buf1Raw, BASE_ALIGNMENT);
|
||||
|
||||
buf2Raw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
|
||||
long buf2 = alignUp(buf2Raw, BASE_ALIGNMENT);
|
||||
|
||||
GenericPointer[] buffers = {
|
||||
new GenericPointer(buf1),
|
||||
new GenericPointer(buf2),
|
||||
new GenericPointer(allocArray(size, elemSize)),
|
||||
new GenericPointer(allocArray(size, elemSize))
|
||||
};
|
||||
|
||||
testPermuteBuffers(buffers, size, elemSize);
|
||||
} finally {
|
||||
if (buf1Raw != 0) {
|
||||
UNSAFE.freeMemory(buf1Raw);
|
||||
}
|
||||
if (buf2Raw != 0) {
|
||||
UNSAFE.freeMemory(buf2Raw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that small copy swaps work
|
||||
*/
|
||||
private void testSmallCopy() {
|
||||
int smallBufSize = SMALL_COPY_SIZE;
|
||||
|
||||
// Test various element types and heap/native combinations
|
||||
for (long elemSize = 2; elemSize <= 8; elemSize <<= 1) {
|
||||
testElemSize(smallBufSize, elemSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify that large copy swaps work
|
||||
*/
|
||||
private void testLargeCopy() {
|
||||
long size = 2 * GB + 8;
|
||||
long bufRaw = 0;
|
||||
|
||||
// Check that a large native copy succeeds
|
||||
try {
|
||||
try {
|
||||
bufRaw = UNSAFE.allocateMemory(size + BASE_ALIGNMENT);
|
||||
} catch (OutOfMemoryError e) {
|
||||
// Accept failure, skip test
|
||||
return;
|
||||
}
|
||||
|
||||
long buf = alignUp(bufRaw, BASE_ALIGNMENT);
|
||||
|
||||
UNSAFE.copySwapMemory(null, buf, null, buf, size, 8);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("copySwapMemory of large buffer failed");
|
||||
} finally {
|
||||
if (bufRaw != 0) {
|
||||
UNSAFE.freeMemory(bufRaw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run positive tests
|
||||
*
|
||||
* @throws RuntimeException if an error is found
|
||||
*/
|
||||
private void testPositive() {
|
||||
testSmallCopy();
|
||||
testLargeCopy();
|
||||
testSmallCopy(true);
|
||||
testLargeCopy(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -542,7 +53,7 @@ public class CopySwap {
|
||||
|
||||
try {
|
||||
bufRaw = UNSAFE.allocateMemory(1024);
|
||||
long buf = alignUp(bufRaw, BASE_ALIGNMENT);
|
||||
long buf = CopyCommon.alignUp(bufRaw, CopyCommon.BASE_ALIGNMENT);
|
||||
short[] arr = new short[16];
|
||||
|
||||
// Check various illegal element sizes
|
||||
@ -586,22 +97,6 @@ public class CopySwap {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Check that a NULL source throws NPE
|
||||
UNSAFE.copySwapMemory(null, 0, null, buf, 16, 2);
|
||||
throw new RuntimeException("copySwapMemory failed to throw NPE");
|
||||
} catch (NullPointerException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
try {
|
||||
// Check that a NULL destination throws NPE
|
||||
UNSAFE.copySwapMemory(null, buf, null, 0, 16, 2);
|
||||
throw new RuntimeException("copySwapMemory failed to throw NPE");
|
||||
} catch (NullPointerException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
try {
|
||||
// Check that a reference array destination throws IAE
|
||||
UNSAFE.copySwapMemory(null, buf, new Object[16], UNSAFE.arrayBaseOffset(Object[].class), 16, 8);
|
||||
@ -653,59 +148,4 @@ public class CopySwap {
|
||||
CopySwap cs = new CopySwap();
|
||||
cs.test();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to represent a "pointer" - either a heap array or
|
||||
* a pointer to a native buffer.
|
||||
*
|
||||
* In the case of a native pointer, the Object is null and the offset is
|
||||
* the absolute address of the native buffer.
|
||||
*
|
||||
* In the case of a heap object, the Object is a primitive array, and
|
||||
* the offset will be set to the base offset to the first element, meaning
|
||||
* the object and the offset together form a double-register pointer.
|
||||
*/
|
||||
static class GenericPointer {
|
||||
private final Object o;
|
||||
private final long offset;
|
||||
|
||||
private GenericPointer(Object o, long offset) {
|
||||
this.o = o;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "GenericPointer(o={" + o + "}, offset=0x" + Long.toHexString(offset) + ")";
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof GenericPointer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GenericPointer otherp = (GenericPointer)other;
|
||||
|
||||
return o == otherp.o && offset == otherp.offset;
|
||||
}
|
||||
|
||||
GenericPointer(Object o) {
|
||||
this(o, UNSAFE.arrayBaseOffset(o.getClass()));
|
||||
}
|
||||
|
||||
GenericPointer(long offset) {
|
||||
this(null, offset);
|
||||
}
|
||||
|
||||
public boolean isOnHeap() {
|
||||
return o != null;
|
||||
}
|
||||
|
||||
public Object getObject() {
|
||||
return o;
|
||||
}
|
||||
|
||||
public long getOffset() {
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,7 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @summary Unit test for sun.net.idn.Punycode
|
||||
* @bug 4737170
|
||||
* @bug 4737170 8060097
|
||||
* @modules java.base/sun.net.idn java.base/sun.text.normalizer
|
||||
* @library .
|
||||
* @compile -XDignore.symbol.file TestStringPrep.java NFS4StringPrep.java
|
||||
@ -41,6 +41,7 @@
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
import sun.net.idn.StringPrep;
|
||||
import sun.text.normalizer.UCharacterIterator;
|
||||
@ -209,7 +210,7 @@ public class TestStringPrep {
|
||||
src = "THISISATEST";
|
||||
byte[] dest = NFS4StringPrep.cs_prepare(src.getBytes("UTF-8"), false);
|
||||
String destStr = new String(dest, "UTF-8");
|
||||
if(!src.toLowerCase().equals(destStr)){
|
||||
if(!src.toLowerCase(Locale.ROOT).equals(destStr)){
|
||||
fail("Did not get expected output. Expected: "+ prettify(src)+
|
||||
" Got: " + prettify(destStr));
|
||||
}
|
||||
@ -275,7 +276,7 @@ public class TestStringPrep {
|
||||
|
||||
private static String hex(char ch) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
String foo = Integer.toString(ch,16).toUpperCase();
|
||||
String foo = Integer.toString(ch,16).toUpperCase(Locale.ROOT);
|
||||
for (int i = foo.length(); i < 4; ++i) {
|
||||
result.append('0');
|
||||
}
|
||||
|
@ -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
|
||||
@ -21,55 +21,52 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8076359 8133151
|
||||
* @summary Test for jdk.security.provider.preferred security property
|
||||
* @requires os.name == "SunOS"
|
||||
* @run main/othervm PreferredProviderNegativeTest preJCESet AES:OracleUcrypto false
|
||||
* @run main/othervm PreferredProviderNegativeTest preJCESet AES:SunNegative true
|
||||
* @run main/othervm PreferredProviderNegativeTest afterJCESet AES:SunJGSS
|
||||
* @run main/othervm PreferredProviderNegativeTest afterJCESet AES:SunECNegative
|
||||
* @run main/othervm PreferredProviderNegativeTest invalidAlg AESNegative:SunJCE
|
||||
*/
|
||||
|
||||
import java.security.Security;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8076359 8133151 8150512
|
||||
* @summary Test for jdk.security.provider.preferred security property
|
||||
* @run main/othervm PreferredProviderNegativeTest preSet AES false
|
||||
* @run main/othervm PreferredProviderNegativeTest preSet AES:SunNegative true
|
||||
* @run main/othervm PreferredProviderNegativeTest afterSet AES:SunJGSS
|
||||
* @run main/othervm PreferredProviderNegativeTest afterSet AES:SunECNegative
|
||||
* @run main/othervm PreferredProviderNegativeTest invalidAlg AESInvalid:SunJCE
|
||||
*/
|
||||
public class PreferredProviderNegativeTest {
|
||||
|
||||
static final String SEC_PREF_PROP = "jdk.security.provider.preferred";
|
||||
|
||||
/*
|
||||
* Test security property could be set by valid and invalid provider
|
||||
* before JCE was loaded
|
||||
*/
|
||||
public static void preJCESet(String value, boolean negativeProvider)
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException {
|
||||
Security.setProperty("jdk.security.provider.preferred", value);
|
||||
|
||||
if (!Security.getProperty("jdk.security.provider.preferred")
|
||||
.equals(value)) {
|
||||
throw new RuntimeException(
|
||||
"Test Failed:The property wasn't set");
|
||||
Security.setProperty(SEC_PREF_PROP, value);
|
||||
|
||||
if (!Security.getProperty(SEC_PREF_PROP).equals(value)) {
|
||||
throw new RuntimeException("Test Failed:The property wasn't set");
|
||||
}
|
||||
|
||||
String[] arrays = value.split(":");
|
||||
Cipher cipher = Cipher.getInstance(arrays[0]);
|
||||
|
||||
if (negativeProvider) {
|
||||
if (cipher.getProvider().getName().equals(arrays[1])) {
|
||||
throw new RuntimeException(
|
||||
"Test Failed:The provider shouldn't be set");
|
||||
"Test Failed:The provider shouldn't be set.");
|
||||
}
|
||||
} else {
|
||||
if (!cipher.getProvider().getName().equals(arrays[1])) {
|
||||
throw new RuntimeException(
|
||||
"Test Faild:The provider could be set "
|
||||
+ "by valid provider ");
|
||||
throw new RuntimeException("Test Faild:The provider could be "
|
||||
+ "set by valid provider.");
|
||||
}
|
||||
}
|
||||
System.out.println("Test Pass");
|
||||
System.out.println("Test Pass.");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -81,10 +78,10 @@ public class PreferredProviderNegativeTest {
|
||||
String[] arrays = value.split(":");
|
||||
Cipher cipher = Cipher.getInstance(arrays[0]);
|
||||
|
||||
Security.setProperty("jdk.security.provider.preferred", value);
|
||||
Security.setProperty(SEC_PREF_PROP, value);
|
||||
if (!cipher.getProvider().getName().equals("SunJCE")) {
|
||||
throw new RuntimeException(
|
||||
"Test Failed:The security property can't be updated after JCE load.");
|
||||
throw new RuntimeException("Test Failed:The security property can't"
|
||||
+ " be updated after JCE load.");
|
||||
}
|
||||
System.out.println("Test Pass");
|
||||
}
|
||||
@ -94,10 +91,11 @@ public class PreferredProviderNegativeTest {
|
||||
String[] arrays = value.split(":");
|
||||
|
||||
try {
|
||||
Security.setProperty("jdk.security.provider.preferred", value);
|
||||
Security.setProperty(SEC_PREF_PROP, value);
|
||||
Cipher.getInstance(arrays[0]);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.println("Test Pass:Got NoSuchAlgorithmException as expired");
|
||||
System.out.println(
|
||||
"Test Pass:Got NoSuchAlgorithmException as expired");
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException(
|
||||
@ -106,15 +104,25 @@ public class PreferredProviderNegativeTest {
|
||||
|
||||
public static void main(String[] args)
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException {
|
||||
boolean negativeProvider;
|
||||
|
||||
if (args.length >= 2) {
|
||||
switch (args[0]) {
|
||||
case "preJCESet":
|
||||
negativeProvider = Boolean.valueOf(args[2]);
|
||||
PreferredProviderNegativeTest.preJCESet(args[1], negativeProvider);
|
||||
case "preSet":
|
||||
boolean negativeProvider = Boolean.valueOf(args[2]);
|
||||
boolean solaris = System.getProperty("os.name")
|
||||
.toLowerCase().contains("sun");
|
||||
String value = args[1];
|
||||
if (args[1].split(":").length < 2) {
|
||||
if (solaris) {
|
||||
value += ":OracleUcrypto";
|
||||
} else {
|
||||
value += ":SunJCE";
|
||||
}
|
||||
}
|
||||
PreferredProviderNegativeTest.preJCESet(
|
||||
value, negativeProvider);
|
||||
break;
|
||||
case "afterJCESet":
|
||||
case "afterSet":
|
||||
PreferredProviderNegativeTest.afterJCESet(args[1]);
|
||||
break;
|
||||
case "invalidAlg":
|
||||
@ -127,4 +135,3 @@ public class PreferredProviderNegativeTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,97 +21,131 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8076359 8133151 8145344
|
||||
* @summary Test the value for new jdk.security.provider.preferred security property
|
||||
* @requires os.name == "SunOS"
|
||||
*/
|
||||
|
||||
import java.security.KeyFactory;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Security;
|
||||
import java.security.Provider;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8076359 8133151 8145344 8150512
|
||||
* @summary Test the value for new jdk.security.provider.preferred
|
||||
* security property
|
||||
*/
|
||||
public class PreferredProviderTest {
|
||||
|
||||
private static final List<DataTuple> SPARC_DATA = Arrays.asList(
|
||||
new DataTuple("SHA1", "SUN"), new DataTuple("SHA-1", "SUN"),
|
||||
new DataTuple("SHA-224", "SUN"), new DataTuple("SHA-256", "SUN"),
|
||||
new DataTuple("SHA-384", "SUN"), new DataTuple("SHA-512", "SUN"));
|
||||
private static final List<DataTuple> X86_DATA = Arrays
|
||||
.asList(new DataTuple("RSA", "SunRsaSign"));
|
||||
|
||||
public void RunTest(String type)
|
||||
public void RunTest(String type, String os)
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException {
|
||||
String preferredProvider = Security
|
||||
.getProperty("jdk.security.provider.preferred");
|
||||
|
||||
String actualProvider = null;
|
||||
if (type.equals("sparcv9")) {
|
||||
if (!preferredProvider.equals(
|
||||
"AES:SunJCE, SHA1:SUN, SHA-224:SUN, SHA-256:SUN, SHA-384:SUN, SHA-512:SUN")) {
|
||||
throw new RuntimeException(
|
||||
"Test Failed: wrong jdk.security.provider.preferred "
|
||||
+ "value on solaris-sparcv9");
|
||||
}
|
||||
for (DataTuple dataTuple : SPARC_DATA) {
|
||||
MessageDigest md = MessageDigest
|
||||
.getInstance(dataTuple.algorithm);
|
||||
actualProvider = md.getProvider().getName();
|
||||
if (!actualProvider.equals(dataTuple.provider)) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test Failed:Got wrong "
|
||||
+ "provider from Solaris-sparcv9 platform,"
|
||||
+ "Expected Provider: %s, Returned Provider: %s",
|
||||
dataTuple.provider, actualProvider));
|
||||
}
|
||||
}
|
||||
} else if (type.equals("amd64")) {
|
||||
if (!preferredProvider.equals("AES:SunJCE, RSA:SunRsaSign")) {
|
||||
throw new RuntimeException(
|
||||
"Test Failed: wrong jdk.security.provider.preferred "
|
||||
+ "value on solaris-x86");
|
||||
}
|
||||
for (DataTuple dataTuple : X86_DATA) {
|
||||
KeyFactory keyFactory = KeyFactory
|
||||
.getInstance(dataTuple.algorithm);
|
||||
actualProvider = keyFactory.getProvider().getName();
|
||||
if (!actualProvider.equals(dataTuple.provider)) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test Failed:Got wrong "
|
||||
+ "provider from Solaris-x86 platform,"
|
||||
+ "Expected Provider: %s, Returned Provider: %s",
|
||||
dataTuple.provider, actualProvider));
|
||||
}
|
||||
}
|
||||
boolean solaris = os.contains("sun");
|
||||
String preferredProp
|
||||
= "AES/GCM/NoPadding:SunJCE, MessageDigest.SHA-256:SUN";
|
||||
System.out.printf("%nExecuting test for the platform '%s'%n", os);
|
||||
if (!solaris) {
|
||||
//For other platform it will try to set the preferred algorithm and
|
||||
//Provider and verify the usage of it.
|
||||
Security.setProperty(
|
||||
"jdk.security.provider.preferred", preferredProp);
|
||||
verifyPreferredProviderProperty(os, type, preferredProp);
|
||||
|
||||
verifyDigestProvider(os, type, Arrays.asList(
|
||||
new DataTuple("SHA-256", "SUN")));
|
||||
} else {
|
||||
throw new RuntimeException("Test Failed: wrong platform value");
|
||||
//For solaris the preferred algorithm/provider is already set in
|
||||
//java.security file which will be verified.
|
||||
switch (type) {
|
||||
case "sparcv9":
|
||||
preferredProp = "AES:SunJCE, SHA1:SUN, SHA-224:SUN,"
|
||||
+ " SHA-256:SUN, SHA-384:SUN, SHA-512:SUN";
|
||||
verifyPreferredProviderProperty(os, type, preferredProp);
|
||||
|
||||
verifyDigestProvider(os, type, Arrays.asList(
|
||||
new DataTuple("SHA1", "SUN"),
|
||||
new DataTuple("SHA-1", "SUN"),
|
||||
new DataTuple("SHA-224", "SUN"),
|
||||
new DataTuple("SHA-256", "SUN"),
|
||||
new DataTuple("SHA-384", "SUN"),
|
||||
new DataTuple("SHA-512", "SUN")));
|
||||
break;
|
||||
case "amd64":
|
||||
preferredProp = "AES:SunJCE, RSA:SunRsaSign";
|
||||
verifyPreferredProviderProperty(os, type, preferredProp);
|
||||
|
||||
verifyKeyFactoryProvider(os, type, Arrays.asList(
|
||||
new DataTuple("RSA", "SunRsaSign")));
|
||||
break;
|
||||
}
|
||||
verifyDigestProvider(os, type, Arrays.asList(
|
||||
new DataTuple("MD5", "OracleUcrypto")));
|
||||
}
|
||||
|
||||
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
actualProvider = cipher.getProvider().getName();
|
||||
if (!actualProvider.equals("SunJCE")) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test Failed:Got wrong provider from Solaris-%s platform, "
|
||||
+ "Expected Provider: SunJCE, Returned Provider: %s",
|
||||
type, actualProvider));
|
||||
throw new RuntimeException(String.format("Test Failed:Got wrong "
|
||||
+ "provider from %s-%s platform, Expected Provider: SunJCE,"
|
||||
+ " Returned Provider: %s", os, type, actualProvider));
|
||||
}
|
||||
}
|
||||
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
actualProvider = md.getProvider().getName();
|
||||
if (!actualProvider.equals("OracleUcrypto")) {
|
||||
private static void verifyPreferredProviderProperty(String os, String arch,
|
||||
String preferred) {
|
||||
String preferredProvider
|
||||
= Security.getProperty("jdk.security.provider.preferred");
|
||||
if (!preferredProvider.equals(preferred)) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test Failed:Got wrong provider from Solaris-%s platform,"
|
||||
+ "Expected Provider: OracleUcrypto, Returned Provider: %s",
|
||||
type, actualProvider));
|
||||
"Test Failed: wrong jdk.security.provider.preferred value "
|
||||
+ "on %s-%s", os, arch));
|
||||
}
|
||||
System.out.println(
|
||||
"Preferred provider security property verification complete.");
|
||||
}
|
||||
|
||||
private static void verifyDigestProvider(String os, String arch,
|
||||
List<DataTuple> algoProviders) throws NoSuchAlgorithmException {
|
||||
for (DataTuple dataTuple : algoProviders) {
|
||||
System.out.printf(
|
||||
"Verifying MessageDigest for '%s'%n", dataTuple.algorithm);
|
||||
MessageDigest md = MessageDigest.getInstance(dataTuple.algorithm);
|
||||
matchProvider(md.getProvider(), dataTuple.provider,
|
||||
dataTuple.algorithm, os, arch);
|
||||
}
|
||||
System.out.println(
|
||||
"Preferred MessageDigest algorithm verification successful.");
|
||||
}
|
||||
|
||||
private static void verifyKeyFactoryProvider(String os, String arch,
|
||||
List<DataTuple> algoProviders) throws NoSuchAlgorithmException {
|
||||
for (DataTuple dataTuple : algoProviders) {
|
||||
System.out.printf(
|
||||
"Verifying KeyFactory for '%s'%n", dataTuple.algorithm);
|
||||
KeyFactory kf = KeyFactory.getInstance(dataTuple.algorithm);
|
||||
matchProvider(kf.getProvider(), dataTuple.provider,
|
||||
dataTuple.algorithm, os, arch);
|
||||
}
|
||||
System.out.println(
|
||||
"Preferred KeyFactory algorithm verification successful.");
|
||||
}
|
||||
|
||||
private static void matchProvider(Provider provider, String expected,
|
||||
String algo, String os, String arch) {
|
||||
if (!provider.getName().equals(expected)) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Test Failed:Got wrong provider from %s-%s platform, "
|
||||
+ "for algorithm %s. Expected Provider: %s,"
|
||||
+ " Returned Provider: %s", os, arch, algo,
|
||||
expected, provider.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
private static class DataTuple {
|
||||
|
||||
private final String provider;
|
||||
private final String algorithm;
|
||||
|
||||
@ -123,10 +157,9 @@ public class PreferredProviderTest {
|
||||
|
||||
public static void main(String[] args)
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException {
|
||||
|
||||
String arch = System.getProperty("os.arch");
|
||||
String os = System.getProperty("os.name").toLowerCase();
|
||||
String arch = System.getProperty("os.arch").toLowerCase();
|
||||
PreferredProviderTest pp = new PreferredProviderTest();
|
||||
pp.RunTest(arch);
|
||||
pp.RunTest(arch, os);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -24,6 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 6844193
|
||||
* @key intermittent
|
||||
* @compile -XDignore.symbol.file MaxRetries.java
|
||||
* @run main/othervm/timeout=300 MaxRetries
|
||||
* @summary support max_retries in krb5.conf
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,6 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 7162687
|
||||
* @key intermittent
|
||||
* @summary enhance KDC server availability detection
|
||||
* @compile -XDignore.symbol.file Unreachable.java
|
||||
* @run main/othervm/timeout=10 Unreachable
|
||||
|
@ -32,6 +32,7 @@ import java.security.interfaces.RSAPrivateCrtKey;
|
||||
/*
|
||||
* @test
|
||||
* @bug 8023546
|
||||
* @key intermittent
|
||||
* @modules java.base/sun.security.x509
|
||||
* java.base/sun.security.tools.keytool
|
||||
* @summary sun/security/mscapi/ShortRSAKey1024.sh fails intermittently
|
||||
|
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//
|
||||
// SunJSSE does not support dynamic system properties, no way to re-use
|
||||
// system properties in samevm/agentvm mode.
|
||||
//
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
import javax.net.ssl.SSLServerSocket;
|
||||
import javax.net.ssl.SSLServerSocketFactory;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8149169
|
||||
* @summary Test for BufferOverflowException during read from SSLSocket when
|
||||
* large packet is coming from server after server initiated handshake
|
||||
* @run main/othervm LargePacketAfterHandshakeTest
|
||||
*/
|
||||
public class LargePacketAfterHandshakeTest {
|
||||
static String pathToStores = "../../../../javax/net/ssl/etc";
|
||||
static String keyStoreFile = "keystore";
|
||||
static String trustStoreFile = "truststore";
|
||||
static String passwd = "passphrase";
|
||||
|
||||
volatile static int serverport = -1;
|
||||
volatile static boolean serverReady = false;
|
||||
volatile static boolean clientDone = false;
|
||||
volatile static Exception serverException = null;
|
||||
|
||||
public static void runServer() {
|
||||
try {
|
||||
System.out.println("Server: Started server thread.");
|
||||
SSLServerSocketFactory ssf =
|
||||
(SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
|
||||
SSLServerSocket s = (SSLServerSocket)ssf.createServerSocket(0);
|
||||
serverport = s.getLocalPort();
|
||||
System.out.println("Server: Started, listening on port " +
|
||||
serverport + ".");
|
||||
serverReady = true;
|
||||
SSLSocket c = (SSLSocket)s.accept();
|
||||
s.close();
|
||||
System.out.println(
|
||||
"Server: Accepted client connection and closed server socket.");
|
||||
BufferedReader r = new BufferedReader(
|
||||
new InputStreamReader(c.getInputStream()));
|
||||
BufferedWriter w = new BufferedWriter(
|
||||
new OutputStreamWriter(c.getOutputStream()));
|
||||
String echostring = r.readLine();
|
||||
System.out.println("Server: Read " + echostring.length() +
|
||||
" chars of input data.");
|
||||
c.startHandshake();
|
||||
System.out.println("Server: Kicked new handshake.");
|
||||
w.write(echostring);
|
||||
w.newLine();
|
||||
w.flush();
|
||||
System.out.println("Server: Echoed " + echostring.length() +
|
||||
" chars of input data.");
|
||||
while (!clientDone) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Server: Caught InterruptedException.");
|
||||
}
|
||||
}
|
||||
r.close();
|
||||
w.close();
|
||||
c.close();
|
||||
System.out.println(
|
||||
"Server: Closed streams and client socket, exiting.");
|
||||
} catch (Exception e) {
|
||||
System.out.println("Server: Caught Exception.");
|
||||
e.printStackTrace();
|
||||
serverReady = true;
|
||||
serverException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void runClient() throws IOException {
|
||||
try {
|
||||
SSLSocketFactory f =
|
||||
(SSLSocketFactory)SSLSocketFactory.getDefault();
|
||||
System.out.println("Client: Initialized.");
|
||||
while (!serverReady) {
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Client: Caught InterruptedException.");
|
||||
}
|
||||
}
|
||||
SSLSocket c = (SSLSocket)f.createSocket("localhost", serverport);
|
||||
BufferedWriter w = new BufferedWriter(
|
||||
new OutputStreamWriter(c.getOutputStream()));
|
||||
BufferedReader r = new BufferedReader(
|
||||
new InputStreamReader(c.getInputStream()));
|
||||
System.out.println("Client: Connected.");
|
||||
String echoPattern = "Otto";
|
||||
StringBuilder echoBuilder =
|
||||
new StringBuilder(4500 + echoPattern.length());
|
||||
while (echoBuilder.length() < 4500) {
|
||||
echoBuilder.append(echoPattern);
|
||||
}
|
||||
String echostring = echoBuilder.toString();
|
||||
w.write(echostring);
|
||||
w.newLine();
|
||||
w.flush();
|
||||
System.out.println("Client: Sent " + echostring.length() +
|
||||
" chars of data.");
|
||||
String echoresponse = r.readLine();
|
||||
clientDone = true;
|
||||
System.out.println("Client: Read " + echoresponse.length() +
|
||||
" chars of data.");
|
||||
w.close();
|
||||
r.close();
|
||||
c.close();
|
||||
System.out.println("Client: Closed streams and socket, exiting.");
|
||||
} catch (IOException e) {
|
||||
System.out.println("Client: Caught Exception.");
|
||||
e.printStackTrace();
|
||||
clientDone = true;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String keyFilename = System.getProperty("test.src", "./") + "/" +
|
||||
pathToStores + "/" + keyStoreFile;
|
||||
String trustFilename = System.getProperty("test.src", "./") + "/" +
|
||||
pathToStores + "/" + trustStoreFile;
|
||||
|
||||
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);
|
||||
|
||||
Thread serverThread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
runServer();
|
||||
}
|
||||
};
|
||||
serverThread.start();
|
||||
runClient();
|
||||
while (serverThread.isAlive()) {
|
||||
try {
|
||||
serverThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Main: Caught InterruptedException " +
|
||||
" waiting for server Thread.");
|
||||
}
|
||||
}
|
||||
if (serverException != null) {
|
||||
throw serverException;
|
||||
}
|
||||
}
|
||||
}
|
@ -21,26 +21,18 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Layer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.internal.PluginRepository;
|
||||
import jdk.tools.jlink.internal.TaskHelper;
|
||||
import jdk.tools.jlink.internal.plugins.PluginsResourceBundle;
|
||||
import tests.Helper;
|
||||
import tests.JImageGenerator;
|
||||
import tests.JImageValidator;
|
||||
import tests.Result;
|
||||
|
||||
/*
|
||||
* @test
|
||||
@ -50,6 +42,7 @@ import tests.JImageValidator;
|
||||
* @modules java.base/jdk.internal.jimage
|
||||
* jdk.jdeps/com.sun.tools.classfile
|
||||
* jdk.jlink/jdk.tools.jlink.internal
|
||||
* jdk.jlink/jdk.tools.jlink.internal.plugins
|
||||
* jdk.jlink/jdk.tools.jmod
|
||||
* jdk.jlink/jdk.tools.jimage
|
||||
* jdk.compiler
|
||||
@ -65,6 +58,7 @@ public class IncludeLocalesPluginTest {
|
||||
private final static int EXPECTED_LOCATIONS = 1;
|
||||
private final static int UNEXPECTED_PATHS = 2;
|
||||
private final static int AVAILABLE_LOCALES = 3;
|
||||
private final static int ERROR_MESSAGE = 4;
|
||||
|
||||
private final static Object[][] testData = {
|
||||
// without --include-locales option: should include all locales
|
||||
@ -144,6 +138,7 @@ public class IncludeLocalesPluginTest {
|
||||
"yav_CM yo yo_BJ yo_NG zgh zgh_MA zh zh_CN zh_CN_#Hans zh_HK " +
|
||||
"zh_HK_#Hans zh_HK_#Hant zh_MO_#Hans zh_MO_#Hant zh_SG zh_SG_#Hans " +
|
||||
"zh_TW zh_TW_#Hant zh__#Hans zh__#Hant zu zu_ZA",
|
||||
"",
|
||||
},
|
||||
|
||||
// All English/Japanese locales
|
||||
@ -173,6 +168,7 @@ public class IncludeLocalesPluginTest {
|
||||
"en_PW en_RW en_SB en_SC en_SD en_SG en_SH en_SL en_SS en_SX en_SZ " +
|
||||
"en_TC en_TK en_TO en_TT en_TV en_TZ en_UG en_UM en_US en_US_POSIX " +
|
||||
"en_VC en_VG en_VI en_VU en_WS en_ZA en_ZM en_ZW ja ja_JP ja_JP_JP_#u-ca-japanese",
|
||||
"",
|
||||
},
|
||||
|
||||
// All locales in India
|
||||
@ -201,6 +197,7 @@ public class IncludeLocalesPluginTest {
|
||||
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"),
|
||||
" as_IN bn_IN bo_IN brx_IN en en_IN en_US en_US_POSIX gu_IN hi_IN kn_IN " +
|
||||
"kok_IN ks_IN_#Arab ml_IN mr_IN ne_IN or_IN pa_IN_#Guru ta_IN te_IN ur_IN",
|
||||
"",
|
||||
},
|
||||
|
||||
// Thai
|
||||
@ -220,6 +217,7 @@ public class IncludeLocalesPluginTest {
|
||||
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
|
||||
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_zh.class"),
|
||||
" en en_US en_US_POSIX th th_TH th_TH_TH_#u-nu-thai",
|
||||
"",
|
||||
},
|
||||
|
||||
// Hong Kong
|
||||
@ -242,6 +240,7 @@ public class IncludeLocalesPluginTest {
|
||||
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
|
||||
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"),
|
||||
" en en_US en_US_POSIX zh_HK zh_HK_#Hans zh_HK_#Hant",
|
||||
"",
|
||||
},
|
||||
|
||||
// Norwegian
|
||||
@ -265,6 +264,7 @@ public class IncludeLocalesPluginTest {
|
||||
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
|
||||
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"),
|
||||
" en en_US en_US_POSIX nb nb_NO nb_SJ nn nn_NO no no_NO no_NO_NY",
|
||||
"",
|
||||
},
|
||||
|
||||
// Hebrew/Indonesian/Yiddish
|
||||
@ -290,6 +290,25 @@ public class IncludeLocalesPluginTest {
|
||||
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_ja.class",
|
||||
"/jdk.localedata/sun/text/resources/cldr/ext/FormatData_th.class"),
|
||||
" en en_US en_US_POSIX in in_ID iw iw_IL ji ji_001",
|
||||
"",
|
||||
},
|
||||
|
||||
// Error case: No matching locales
|
||||
{"--include-locales=xyz",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new PluginException(
|
||||
PluginsResourceBundle.getMessage("include-locales.nomatchinglocales"))
|
||||
.toString(),
|
||||
},
|
||||
|
||||
// Error case: Invalid argument
|
||||
{"--include-locales=zh_HK",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"range=zh_hk",
|
||||
},
|
||||
};
|
||||
|
||||
@ -304,20 +323,28 @@ public class IncludeLocalesPluginTest {
|
||||
|
||||
for (Object[] data : testData) {
|
||||
// create image for each test data
|
||||
Path image = JImageGenerator.getJLinkTask()
|
||||
Result result = JImageGenerator.getJLinkTask()
|
||||
.modulePath(helper.defaultModulePath())
|
||||
.output(helper.createNewImageDir(moduleName))
|
||||
.addMods("jdk.localedata")
|
||||
.option((String)data[INCLUDE_LOCALES_OPTION])
|
||||
.call().assertSuccess();
|
||||
.call();
|
||||
|
||||
// test locale data entries
|
||||
testLocaleDataEntries(image,
|
||||
(List<String>)data[EXPECTED_LOCATIONS],
|
||||
(List<String>)data[UNEXPECTED_PATHS]);
|
||||
String errorMsg = (String)data[ERROR_MESSAGE];
|
||||
if (errorMsg.isEmpty()) {
|
||||
Path image = result.assertSuccess();
|
||||
|
||||
// test available locales
|
||||
testAvailableLocales(image, (String)data[AVAILABLE_LOCALES]);
|
||||
// test locale data entries
|
||||
testLocaleDataEntries(image,
|
||||
(List<String>)data[EXPECTED_LOCATIONS],
|
||||
(List<String>)data[UNEXPECTED_PATHS]);
|
||||
|
||||
// test available locales
|
||||
testAvailableLocales(image, (String)data[AVAILABLE_LOCALES]);
|
||||
} else {
|
||||
result.assertFailure(new TaskHelper(TaskHelper.JLINK_BUNDLE)
|
||||
.getMessage("error.prefix") + " " +errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user